Docs: deleted spring-cloud-alibaba-docs module (#3490)

* Docs: deleted spring-cloud-alibaba-docs module

* docs: update docs link
pull/3513/head
YuLuo 1 year ago committed by GitHub
parent 0d651dcf69
commit 01e6981b4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -109,7 +109,6 @@
<modules>
<module>spring-cloud-alibaba-dependencies</module>
<module>spring-cloud-alibaba-examples</module>
<module>spring-cloud-alibaba-docs</module>
<module>spring-cloud-alibaba-starters</module>
<module>spring-cloud-alibaba-coverage</module>
<module>spring-cloud-alibaba-tests</module>

@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-alibaba-docs</artifactId>
<name>Spring Cloud Alibaba Documentation</name>
<packaging>pom</packaging>
<properties>
<docs.main>spring-cloud-alibaba</docs.main>
<main.basedir>${basedir}/..</main.basedir>
</properties>
<profiles>
<profile>
<id>docs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<inherited>false</inherited>
<configuration>
<sourceDirectory>${basedir}/src/main/asciidoc-zh</sourceDirectory>
</configuration>
</plugin>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

@ -1,176 +0,0 @@
== Spring Cloud AliCloud ACM
Spring Cloud AliCloud ACM 是阿里云提供的商业版应用配置管理(Application Configuration Management) 产品 在 Spring Cloud 应用侧的客户端实现,且目前完全免费。
使用 Spring Cloud AliCloud ACM可基于 Spring Cloud 的编程模型快速接入 ACM 配置管理功能。
NOTE: 目前 EDAS 已经支持直接部署 Nacos Config 应用
=== 如何引入 Spring Cloud AliCloud ACM
如果要在您的项目中引入 ACM使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-acm` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-acm</artifactId>
</dependency>
----
=== 使用 ACM 进行配置管理
当客户端引入了 Spring Cloud AliCloud ACM Starter 以后,应用启动时会自动从配置管理的服务端获取配置信息,并注入到 Spring 的 Environment 中。
以下是一个简单的应用示例。
[source,java]
----
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :"+userName+"; age: "+userAge);
}
}
----
在从配置中心服务端获取配置信息之前,还需要配置服务端的地址,在 bootstrap.properties 中,还需要配置以下信息。
[source,properties]
----
# 必选,应用名会被作为从服务端获取配置 key 的关键词组成部分
spring.application.name=acm-config
server.port=18081
# 以下就是配置中心服务端的IP和端口配置
spring.cloud.alicloud.acm.server-list=127.0.0.1
spring.cloud.alicloud.acm.server-port=8080
----
NOTE: 此时没有启动配置中心,启动应用会报错,因此在应用启动之前,应当首先启动配置中心。
==== 启动配置中心
ACM 使用的配置中心有两种,一种是本地运行的轻量版配置中心,主要用于开发和本地调试,一种是阿里云产品 ACM。通常情况下可以使用轻量版配置中心作为开发和测试环境使用云上的 ACM 作为灰度和生产环境。
===== 使用轻量版配置中心
轻量版配置中心的下载和启动方式可参考 https://help.aliyun.com/document_detail/44163.html[这里]
NOTE: 只需要执行文档中的第1步 (下载轻量配置中心) 和第2步 (启动轻量配置中心)。
===== 使用阿里云配置中心
使用云上 ACM ,可以省去服务端的维护工作,同时稳定性也会更有保障。当使用云上配置中心时,代码部分和使用轻量配置中心并没有区别,但是配置上会有一些区别。
以下是一个简单的使用云上配置中心的配置示例,配置详情需要在 https://acm.console.aliyun.com[ACM控制台查询]
[source,properties]
----
# 应用名会被作为从服务端获取配置 key 的关键词组成部分,因此是必选
spring.application.name=acm-config
# 端口配置自由配置即可
server.port=18081
# 以下就是配置中心的IP和端口配置
spring.cloud.alicloud.acm.server-mode=EDAS
spring.cloud.alicloud.access-key=你的阿里云AK
spring.cloud.alicloud.secret-key=你的阿里云SK
spring.cloud.alicloud.acm.endpoint=acm.aliyun.com
spring.cloud.alicloud.acm.namespace=你的 ACM namespace需要在 ACM 控制台查询
----
NOTE: EDAS 提供应用托管服务,如果你将应用托管到 EDAS那么 EDAS 将会自动为你填充所有与业务无关的配置。
==== 在配置中心添加配置
1. 启动好轻量版配置中心之后,在控制台中添加如下的配置。
[source,subs="normal"]
----
Group: DEFAULT_GROOUP
DataId: acm-config.properties
Content: user.name=james
user.age=18
----
NOTE: DataId 的格式为 `{prefix}.{file-extension}`,prefix 默认从配置 spring.application.name 中取值file-extension 默认的值为 "properties"。
==== 启动应用验证
启动这个Example可以在控制台看到打印出的值正是我们在轻量版配置中心上预先配置的值。
[source,subs="normal"]
----
user name :james; age: 18
----
=== 更改配置文件扩展名
spring-cloud-starter-alicloud-acm 中 DataId 默认的文件扩展名是 properties。除去 properties 格式之外,也支持 yaml 格式。
支持通过 spring.cloud.alicloud.acm.file-extension 来配置文件的扩展名yaml 格式可以配置成 `yaml` 或 `yml`。
NOTE: 修改文件扩展名后,在配置中心中的 DataID 以及 Content 的格式都必须做相应的修改。
=== 动态更新
spring-cloud-starter-alicloud-acm 默认支持配置的动态更新,当您在配置中心修改配置的内容时,会发布 Spring 中的 RefreshEvent 事件。
带有 @RefreshScope 和 @ConfigurationProperties 注解的类会自动刷新。
NOTE: 你可以通过配置 spring.cloud.alicloud.acm.refresh.enabled=false 来关闭动态刷新。
=== Profile 粒度的配置
spring-cloud-starter-alicloud-acm 在加载配置的时候,首先会加载 DataId 为{spring.application.name}.{file-extension}的配置,当 spring.profiles.active 中配置有内容时,还会依次去加载 spring.profile 对应的内容, DataId 的格式为{spring.application.name}-{profile}.{file-extension}的配置,且后者的优先级高于前者。
spring.profiles.active 属于配置的元数据,所以也必须配置在 bootstrap.properties 或 bootstrap.yaml 中。比如可以在 bootstrap.properties 中增加如下内容。
[sources,properties]
----
spring.profiles.active={profile-name}
----
Note: 也可以通过 JVM 参数 -Dspring.profiles.active=develop 或者 --spring.profiles.active=develop 这类优先级更高的方式来配置,只需遵循 Spring Boot 规范即可。
=== 自定义配置中心超时时间
ACM Client 与 Server 通信的超时时间默认是 3000ms可以通过 `spring.cloud.alicloud.acm.timeout` 来修改超时时间,单位为 ms 。
=== 自定义 Group 的配置
在没有明确指定 `{spring.cloud.alicloud.acm.group}` 配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group可以通过以下配置来实现
[source,properties]
----
spring.cloud.alicloud.acm.group=DEVELOP_GROUP
----
NOTE: 该配置必须放在 bootstrap.properties 文件中。并且在添加配置时 Group 的值要和 `spring.cloud.alicloud.acm.group` 的配置值一致。
=== 共享配置
ACM 提供了一种多个应用之间共享配置中心的同一个配置的推荐方式,供多个应用共享一些配置时使用,您在使用的时候需要添加在 bootstrap 中添加一个配置项 `spring.application.group`。
[source,properties]
----
spring.application.group=company.department.team
----
这时应用在获取上文提到的自身所独有的配置之前,会先依次从这些 DataId 去获取,分别是 company:application.properties, company.department:application.properties, company.department.team:application.properties。
然后,还会从 {spring.application.group}:{spring.application.name}.{file-extension} 中获取,越往后优先级越高,最高的仍然是应用自身所独有的配置。
NOTE: 共享配置中 DataId 默认后缀为 properties可以通过 spring.cloud.alicloud.acm.file-extension 配置. `{spring.application.group}:{spring.application.name}.{file-extension}` 。
NOTE: 如果设置了 `spring.profiles.active` DataId 的格式还支持 `{spring.application.group}:{spring.application.name}-{spring.profiles.active}.{file-extension}`。优先级高于 `{spring.application.group}:{spring.application.name}.{file-extension}`
=== Actuator 监控
ACM 对应的 Actuator 监控地址为 `/acm`,其中 `config` 代表了 ACM 元数据配置的信息,`runtime.sources` 对应的是从 ACM 服务端获取的配置的信息及最后刷新时间, `runtime.refreshHistory` 对应的是动态刷新的历史记录。

@ -1,96 +0,0 @@
== Spring Cloud AliCloud ANS
ANSApplication Naming Service 是隶属于阿里云 EDAS 产品的组件, Spring Cloud AliCloud ANS 提供了 Spring Cloud 规范下商业版的服务注册与发现,可以让用户方便的在本地开发,同时也可以运行在云环境里。
NOTE: 目前 EDAS 已经支持直接部署 Nacos Discovery 应用
=== 如何引入 Spring Cloud AliCloud ANS
如果要在您的项目中引入 ANS使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-ans` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-ans</artifactId>
</dependency>
----
=== 使用ANS进行服务注册
当客户端引入了 Spring Cloud AliCloud ANS Starter 以后服务的元数据会被自动注册到注册中心比如IP、端口、权重等信息。客户端会与服务端保持心跳来证明自己可以正常提供服务。
以下是一个简单的应用示例。
[source,java]
----
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ProviderApplication {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
----
既然服务会被注册到注册中心,那么肯定需要配置注册中心的地址,在 application.properties 中,还需要配置上以下地址。
[source,properties]
----
# 应用名会被作为服务名称使用,因此会必选
spring.application.name=ans-provider
server.port=18081
# 以下就是注册中心的IP和端口配置
spring.cloud.alicloud.ans.server-list=127.0.0.1
spring.cloud.alicloud.ans.server-port=8080
----
NOTE: 此时没有启动注册中心,启动应用会报错,因此在应用启动之前,应当首先启动注册中心。
=== 启动注册中心
ANS 使用的注册中心有两种一种是完全免费的轻量版配置中心主要用于开发和本地调试一种是云上注册中心ANS 依托于阿里云 EDAS 产品提供服务注册的功能。通常情况下,可以使用轻量版配置中心作为开发和测试环境,使用云上的 EDAS 作为灰度和生产环境。
==== 启动轻量版配置中心
轻量版配置中心的下载和启动方式可参考 https://help.aliyun.com/document_detail/44163.html?spm=a2c4g.11186623.6.677.5f206b82Z2mTCF[这里]
NOTE: 只需要进行第1步下载轻量配置中心和第2步启动轻量配置中心即可第3步配置hosts在与 ANS 结合使用时,不需要操作。
启动完轻量版配置中心以后,直接启动 ProviderApplication 即可将服务注册到轻量版配置中心由于轻量版配置中心的默认端口是8080因此你可以打开 http://127.0.0.1:8080 ,点击左侧"服务列表",查看注册上来的服务。
==== 使用云上注册中心
使用云上注册中心,可以省去服务端的维护工作,同时稳定性也会更有保障。当使用云上注册中心时,代码部分和使用轻量配置中心并没有区别,但是配置上会有一些区别。
以下是一个简单的使用云上配置中心的配置示例。
[source,properties]
----
# 应用名会被作为服务名称使用,因此是必选
spring.application.name=ans-provider
# 端口配置自由配置即可
server.port=18081
# 以下就是注册中心的IP和端口配置因为默认就是127.0.0.1和8080因此以下两行配置也可以省略
spring.cloud.alicloud.ans.server-mode=EDAS
spring.cloud.alicloud.access-key=你的阿里云AK
spring.cloud.alicloud.secret-key=你的阿里云SK
spring.cloud.alicloud.edas.namespace=cn-xxxxx
----
server-mode 的默认值为 LOCAL ,如果要使用云上注册中心,则需要更改为 EDAS 。
access-key 和 secret-key 则是阿里云账号的 AK/SK需要首先注册阿里云账号然后登陆 https://usercenter.console.aliyun.com/#/manage/ak[阿里云AK/SK管理页面] ,即可看到 AccessKey ID 和 Access Key Secret ,如果没有的话,需要点击"创建 AccessKey"按钮创建。
namespace 是阿里云 EDAS 产品的概念,用于隔离不同的环境,比如测试环境和生产环境。要获取 namespace 需要 https://common-buy.aliyun.com/?spm=5176.11451019.0.0.6f5965c0Uq5tue&commodityCode=edaspostpay#/buy[开通 EDAS 服务],按量计费模式下开通是免费的,开通以后进入 https://edas.console.aliyun.com/#/namespaces?regionNo=cn-hangzhou[EDAS控制台],即可看到对应的 namespace比如 cn-hangzhou。
NOTE: EDAS 提供应用托管服务,如果你将应用托管到 EDAS那么 EDAS 将会自动为你填充所有配置。

@ -1,21 +0,0 @@
== 依赖管理
Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本。
如果您是 Maven Central 用户,请将我们的 BOM 添加到您的 pom.xml 中的 <dependencyManagement> 部分。 这将允许您省略任何Maven依赖项的版本而是将版本控制委派给BOM。
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
在下面的章节中,假设您使用的是 Spring Cloud Alibaba bom相关 starter 依赖将不包含版本号。

@ -1,148 +0,0 @@
== AOT and Native Image Support
=== GraalVM 介绍
Spring Boot 3.0 本次带来最大的改动就是 GraalVM 原生镜像的支持,也是官方文档中强调的他们花费时间精力比较多的部分。 GraalVM 技术作为JRE的替代方案其通过预先编译Ahead Of TimeAOT等技术对 Java 应用进行预先编译,让 Spring 在运行应用时掌握更多应用有关的信息,让整个应用启动速度更快。另外,通过编译工具在编译过程中通过消除一些不必要的内容可以让最终的应用更小,占用内存更低。对于一些对启动速度要求非常高的场景,比如 Serverless、FaaS 场景非常友好! 本次 Spring Boot 3.0 直接将其正式从 Spring Native 迁入到 Spring Boot 中来也预示着该项技术开始逐渐走向成熟Spring 生态开始迈入 GraalVM 阶段!
*跟 JVM 编译部署方式相比GraalVM 具有以下特点:*
* 在应用构建阶段,从主入口点就开始进行应用程序的静态分析。
* 创建本机镜像时,通过代码分析,会将无法访问的代码删除,并且不会成为可执行文件的一部分,从而可在一定程度上压缩程序包大小。
* GraalVM 无法直接感知代码的动态元素,因此对于存在反射、序列化和动态代理的应用程序,需要提前提供相关 hint 配置文件,帮助解析应用程序,相关操作过程可参考官方文档。
* 应用程序类路径在构建时是固定的,不能更改。
* 没有惰性类加载,可执行文件中的所有内容都将在启动时加载到内存中。
* 支持的 Java 应用程序在某些方面存在一些限制,因此目前并不能保证之前的 Java 应用都可直接使用 GraalVM 技术进行应用构建,有一定概率会存在不兼容的异常情况。
本次发布的 Spring Cloud Alibaba 2022.0.0.0 版本所包含的部分中间件客户端已完成了构建 GraalVM 原生应用的适配,以下是社区对目前所支持的服务注册与发现模块相关示例应用在升级为 Spring Boot 3.0 以后,使用 GraalVM 构建原生应用镜像做的在启动速度和运行时占用内容相关的测试,以下测试过程在 MacOS 11.42.6 GHz 6-Core Intel Core i7 处理器16G 内存环境下分别模拟3次取平均值测得
image::https://sca-storage.oss-cn-hangzhou.aliyuncs.com/website/docs/zh/graalvm_performance.jpg[]
从上述对比可发现,最新支持 Spring Boot 3.0 基于 GraalVM 的 Spring Cloud Alibaba 应用会在启动速度、运行时内存占用和应用包大小方面得到大幅度降低,例如,其中服务注册消费应用启动速度提升了近 10 倍,运行时内存占用比原来降低了近乎 2/3效果非常明显。这给云原生时代托管在云上的应用带来了显著优势让其可以更快地进行弹性扩缩容以及降低企业整体用云成本
=== 使用 GraalVM 技术构建应用
==== 项目构建
本次适配 Spring Boot 3.0 的 Spring Cloud Alibaba 所支持的所有组件中都已经支持 GraalVM 技术构建应用。接下来,将介绍一下相关组件使用 GraalVM 技术进行应用编译与运行测试
按照一般的 Spring Cloud Alibaba 应用构建方式进行项目构建即可,以下为相关必须添加的依赖内容:
```xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
以上为本次通过 Spring Cloud Alibaba 使用 Nacos 进行服务注册所需要的必要依赖,其他依赖请根据自身需求进行调整,请注意,使用 GraalVM `spring-boot-starter-parent` 父模块是非常关键的,其声明一个 native profile其中包含了创建、运行 GraalVM 原生映像的必要信息。 构建 Spring Boot 原生镜像应用主要有两种方式:
1. 使用 Spring Boot 对 Cloud Native Buildpacks 的支持来生成包含本机可执行文件的轻量级容器。
2. 使用 GraalVM Native Build Tools 生成本机可执行文件。 由于第一种方式使用过程中对本地环境有一定的要求,如需使用可参考 https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.introducing-graalvm-native-images[Spring Boot 3.0] 相关用户文档。本文接下来演示使用第二种方式进行 GraalVM 应用构建。
==== 环境准备
要使用 Native Build Tools 构建原生镜像,需要在首先在机器上安装 GraalVM 发行版。 您可以在 Liberica Native Image Kit 页面上手动下载它,也可以使用像 SDKMAN!
这样的下载管理器。本文演示环境为MacOS如果是 Windows 可参考相应文档进行操作。执行以下命令安装 GraalVM 环境:
[source,shell]
----
sdk install java 22.3.r17-nik
sdk use java 22.3.r17-nik
----
通过检查 java -version 的输出来验证是否配置了正确的版本:
[source,shell]
----
$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)
----
==== 生成 hint 文件
通过以下命令生成应用中反射、序列化和动态代理所需的hint配置文件
[source,shell]
----
mvn -Pnative spring-boot:run
----
之后我们的 example 应用会启动,我们需要尽可能完整的测试一遍 example 的所有功能,保证应用的大部分代码都被测试用例覆盖,这样才能确保完整生成应用运行过程中的所有必须的动态属性。 运行完所有测试用例后,我们发现`resource/META-INF/native-image` 目录下会生成以下一些 hint 文件:
- resource-config.json应用中资源hint文件
- reflect-config.json应用中反射定义hint文件
- serialization-config.json应用中序列化内容hint文件
- proxy-config.json应用中Java代理相关内容hint文件
- jni-config.json应用中Java Native InterfaceJNI内容hint文件
注意事项RocketMQ 应用通过上述命令进行 hint 文件生成过程中,可能会出现配置信息扫描不全问题,可参考 https://github.com/alibaba/spring-cloud-alibaba/issues/3101[相关issue]Sentinel应用通过上述命令进行 hint 文件生成过程中,可能会遇到如下问题,可参考 https://github.com/alibaba/Sentinel/issues/3012[相关issue]。
==== 构建原生镜像
以上步骤一切准备就绪后,通过以下命令来构建原生镜像:
[source,shell]
----
mvn -Pnative native:compile
----
成功执行后,我们在``/target``目录可以看到我们生成的可执行文件。
==== 启动原生镜像
与普通可执行文件无异,通过``target/nacos-config-example``启动本example, 可以观察到类似如下的输出:
[source,shell]
----
2022-12-22T16:28:51.006+08:00 INFO 75439 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''
2022-12-22T16:28:51.008+08:00 INFO 75439 --- [ main] c.a.cloud.imports.examples.Application : Started Application in 0.653 seconds (process running for 0.662)
----
可以发现应用的启动速度大大加快。 再通过``vmmap pid | grep Physical``命令查看运行过程中的内存占用情况 通过原生镜像启动的应用内存占用情况如下:
```
Physical footprint: 59.2M
Physical footprint (peak): 59.2M
```
通过普通的方式启动Java应用的内存占用情况如下
```
Physical footprint: 214.0M
Physical footprint (peak): 256.8M
```
可以看到通过原生镜像启动Java应用后内存占用大大减少。 应用启动后各项功能与通过jar启动无异。

@ -1,19 +0,0 @@
== 介绍
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba您只需要添加一些注解和少量配置就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
目前 Spring Cloud Alibaba 提供了如下功能:
1. **服务限流降级**:支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Dubbo 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
2. **服务注册与发现**:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
3. **分布式配置管理**:支持分布式系统中的外部化配置,配置更改时自动刷新。
4. **Rpc服务**:扩展 Spring Cloud 客户端 RestTemplate 和 OpenFeign支持调用 Dubbo RPC 服务
5. **消息驱动能力**:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
6. **分布式事务**:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
7. **阿里云对象存储**:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
8. **分布式任务调度**:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Workerschedulerx-client上执行。
9. **阿里云短信服务**:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
Spring Cloud Alibaba 也提供了丰富的 https://github.com/alibaba/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples[examples]。

@ -1,463 +0,0 @@
== Spring Cloud Alibaba Nacos Config
Nacos 是一个 Alibaba 开源的、易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
使用 Spring Cloud Alibaba Nacos Config可基于 Spring Cloud 的编程模型快速接入 Nacos 配置管理功能。
=== 如何引入 Nacos Config 进行配置管理
如果要在您的项目中使用 Nacos 来实现配置管理,使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-nacos-config` 的 starter。
[source,xml,indent=0]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
----
=== 快速开始
Nacos Config 使用 DataId 和 GROUP 确定一个配置。
下图表示 DataId 使用 `myDataid`, GROUP 使用 `DEFAULT_GROUP`,配置格式为 Properties 的一个配置项:
.Nacos Config Item
image::https://img.alicdn.com/tfs/TB1Yli3bUY1gK0jSZFMXXaWcVXa-2436-1138.png[]
==== Nacos 服务端初始化
具体启动方式参考 Spring Cloud Alibaba Nacos Discovery 小节的 "Nacos Server 启动" 章节。
Nacos Server 启动完毕后,添加如何配置:
[source,subs="normal"]
----
Data ID: nacos-config.properties
Group : DEFAULT_GROUP
配置格式: Properties
配置内容:
user.name=jack
user.age=90
----
NOTE: 注意DataId是以 properties(默认的文件扩展名方式)为扩展名。
==== 客户端使用方式
如果要在您的项目中使用 Nacos 来实现应用的外部化配置,使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-nacos-config` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
----
现在创建一个标准的 Spring Boot 应用。
[source,java]
----
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :"+userName+"; age: "+userAge);
}
}
----
NOTE: ``spring-cloud-alibaba``从``2021.0.1.0``版本开始,默认使用``spring.config.import``方式引入配置,如果您想继续使用``bootstrap``
方式加载配置,您可以在项目根``pom.xml``文件中加入以下依赖:
[source,xml]
----
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>4.0.0</version>
</dependency>
----
在运行此 NacosConfigApplication 之前,您需要先配置 `application.yaml` 文件中的 Nacos Server 地址,并引入对应的配置,例如:
.application.yaml
[source,yaml]
----
# GROUP 不配置默认使用 DEFAULT_GROUP。
spring:
application:
name: nacos-config
cloud:
nacos:
config:
serverAddr: 127.0.0.1:8848
config:
import:
- nacos:nacos-config.properties
----
NOTE: 注意当你使用域名的方式来访问 Nacos 时,`spring.cloud.nacos.config.server-addr` 配置的方式为 `域名:port`。
例如 Nacos 的域名为abc.com.nacos监听的端口为 80则 `spring.cloud.nacos.config.server-addr=abc.com.nacos:80`。
注意 80 端口不能省略。
启动这个 Example可以看到如下输出结果
[source,subs="normal"]
----
2018-11-02 14:24:51.638 INFO 32700 --- [main] c.a.demo.provider.ConfigApplication : Started ConfigApplication in 14.645 seconds (JVM running for 15.139)
user name :jack; age: 90
----
=== 基于 DataId 为 yaml 的文件扩展名配置方式
Nacos Config 除了支持 properties 格式以外,也支持 yaml 格式。这个时候只需要完成以下两步:
1、在应用的 application.yaml 配置文件中引入配置,如下所示
.application.yaml
[source,yaml]
----
spring:
application:
name: nacos-config
cloud:
nacos:
config:
serverAddr: 127.0.0.1:8848
config:
import:
- nacos:nacos-config.yaml
----
2、在 Nacos 的控制台新增一个DataId为yaml为扩展名的配置如下所示
[source,subs="normal"]
----
Data ID: nacos-config.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容:
user:
name: rose
age: 68
----
这两步完成后,重启测试程序,可以看到如下输出结果。
[source,subs="normal"]
----
user name :rose; age: 68
----
=== 支持配置的动态更新
Nacos Config 默认支持配置的动态更新,启动 Spring Boot 应用测试的代码如下:
[source,java]
----
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication.class, args);
while(true) {
//当动态配置刷新时,会更新到 Enviroment中因此这里每隔一秒中从Enviroment中获取配置
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(1);
}
}
}
----
如下所示当变更user.name时应用程序中能够获取到最新的值
[source,subs="normal"]
----
user name :nacos-config-yaml; age: 68
user name :nacos-config-yaml; age: 68
user name :nacos-config-yaml; age: 68
2018-11-02 15:04:25.069 INFO 32957 --- [-127.0.0.1:8848] o.s.boot.SpringApplication : Started application in 0.144 seconds (JVM running for 71.752)
2018-11-02 15:04:25.070 INFO 32957 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@10c89124: startup date [Fri Nov 02 15:04:25 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@6520af7
2018-11-02 15:04:25.071 INFO 32957 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6520af7: startup date [Fri Nov 02 15:04:24 CST 2018]; root of context hierarchy
//从 Enviroment 中 读取到更改后的值
user name :nacos-config-yaml-update; age: 68
user name :nacos-config-yaml-update; age: 68
----
NOTE: 你可以通过配置 `spring.cloud.nacos.config.refresh.enabled=false` 来关闭动态刷新
=== 支持profile粒度的配置
Nacos Config 在加载配置的时候,不仅仅加载了以 DataId 为 `${spring.application.name}.${file-extension:properties}` 为前缀的基础配置还加载了DataId为 `${spring.application.name}-${profile}.${file-extension:properties}` 的基础配置。在日常开发中如果遇到多套环境下的不同配置可以通过Spring 提供的 `${spring.profiles.active}` 这个配置项来配置。
[source,properties]
----
spring.profiles.active=develop
----
NOTE: ${spring.profiles.active} 当通过配置文件来指定时必须放在 bootstrap.properties 文件中。
Nacos 上新增一个DataId为nacos-config-develop.yaml的基础配置如下所示
[source,subs="normal"]
----
Data ID: nacos-config-develop.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: current.env: develop-env
----
启动 Spring Boot 应用测试的代码如下:
[source,java]
----
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication.class, args);
while(true) {
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
//获取当前部署的环境
String currentEnv = applicationContext.getEnvironment().getProperty("current.env");
System.err.println("in "+currentEnv+" enviroment; "+"user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(1);
}
}
}
----
启动后,可见控制台的输出结果:
[source,subs="normal"]
----
in develop-env enviroment; user name :nacos-config-yaml-update; age: 68
2018-11-02 15:34:25.013 INFO 33014 --- [ Thread-11] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6f1c29b7: startup date [Fri Nov 02 15:33:57 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@63355449
----
如果需要切换到生产环境,只需要更改 `${spring.profiles.active}` 参数配置即可。如下所示:
[source,properties]
----
spring.profiles.active=product
----
同时生产环境上 Nacos 需要添加对应 DataId 的基础配置。例如,在生产环境下的 Naocs 添加了DataId为nacos-config-product.yaml的配置
[source,subs="normal"]
----
Data ID: nacos-config-product.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: current.env: product-env
----
启动测试程序,输出结果如下:
[source,subs="normal"]
----
in product-env enviroment; user name :nacos-config-yaml-update; age: 68
2018-11-02 15:42:14.628 INFO 33024 --- [Thread-11] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6aa8e115: startup date [Fri Nov 02 15:42:03 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@19bb07ed
----
NOTE: 此案例中我们通过 `spring.profiles.active=<profilename>` 的方式写死在配置文件中,而在真正的项目实施过程中这个变量的值是需要不同环境而有不同的值。这个时候通常的做法是通过 `-Dspring.profiles.active=<profile>` 参数指定其配置来达到环境间灵活的切换。
=== 支持自定义 namespace 的配置
Nacos 内部有 https://nacos.io/zh-cn/docs/concepts.html[Namespace 的概念]:
[quote]
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
在没有明确指定 `${spring.cloud.nacos.config.namespace}` 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespace。如果需要使用自定义的命名空间可以通过以下配置来实现
[source,properties]
----
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
----
NOTE: 该配置必须放在 bootstrap.properties 文件中。此外 `spring.cloud.nacos.config.namespace` 的值是 namespace 对应的 idid 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae否则将会导致读取不到正确的配置。
=== 支持自定义 Group 的配置
在没有明确指定 `${spring.cloud.nacos.config.group}` 配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group可以通过以下配置来实现
[source,properties]
----
spring.cloud.nacos.config.group=DEVELOP_GROUP
----
NOTE: 该配置必须放在 bootstrap.properties 文件中。并且在添加配置时 Group 的值一定要和 `spring.cloud.nacos.config.group` 的配置值一致。
=== 支持自定义扩展的 Data Id 配置
Nacos Config 从 0.2.1 版本后,可支持自定义 Data Id 的配置。关于这部分详细的设计可参考 https://github.com/alibaba/spring-cloud-alibaba/issues/141[这里]。
一个完整的配置案例如下所示:
[source,properties]
----
spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
spring.cloud.nacos.config.ext-config[0].data-id=ext-config-common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
spring.cloud.nacos.config.ext-config[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.ext-config[1].group=GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
spring.cloud.nacos.config.ext-config[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.ext-config[2].group=REFRESH_GROUP
spring.cloud.nacos.config.ext-config[2].refresh=true
----
可以看到:
* 通过 `spring.cloud.nacos.config.ext-config[n].data-id` 的配置方式来支持多个 Data Id 的配置。
* 通过 `spring.cloud.nacos.config.ext-config[n].group` 的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP。
* 通过 `spring.cloud.nacos.config.ext-config[n].refresh` 的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新,
感知到最新的配置值。默认是不支持的。
NOTE: 多个 Data Id 同时配置时,他的优先级关系是 `spring.cloud.nacos.config.ext-config[n].data-id` 其中 n 的值越大,优先级越高。
NOTE: `spring.cloud.nacos.config.ext-config[n].data-id` 的值必须带文件扩展名,文件扩展名既可支持 properties又可以支持 yaml/yml。
此时 `spring.cloud.nacos.config.file-extension` 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
通过自定义扩展的 Data Id 配置,既可以解决多个应用间配置共享的问题,又可以支持一个应用有多个配置文件。
为了更加清晰的在多个应用间配置共享的 Data Id ,你可以通过以下的方式来配置:
[source,properties]
----
spring.cloud.nacos.config.shared-dataids=bootstrap-common.properties,all-common.properties
spring.cloud.nacos.config.refreshable-dataids=bootstrap-common.properties
----
可以看到:
* 通过 `spring.cloud.nacos.config.shared-dataids` 来支持多个共享 Data Id 的配置,多个之间用逗号隔开。
* 通过 `spring.cloud.nacos.config.refreshable-dataids` 来支持哪些共享配置的 Data Id 在配置变化时,应用中是否可动态刷新,
感知到最新的配置值,多个 Data Id 之间用逗号隔开。如果没有明确配置,默认情况下所有共享配置的 Data Id 都不支持动态刷新。
NOTE: 通过 `spring.cloud.nacos.config.shared-dataids` 来支持多个共享配置的 Data Id 时,
多个共享配置间的一个优先级的关系我们约定:按照配置出现的先后顺序,即后面的优先级要高于前面。
NOTE: 通过 `spring.cloud.nacos.config.shared-dataids` 来配置时Data Id 必须带文件扩展名,文件扩展名既可支持 properties也可以支持 yaml/yml。
此时 `spring.cloud.nacos.config.file-extension` 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
NOTE: `spring.cloud.nacos.config.refreshable-dataids` 给出哪些需要支持动态刷新时Data Id 的值也必须明确给出文件扩展名。
=== 配置的优先级
Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置
* A: 通过 `spring.cloud.nacos.config.shared-dataids` 支持多个共享 Data Id 的配置
* B: 通过 `spring.cloud.nacos.config.ext-config[n].data-id` 的方式支持多个扩展 Data Id 的配置
* C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是: A < B < C
=== Nacos Config 对外暴露的 Endpoint
Nacos Config 内部提供了一个 Endpoint, 对应的 endpoint id 为 `nacos-config`。
Endpoint 暴露的 json 中包含了三种属性:
1. Sources: 当前应用配置的数据信息
2. RefreshHistory: 配置刷新的历史记录
3. NacosConfigProperties: 当前应用 Nacos 的基础配置信息
这是 Endpoint 暴露的 json 示例:
[source,json,indent=0]
----
{
"NacosConfigProperties": {
"serverAddr": "127.0.0.1:8848",
"encode": null,
"group": "DEFAULT_GROUP",
"prefix": null,
"fileExtension": "properties",
"timeout": 3000,
"endpoint": null,
"namespace": null,
"accessKey": null,
"secretKey": null,
"contextPath": null,
"clusterName": null,
"name": null,
"sharedDataids": "base-common.properties,common.properties",
"refreshableDataids": "common.properties",
"extConfig": null
},
"RefreshHistory": [{
"timestamp": "2019-07-29 11:20:04",
"dataId": "nacos-config-example.properties",
"md5": "7d5d7f1051ff6571e2ec9f90887d9d91"
}],
"Sources": [{
"lastSynced": "2019-07-29 11:19:04",
"dataId": "common.properties"
}, {
"lastSynced": "2019-07-29 11:19:04",
"dataId": "base-common.properties"
}, {
"lastSynced": "2019-07-29 11:19:04",
"dataId": "nacos-config-example.properties"
}]
}
----
=== 完全关闭 Nacos Config 的自动化配置
通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config
=== 关于 Nacos Config Starter 更多的配置项信息
更多关于 Nacos Config Starter 的配置项如下所示:
|===
|配置项 |Key |默认值 |说明
|服务端地址|`spring.cloud.nacos.config.server-addr`|| Nacos Server 启动监听的ip地址和端口
|配置对应的 DataId|`spring.cloud.nacos.config.name`|| 先取 prefix再取 name最后取 spring.application.name
|配置对应的 DataId|`spring.cloud.nacos.config.prefix`|| 先取 prefix再取 name最后取 spring.application.name
|配置内容编码|`spring.cloud.nacos.config.encode`||读取的配置内容对应的编码
|GROUP|`spring.cloud.nacos.config.group`|`DEFAULT_GROUP`|配置对应的组
|文件扩展名|`spring.cloud.nacos.config.fileExtension`|`properties`|配置项对应的文件扩展名,目前支持 properties 和 yaml(yml)
|获取配置超时时间|`spring.cloud.nacos.config.timeout`|`3000`|客户端获取配置的超时时间(毫秒)
|接入点|`spring.cloud.nacos.config.endpoint`||地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
|命名空间|`spring.cloud.nacos.config.namespace`||常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
|AccessKey|`spring.cloud.nacos.config.accessKey`||当要上阿里云时,阿里云上面的一个云账号名
|SecretKey|`spring.cloud.nacos.config.secretKey`||当要上阿里云时,阿里云上面的一个云账号密码
|Nacos Server 对应的 context path|`spring.cloud.nacos.config.contextPath`||Nacos Server 对外暴露的 context path
|集群|`spring.cloud.nacos.config.clusterName`||配置成Nacos集群名称
|共享配置|`spring.cloud.nacos.config.sharedDataids`||共享配置的 DataId, "," 分割
|共享配置动态刷新|`spring.cloud.nacos.config.refreshableDataids`||共享配置中需要动态刷新的 DataId, "," 分割
|自定义 Data Id 配置|`spring.cloud.nacos.config.extConfig`||属性是个集合,内部由 `Config` POJO 组成。`Config` 有 3 个属性,分别是 `dataId`, `group` 以及 `refresh`
|===

@ -1,360 +0,0 @@
== Spring Cloud Alibaba Nacos Discovery
Nacos 是一个 Alibaba 开源的、易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
使用 Spring Cloud Alibaba Nacos Discovery可基于 Spring Cloud 的编程模型快速接入 Nacos 服务注册功能。
=== 服务注册/发现: Nacos Discovery
服务发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于
服务的动态扩缩容。Nacos Discovery 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外Nacos
Discovery 也将服务实例自身的一些元数据信息-例如 hostport, 健康检查URL主页等内容注册到 Nacos。Nacos 的获取和启动方式可以参考 https://nacos.io/zh-cn/docs/quick-start.html[Nacos 官网]。
=== 如何引入 Nacos Discovery 进行服务注册/发现
如果要在您的项目中使用 Nacos 来实现服务注册/发现,使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-nacos-discovery` 的 starter。
[source,xml,indent=0]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
----
=== 一个使用 Nacos Discovery 进行服务注册/发现并调用的例子
Nacos Discovery 适配了 Netflix Ribbon可以使用 RestTemplate 或 OpenFeign 进行服务的调用。
==== Nacos Server 启动
具体启动方式参考 https://nacos.io/zh-cn/docs/quick-start.html[Nacos 官网]。
Nacos Server 启动后,进入 http://ip:8848 查看控制台(默认账号名/密码为 nacos/nacos):
.Nacos Dashboard
image::https://img.alicdn.com/tfs/TB1dyWJbQL0gK0jSZFtXXXQCXXa-2788-1086.png[]
关于更多的 Nacos Server 版本,可以从 https://github.com/alibaba/nacos/releases[release 页面] 下载最新的版本。
==== Provider 应用
以下步骤向您展示了如何将一个服务注册到 Nacos。
* pom.xml的配置。一个完整的 pom.xml 配置如下所示:
.pom.xml
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>open.source.test</groupId>
<artifactId>nacos-discovery-test</artifactId>
<version>1.0-SNAPSHOT</version>
<name>nacos-discovery-test</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
----
* application.properties 配置。一些关于 Nacos 基本的配置也必须在 application.properties(也可以是application.yaml)配置,如下所示:
.application.properties
[source,properties,indent=0]
----
server.port=8081
spring.application.name=nacos-provider
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*
----
NOTE: 如果不想使用 Nacos 作为您的服务注册与发现,可以将 `spring.cloud.nacos.discovery` 设置为 `false`。
* 启动 Provider 示例。如下所示:
[source,java,indent=0]
----
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderDemoApplication {
public static void main(String[] args) {
SpringApplication.run(NacosProviderDemoApplication.class, args);
}
@RestController
public class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Discovery " + string;
}
}
}
----
这个时候你就可以在 Nacos的控制台上看到注册上来的服务信息了。
==== Consumer 应用
Consumer 应用可能还没像启动一个 Provider 应用那么简单。因为在 Consumer 端需要去调用 Provider 端提供的REST 服务。例子中我们使用最原始的一种方式,
即显示的使用 LoadBalanceClient 和 RestTemplate 结合的方式来访问。
pom.xml 和 application.properties 的配置可以参考 1.2 小结。启动一个 Consumer应用的示例代码如下所示
NOTE: 通过带有负载均衡的RestTemplate 和 FeignClient 也是可以访问的。
[source,java,indent=0]
----
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApp {
@RestController
public class NacosController{
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@Value("${spring.application.name}")
private String appName;
@GetMapping("/echo/app-name")
public String echoAppName(){
//使用 LoadBalanceClient 和 RestTemplate 结合的方式来访问
ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider");
String url = String.format("http://%s:%s/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);
System.out.println("request url:"+url);
return restTemplate.getForObject(url,String.class);
}
}
//实例化 RestTemplate 实例
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApp.class,args);
}
}
----
这个例子中我们注入了一个 LoadBalancerClient 的实例,并且手动的实例化一个 RestTemplate同时将 `spring.application.name` 的配置值 注入到应用中来,
目的是调用 Provider 提供的服务时,希望将当前配置的应用名给显示出来。
NOTE: 在启动 Consumer 应用之前请先将 Nacos 服务启动好。具体启动方式可参考 https://nacos.io/zh-cn/docs/quick-start.html[Nacos 官网]。
启动后,访问 Consumer 提供出来的 `http://ip:port/echo/app-name` 接口。我这里测试启动的 port是 8082。访问结果如下所示
访问地址http://127.0.0.1:8082/echo/app-name
访问结果Hello Nacos Discovery nacos-consumer
=== Nacos Discovery 对外暴露的 Endpoint
Nacos Discovery 内部提供了一个 Endpoint, 对应的 endpoint id 为 `nacosdiscovery`。
Endpoint 暴露的 json 中包含了两种属性:
1. subscribe: 显示了当前服务有哪些服务订阅者
2. NacosDiscoveryProperties: 当前应用 Nacos 的基础配置信息
这是 Endpoint 暴露的 json 示例:
[source,json,indent=0]
----
{
"subscribe": [
{
"jsonFromServer": "",
"name": "nacos-provider",
"clusters": "",
"cacheMillis": 10000,
"hosts": [
{
"instanceId": "30.5.124.156#8081#DEFAULT#nacos-provider",
"ip": "30.5.124.156",
"port": 8081,
"weight": 1.0,
"healthy": true,
"enabled": true,
"cluster": {
"serviceName": null,
"name": null,
"healthChecker": {
"type": "TCP"
},
"defaultPort": 80,
"defaultCheckPort": 80,
"useIPPort4Check": true,
"metadata": {
}
},
"service": null,
"metadata": {
}
}
],
"lastRefTime": 1541755293119,
"checksum": "e5a699c9201f5328241c178e804657e11541755293119",
"allIPs": false,
"key": "nacos-provider",
"valid": true
}
],
"NacosDiscoveryProperties": {
"serverAddr": "127.0.0.1:8848",
"endpoint": "",
"namespace": "",
"logName": "",
"service": "nacos-provider",
"weight": 1.0,
"clusterName": "DEFAULT",
"metadata": {
},
"registerEnabled": true,
"ip": "30.5.124.201",
"networkInterface": "",
"port": 8082,
"secure": false,
"accessKey": "",
"secretKey": ""
}
}
----
=== 如何开启权重路由
==== Spring Cloud Loadbalancer
.pom.xml
[source,xml]
----
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
</dependencies>
----
.application.properties
[source,properties]
----
spring.cloud.loadbalancer.ribbon.enabled=false
spring.cloud.loadbalancer.nacos.enabled=true
----
=== IPv4至IPv6地址迁移方案
==== IPv4和IPv6地址双注册
在配置完成以上Spring Cloud LoadBalancer作为负载均衡策略后应用启动后会默认将微服务的IPv4地址和IPv6地址注册到注册中心中其中IPv4地址会存放在Nacos服务列表中的IP字段下IPv6地址在Nacos的metadata字段中其对应的Key为IPv6。当服务消费者调用服务提供者时会根据自身的IP地址栈支持情况选择合适的IP地址类型发起服务调用。具体规则
1服务消费者本身支持IPv4和IPv6双地址栈或仅支持IPv6地址栈的情况下服务消费者会使用服务提供的IPv6地址发起服务调用IPv6地址调用失败如本身还同事支持IPv4地址栈时暂不支持切换到IPv4再发起重试调用
2服务消费者本身仅支持IPv4单地址栈的情况下服务消费者会使用服务提供的IPv4地址发起服务调用。
==== 仅注册IPv4
如果您只想使用IPv4地址进行注册可以在application.properties使用以下配置
[source,properties]
----
spring.cloud.nacos.discovery.ip-type=IPv4
----
==== 仅注册IPv6
如果您只想使用IPv6地址可以在application.properties使用以下配置
[source,properties]
----
spring.cloud.nacos.discovery.ip-type=IPv6
----
=== 关于 Nacos Discovery Starter 更多的配置项信息
更多关于 Nacos Discovery Starter 的配置项如下所示:
|===
|配置项 |Key |默认值 |说明
|服务端地址|`spring.cloud.nacos.discovery.server-addr`|| Nacos Server 启动监听的ip地址和端口
|服务名|`spring.cloud.nacos.discovery.service`|`${spring.application.name}`|注册的服务名
|权重|`spring.cloud.nacos.discovery.weight`|`1`|取值范围 1 到 100数值越大权重越大
|网卡名|`spring.cloud.nacos.discovery.network-interface`||当IP未配置时注册的IP为此网卡所对应的IP地址如果此项也未配置则默认取第一块网卡的地址
|注册的IP地址|`spring.cloud.nacos.discovery.ip`||优先级最高
|注册的IP地址类型|`spring.cloud.nacos.discovery.ip-type`|`IPv4`|可以配置IPv4和IPv6两种类型如果网卡同类型IP地址存在多个希望制定特定网段地址可使用`spring.cloud.inetutils.preferred-networks`配置筛选地址
|注册的端口|`spring.cloud.nacos.discovery.port`|`-1`|默认情况下不用配置,会自动探测
|命名空间|`spring.cloud.nacos.discovery.namespace`||常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
|AccessKey|`spring.cloud.nacos.discovery.access-key`||当要上阿里云时,阿里云上面的一个云账号名
|SecretKey|`spring.cloud.nacos.discovery.secret-key`||当要上阿里云时,阿里云上面的一个云账号密码
|Metadata|`spring.cloud.nacos.discovery.metadata`||使用Map格式配置用户可以根据自己的需要自定义一些和服务相关的元数据信息
|日志文件名|`spring.cloud.nacos.discovery.log-name`||
|集群|`spring.cloud.nacos.discovery.cluster-name`|`DEFAULT`|Nacos集群名称
|接入点|`spring.cloud.nacos.discovery.endpoint`||地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
|是否集成LoadBalancer|`spring.cloud.loadbalancer.nacos.enabled`|`false`|
|是否开启Nacos Watch|`spring.cloud.nacos.discovery.watch.enabled`|`false`|可以设置成 true 来开启 watch
|是否开启Nacos Discovery HeartBeat|`spring.cloud.nacos.discovery.heart-beat.enabled`|`false`|可以设置成 true 来开启 heart beat
|===

@ -1,140 +0,0 @@
== Spring Cloud AliCloud OSS
OSSObject Storage Service是阿里云的一款对象存储服务产品 Spring Cloud AliCloud OSS 提供了Spring Cloud规范下商业版的对象存储服务提供简单易用的API并且支持与 Spring 框架中 Resource 的整合。
=== 如何引入 Spring Cloud AliCloud OSS
如果要在您的项目中引入 OSS使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-oss` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
----
=== 如何使用 OSS API
==== 配置 OSS
使用 Spring Cloud AliCloud OSS 之前,需要在 application.properties 中加入以下配置。
[source,properties]
----
spring.cloud.alicloud.access-key=你的阿里云AK
spring.cloud.alicloud.secret-key=你的阿里云SK
spring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
----
access-key 和 secret-key 是阿里云账号的AK/SK需要首先注册阿里云账号然后登陆 https://usercenter.console.aliyun.com/#/manage/ak[阿里云AK/SK管理页面] ,即可看到 AccessKey ID 和 Access Key Secret ,如果没有的话,需要点击"创建AccessKey"按钮创建。
endpoint可以到 OSS 的 https://help.aliyun.com/document_detail/31837.html?spm=a2c4g.11186623.2.9.7dc72841Z2hGqa#concept-zt4-cvy-5db[官方文档]中查看,根据所在的 region ,填写对应的 endpoint 即可。
==== 引入 OSS API
Spring Cloud Alicloud OSS 中的 OSS API 基于阿里云官方OSS SDK提供具备上传、下载、查看等所有对象存储类操作API。
一个简单的使用 OSS API 的应用如下。
[source,java]
----
@SpringBootApplication
public class OssApplication {
@Autowired
private OSS ossClient;
@RequestMapping("/")
public String home() {
ossClient.putObject("bucketName", "fileName", new FileInputStream("/your/local/file/path"));
return "upload success";
}
public static void main(String[] args) throws URISyntaxException {
SpringApplication.run(OssApplication.class, args);
}
}
----
在上传文件之前,首先需要 https://account.aliyun.com/register/register.htm?spm=5176.8142029.388261.26.e9396d3eaYK2sG&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F[注册阿里云账号] ,如果已经有的话,请 https://common-buy.aliyun.com/?spm=5176.8465980.unusable.dopen.4cdf1450rg8Ujb&commodityCode=oss#/open[开通OSS服务]。
进入 https://oss.console.aliyun.com/overview[OSS控制台],点击左侧"新建Bucket"按照提示创建一个Bucket然后将bucket名称替换掉上面代码中的"bucketName",而"fileName"取任意文件名,"/your/local/file/path"取任意本地文件路径,然后 curl http://127.0.0.1:端口/ 即可上传文件,可以到 https://oss.console.aliyun.com/overview[OSS控制台]查看效果。
更多关于 OSS API 的操作,可以参考 https://help.aliyun.com/document_detail/32008.html[OSS官方SDK文档]。
=== 与 Spring 框架的 Resource 结合
Spring Cloud AliCloud OSS 整合了 Spring 框架的 Resource 规范,可以让用户很方便的引用 OSS 的资源。
一个简单的使用 Resource 的例子如下。
[source,java]
----
@SpringBootApplication
public class OssApplication {
@Value("oss://bucketName/fileName")
private Resource file;
@GetMapping("/file")
public String fileResource() {
try {
return "get file resource success. content: " + StreamUtils.copyToString(
file.getInputStream(), Charset.forName(CharEncoding.UTF_8));
} catch (Exception e) {
return "get resource fail: " + e.getMessage();
}
}
public static void main(String[] args) throws URISyntaxException {
SpringApplication.run(OssApplication.class, args);
}
}
----
NOTE: 以上示例运行的前提是,在 OSS 上需要有名为"bucketName"的Bucket同时在该Bucket下存在名为"fileName"的文件。
=== 采用 STS 授权
Spring Cloud AliCloud OSS 除了 AccessKey/SecretKey 的授权方式以外,还支持 STS 授权方式。 STS 是临时访问令牌的方式,一般用于授权第三方,临时访问自己的资源。
作为第三方,也就是被授权者,只需要配置以下内容,就可以访问临时被授权的资源。
[source,properties]
----
spring.cloud.alicloud.oss.authorization-mode=STS
spring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
spring.cloud.alicloud.oss.sts.access-key=你被授权的AK
spring.cloud.alicloud.oss.sts.secret-key=你被授权的SK
spring.cloud.alicloud.oss.sts.security-token=你被授权的ST
----
其中 spring.cloud.alicloud.oss.authorization-mode 是枚举类型,此时填写 STS ,代表采用 STS 的方式授权。 endpoint可以到 OSS 的 https://help.aliyun.com/document_detail/31837.html?spm=a2c4g.11186623.2.9.7dc72841Z2hGqa#concept-zt4-cvy-5db[官方文档]中查看,根据所在的 region ,填写对应的 endpoint 即可。
access-key、secret-key和security-token需要由授权方颁发如果对 STS 不了解的话,可以参考 https://help.aliyun.com/document_detail/31867.html[STS官方文档]。
=== 更多客户端配置
除了基本的配置项以外, Spring Cloud AliCloud OSS 还支持很多额外的配置,也是在 application.properties 文件中。
以下是一些简单的示例。
[source,properties]
----
spring.cloud.alicloud.oss.authorization-mode=STS
spring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
spring.cloud.alicloud.oss.sts.access-key=你被授权的AK
spring.cloud.alicloud.oss.sts.secret-key=你被授权的SK
spring.cloud.alicloud.oss.sts.security-token=你被授权的ST
spring.cloud.alicloud.oss.config.connection-timeout=3000
spring.cloud.alicloud.oss.config.max-connections=1000
----
如果想了解更多的配置项,可以参考 https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.703.50b25413nGsYHc[OSSClient配置项] 的末尾表格。
NOTE: 通常情况下,都需要将 https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.703.50b25413nGsYHc[OSSClient配置项] 末尾表格中的参数名更换成"-"连接,且所有字母小写。例如 ConnectionTimeout对应 connection-timeout。

@ -1,333 +0,0 @@
== Spring Cloud Alibaba RocketMQ Binder (NEW)
=== RocketMQ 介绍
https://rocketmq.apache.org[RocketMQ] 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。
具有以下特点:
* 能够保证严格的消息顺序
* 提供丰富的消息拉取模式
* 高效的订阅者水平扩展能力
* 实时的消息订阅机制
* 亿级消息堆积能力
=== RocketMQ 基本使用
* 下载 RocketMQ
下载 https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip[RocketMQ最新的二进制文件],并解压
解压后的目录结构如下:
```
apache-rocketmq
├── LICENSE
├── NOTICE
├── README.md
├── benchmark
├── bin
├── conf
└── lib
```
* 启动 NameServer
```bash
nohup sh bin/mqnamesrv &
tail -f ~/logs/rocketmqlogs/namesrv.log
```
* 启动 Broker
```bash
nohup sh bin/mqbroker -n localhost:9876 &
tail -f ~/logs/rocketmqlogs/broker.log
```
* 发送、接收消息
发送消息:
```bash
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
```
发送成功后显示:`SendResult [sendStatus=SEND_OK, msgId= ...`
接收消息:
```bash
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
```
接收成功后显示:`ConsumeMessageThread_%d Receive New Messages: [MessageExt...`
* 关闭 Server
```bash
sh bin/mqshutdown broker
sh bin/mqshutdown namesrv
```
=== Spring Cloud Stream 介绍
Spring Cloud Stream 是一个用于构建基于消息的微服务应用框架。它基于 SpringBoot 来创建具有生产级别的单机 Spring 应用,并且使用 `Spring Integration` 与 Broker 进行连接。
Spring Cloud Stream 提供了消息中间件配置的统一抽象,推出了 publish-subscribe、consumer groups、partition 这些统一的概念。
Spring Cloud Stream 内部有两个概念Binder 和 Binding。
* Binder: 跟外部消息中间件集成的组件,用来创建 Binding各消息中间件都有自己的 Binder 实现。
比如 `Kafka` 的实现 `KafkaMessageChannelBinder``RabbitMQ` 的实现 `RabbitMessageChannelBinder` 以及 `RocketMQ` 的实现 `RocketMQMessageChannelBinder`。
* Binding: 包括 Input Binding 和 Output Binding。
Binding 在消息中间件与应用程序提供的 Provider 和 Consumer 之间提供了一个桥梁,实现了开发者只需使用应用程序的 Provider 或 Consumer 生产或消费数据即可,屏蔽了开发者与底层消息中间件的接触。
.Spring Cloud Stream
image::https://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/images/SCSt-overview.png[]
使用 Spring Cloud Stream 完成一段简单的消息发送和消息接收代码:
```java
MessageChannel messageChannel = new DirectChannel();
// 消息订阅
((SubscribableChannel) messageChannel).subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
System.out.println("receive msg: " + message.getPayload());
}
});
// 消息发送
messageChannel.send(MessageBuilder.withPayload("simple msg").build());
```
这段代码所有的消息类都是 `spring-messaging` 模块里提供的。屏蔽具体消息中间件的底层实现,如果想用更换消息中间件,在配置文件里配置相关消息中间件信息以及修改 binder 依赖即可。
**Spring Cloud Stream 底层基于这段代码去做了各种抽象。**
=== 如何使用 Spring Cloud Alibaba RocketMQ Binder
如果要在您的项目中引入 RocketMQ Binder需要引入如下 maven 依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
</dependency>
```
或者可以使用 Spring Cloud Stream RocketMQ Starter
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
```
=== Spring Cloud Alibaba RocketMQ Binder 实现
这是 Spring Cloud Stream RocketMQ Binder 的实现架构:
.SCS RocketMQ Binder
image::https://img.alicdn.com/tfs/TB1v8rcbUY1gK0jSZFCXXcwqXXa-1236-773.png[]
RocketMQ Binder 的重构优化去除了对 https://github.com/apache/rocketmq-spring[RocketMQ-Spring]框架的依赖 。
RocketMQ Binder 核心类 `RocketMQMessageChannelBinder` 实现了 Spring Cloud Stream 规范,内部会构建 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java[RocketMQInboundChannelAdapter] 和 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java[RocketMQProducerMessageHandler]。
`RocketMQProducerMessageHandler` 会基于 Binding 配置通过 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java[RocketMQProduceFactory]构造 RocketMQ Producer其内部会把 `spring-messaging` 模块内 `org.springframework.messaging.Message` 消息类转换成 RocketMQ 的消息类 `org.apache.rocketmq.common.message.Message`,然后发送出去。
`RocketMQInboundChannelAdapter` 也会基于 Binding 配置通过 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java[RocketMQConsumerFactory]构造 DefaultMQPushConsumer其内部会启动 RocketMQ Consumer 接收消息。
NOTE: 与 https://github.com/apache/rocketmq-spring[RocketMQ-Spring] 框架的兼容需要手动处理
目前 Binder 支持在 `Header` 中设置相关的 key 来进行 RocketMQ Message 消息的特性设置。
比如 `TAGS`、`KEYS`、`TRANSACTIONAL_ARGS` 等 RocketMQ 消息对应的标签,详情见 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java[com.alibaba.cloud.stream.binder.rocketmq.constant.RocketMQConst]
```java
MessageBuilder builder = MessageBuilder.withPayload(msg)
.setHeader(RocketMQHeaders.TAGS, "binder")
.setHeader(RocketMQHeaders.KEYS, "my-key");
Message message = builder.build();
output().send(message);
```
或者使用StreamBridge
```java
MessageBuilder builder = MessageBuilder.withPayload(msg)
.setHeader(RocketMQHeaders.TAGS, "binder")
.setHeader(RocketMQHeaders.KEYS, "my-key");
Message message = builder.build();
streamBridge.send("producer-out-0", message);
```
NOTE: 更多使用请参考样例: https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/rocketmq-example[RocketMQ Example]
=== 配置选项
==== RocketMQ Binder Properties
spring.cloud.stream.rocketmq.binder.name-server::
RocketMQ NameServer 地址(老版本使用 namesrv-addr 配置项)。
+
Default: `127.0.0.1:9876`.
spring.cloud.stream.rocketmq.binder.access-key::
阿里云账号 AccessKey。
+
Default: null.
spring.cloud.stream.rocketmq.binder.secret-key::
阿里云账号 SecretKey。
+
Default: null.
spring.cloud.stream.rocketmq.binder.enable-msg-trace::
是否为 Producer 和 Consumer 开启消息轨迹功能
+
Default: `true`.
spring.cloud.stream.rocketmq.binder.customized-trace-topic::
消息轨迹开启后存储的 topic 名称。
+
Default: `RMQ_SYS_TRACE_TOPIC`.
==== RocketMQ Consumer Properties
下面的这些配置是以 `spring.cloud.stream.rocketmq.bindings.<channelName>.consumer.` 为前缀的 RocketMQ Consumer 相关的配置。
更多见 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQConsumerProperties.java[com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties]。
enable::
是否启用 Consumer。
+
默认值: `true`.
subscription::
Consumer 基于 TAGS 订阅,多个 tag 以 `||` 分割。更多见 `com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties.subscription`
+
默认值: empty.
messageModel::
Consumer 消费模式。如果想让每一个的订阅者都能接收到消息,可以使用广播模式。更多见 `org.apache.rocketmq.common.protocol.heartbeat.MessageModel`
+
默认值: `CLUSTERING`.
consumeFromWhere::
Consumer 从哪里开始消费。更多见 `org.apache.rocketmq.common.consumer.ConsumeFromWhere`
+
默认值: `CONSUME_FROM_LAST_OFFSET`.
#下面的这些配置是 Consumer Push 模式相关的配置。#
`spring.cloud.stream.rocketmq.bindings.<channelName>.consumer.push.`
orderly::
是否同步消费消息模式
+
默认值: `false`.
delayLevelWhenNextConsume::
异步消费消息模式下消费失败重试策略:
* -1,不重复,直接放入死信队列
* 0,broker 控制重试策略
* >0,client 控制重试策略
+
默认值: `0`.
suspendCurrentQueueTimeMillis::
同步消费消息模式下消费失败后再次消费的时间间隔。
+
默认值: `1000`.
其他更多参数见 `com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties.Push`
#下面的这些配置是 Consumer Pull 模式相关的配置。#
`spring.cloud.stream.rocketmq.bindings.<channelName>.consumer.pull.`
pullThreadNums::
消费时拉取的线程数
+
默认值: `20`.
pollTimeoutMillis::
拉取时的超时毫秒数
+
默认值: `1000 * 5`.
其他更多参数见 `com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties.Pull`.
NOTE: 更多参数见 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQConsumerProperties.java[com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties]
==== RocketMQ Provider Properties
下面的这些配置是以 `spring.cloud.stream.rocketmq.bindings.<channelName>.producer.` 为前缀的 RocketMQ Producer 相关的配置。更多见 https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java[com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties]
enable::
是否启用 Producer。
+
默认值: `true`.
group::
Producer group name。
+
默认值: empty.
maxMessageSize::
消息发送的最大字节数。
+
默认值: `8249344`.
producerType::
消息生产者类型,普通或者事务。更多见 `com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties.ProducerType`.
+
默认值: `Normal`.
transactionListener::
事务消息监听器的beanName在 `producerType=Trans` 时才有效;必须是实现 `org.apache.rocketmq.client.producer.TransactionListener` 接口的Spring Bean。
sendType::
消息发送类型(同步、异步、单向)。更多见`com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties.SendType`.
+
默认值: `Sync`.
sendCallBack::
消息发送后回调函数的beanName在 `sendType=Async` 时才有效;必须是实现 `org.apache.rocketmq.client.producer.SendCallback` 接口的Spring Bean。
vipChannelEnabled::
是否在 Vip Channel 上发送消息。
+
默认值: `true`.
sendMessageTimeout::
发送消息的超时时间(毫秒)。
+
默认值: `3000`.
compressMessageBodyThreshold::
消息体压缩阀值(当消息体超过 4k 的时候会被压缩)。
+
默认值: `4096`.
retryTimesWhenSendFailed::
在同步发送消息的模式下,消息发送失败的重试次数。
+
默认值: `2`.
retryTimesWhenSendAsyncFailed::
在异步发送消息的模式下,消息发送失败的重试次数。
+
默认值: `2`.
retryAnotherBroker::
消息发送失败的情况下是否重试其它的 broker。
+
默认值: `false`.
NOTE: 生产者其他更多参数请见:
https://github.com/alibaba/spring-cloud-alibaba/blob/rocketmq/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java[com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties]
=== 阿里云 MQ 服务
使用阿里云 MQ 服务需要配置 AccessKey、SecretKey 以及云上的 NameServer 地址。
NOTE: 0.1.2 & 0.2.2 & 0.9.0 才支持该功能
```properties
spring.cloud.stream.rocketmq.binder.access-key=YourAccessKey
spring.cloud.stream.rocketmq.binder.secret-key=YourSecretKey
spring.cloud.stream.rocketmq.binder.name-server=NameServerInMQ
```
NOTE: topic 和 group 请以 实例id% 为前缀进行配置。比如 topic 为 "test",需要配置成 "实例id%test"
.NameServer 的获取(配置中请去掉 http:// 前缀)

@ -1,360 +0,0 @@
== Spring Cloud Alibaba RocketMQ Binder
=== RocketMQ 介绍
https://rocketmq.apache.org[RocketMQ] 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。
具有以下特点:
* 能够保证严格的消息顺序
* 提供丰富的消息拉取模式
* 高效的订阅者水平扩展能力
* 实时的消息订阅机制
* 亿级消息堆积能力
=== RocketMQ 基本使用
* 下载 RocketMQ
下载 https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip[RocketMQ最新的二进制文件],并解压
解压后的目录结构如下:
```
apache-rocketmq
├── LICENSE
├── NOTICE
├── README.md
├── benchmark
├── bin
├── conf
└── lib
```
* 启动 NameServer
```bash
nohup sh bin/mqnamesrv &
tail -f ~/logs/rocketmqlogs/namesrv.log
```
* 启动 Broker
```bash
nohup sh bin/mqbroker -n localhost:9876 &
tail -f ~/logs/rocketmqlogs/broker.log
```
* 发送、接收消息
发送消息:
```bash
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
```
发送成功后显示:`SendResult [sendStatus=SEND_OK, msgId= ...`
接收消息:
```bash
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
```
接收成功后显示:`ConsumeMessageThread_%d Receive New Messages: [MessageExt...`
* 关闭 Server
```bash
sh bin/mqshutdown broker
sh bin/mqshutdown namesrv
```
=== Spring Cloud Stream 介绍
Spring Cloud Stream 是一个用于构建基于消息的微服务应用框架。它基于 SpringBoot 来创建具有生产级别的单机 Spring 应用,并且使用 `Spring Integration` 与 Broker 进行连接。
Spring Cloud Stream 提供了消息中间件配置的统一抽象,推出了 publish-subscribe、consumer groups、partition 这些统一的概念。
Spring Cloud Stream 内部有两个概念Binder 和 Binding。
* Binder: 跟外部消息中间件集成的组件,用来创建 Binding各消息中间件都有自己的 Binder 实现。
比如 `Kafka` 的实现 `KafkaMessageChannelBinder``RabbitMQ` 的实现 `RabbitMessageChannelBinder` 以及 `RocketMQ` 的实现 `RocketMQMessageChannelBinder`。
* Binding: 包括 Input Binding 和 Output Binding。
Binding 在消息中间件与应用程序提供的 Provider 和 Consumer 之间提供了一个桥梁,实现了开发者只需使用应用程序的 Provider 或 Consumer 生产或消费数据即可,屏蔽了开发者与底层消息中间件的接触。
.Spring Cloud Stream
image::https://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/images/SCSt-overview.png[]
使用 Spring Cloud Stream 完成一段简单的消息发送和消息接收代码:
```java
MessageChannel messageChannel = new DirectChannel();
// 消息订阅
((SubscribableChannel) messageChannel).subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
System.out.println("receive msg: " + message.getPayload());
}
});
// 消息发送
messageChannel.send(MessageBuilder.withPayload("simple msg").build());
```
这段代码所有的消息类都是 `spring-messaging` 模块里提供的。屏蔽具体消息中间件的底层实现,如果想用更换消息中间件,在配置文件里配置相关消息中间件信息以及修改 binder 依赖即可。
**Spring Cloud Stream 底层基于这段代码去做了各种抽象。**
=== 如何使用 Spring Cloud Alibaba RocketMQ Binder
如果要在您的项目中引入 RocketMQ Binder需要引入如下 maven 依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
</dependency>
```
或者可以使用 Spring Cloud Stream RocketMQ Starter
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
```
=== Spring Cloud Alibaba RocketMQ Binder 实现
这是 Spring Cloud Stream RocketMQ Binder 的实现架构:
.SCS RocketMQ Binder
image::https://img.alicdn.com/tfs/TB1v8rcbUY1gK0jSZFCXXcwqXXa-1236-773.png[]
RocketMQ Binder 的实现依赖于 https://github.com/apache/rocketmq-spring[RocketMQ-Spring] 框架。
RocketMQ-Spring 框架是 RocketMQ 与 Spring Boot 的整合RocketMQ Spring 主要提供了 3 个特性:
1. 使用 `RocketMQTemplate` 用来统一发送消息,包括同步、异步发送消息和事务消息
2. `@RocketMQTransactionListener` 注解用来处理事务消息的监听和回查
3. `@RocketMQMessageListener` 注解用来消费消息
RocketMQ Binder 的核心类 RocketMQMessageChannelBinder 实现了 Spring Cloud Stream 规范,内部构建会 `RocketMQInboundChannelAdapter` 和 `RocketMQMessageHandler`。
`RocketMQMessageHandler` 会基于 Binding 配置构造 `RocketMQTemplate``RocketMQTemplate` 内部会把 `spring-messaging` 模块内 `org.springframework.messaging.Message` 消息类转换成 RocketMQ 的消息类 `org.apache.rocketmq.common.message.Message`,然后发送出去。
`RocketMQInboundChannelAdapter` 也会基于 Binding 配置构造 `RocketMQListenerBindingContainer``RocketMQListenerBindingContainer` 内部会启动 RocketMQ `Consumer` 接收消息。
NOTE: 在使用 RocketMQ Binder 的同时也可以配置 rocketmq.** 用于触发 RocketMQ Spring 相关的 AutoConfiguration
目前 Binder 支持在 `Header` 中设置相关的 key 来进行 RocketMQ Message 消息的特性设置。
比如 `TAGS`、`DELAY`、`TRANSACTIONAL_ARG`、`KEYS`、`WAIT_STORE_MSG_OK`、`FLAG` 表示 RocketMQ 消息对应的标签,
```java
MessageBuilder builder = MessageBuilder.withPayload(msg)
.setHeader(RocketMQHeaders.TAGS, "binder")
.setHeader(RocketMQHeaders.KEYS, "my-key")
.setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");
Message message = builder.build();
output().send(message);
```
=== MessageSource 支持
SCS RocketMQ Binder 支持 `MessageSource`,可以进行消息的拉取,例子如下:
```java
@SpringBootApplication
@EnableBinding(MQApplication.PolledProcessor.class)
public class MQApplication {
private final Logger logger =
LoggerFactory.getLogger(MQApplication.class);
public static void main(String[] args) {
SpringApplication.run(MQApplication.class, args);
}
@Bean
public ApplicationRunner runner(PollableMessageSource source,
MessageChannel dest) {
return args -> {
while (true) {
boolean result = source.poll(m -> {
String payload = (String) m.getPayload();
logger.info("Received: " + payload);
dest.send(MessageBuilder.withPayload(payload.toUpperCase())
.copyHeaders(m.getHeaders())
.build());
}, new ParameterizedTypeReference<String>() { });
if (result) {
logger.info("Processed a message");
}
else {
logger.info("Nothing to do");
}
Thread.sleep(5_000);
}
};
}
public static interface PolledProcessor {
@Input
PollableMessageSource source();
@Output
MessageChannel dest();
}
}
```
=== 配置选项
==== RocketMQ Binder Properties
spring.cloud.stream.rocketmq.binder.name-server::
RocketMQ NameServer 地址(老版本使用 namesrv-addr 配置项)。
+
Default: `127.0.0.1:9876`.
spring.cloud.stream.rocketmq.binder.access-key::
阿里云账号 AccessKey。
+
Default: null.
spring.cloud.stream.rocketmq.binder.secret-key::
阿里云账号 SecretKey。
+
Default: null.
spring.cloud.stream.rocketmq.binder.enable-msg-trace::
是否为 Producer 和 Consumer 开启消息轨迹功能
+
Default: `true`.
spring.cloud.stream.rocketmq.binder.customized-trace-topic::
消息轨迹开启后存储的 topic 名称。
+
Default: `RMQ_SYS_TRACE_TOPIC`.
+
spring.cloud.stream.rocketmq.binder.access-channel::
商业版rocketmq消息轨迹topic自适应值为CLOUD
+
Default: null.
==== RocketMQ Consumer Properties
下面的这些配置是以 `spring.cloud.stream.rocketmq.bindings.<channelName>.consumer.` 为前缀的 RocketMQ Consumer 相关的配置。
enable::
是否启用 Consumer。
+
默认值: `true`.
tags::
Consumer 基于 TAGS 订阅,多个 tag 以 `||` 分割。
+
默认值: empty.
sql::
Consumer 基于 SQL 订阅。
+
默认值: empty.
broadcasting::
Consumer 是否是广播消费模式。如果想让所有的订阅者都能接收到消息,可以使用广播模式。
+
默认值: `false`.
orderly::
Consumer 是否同步消费消息模式。
+
默认值: `false`.
delayLevelWhenNextConsume::
异步消费消息模式下消费失败重试策略:
* -1,不重复,直接放入死信队列
* 0,broker 控制重试策略
* >0,client 控制重试策略
+
默认值: `0`.
suspendCurrentQueueTimeMillis::
同步消费消息模式下消费失败后再次消费的时间间隔。
+
默认值: `1000`.
==== RocketMQ Provider Properties
下面的这些配置是以 `spring.cloud.stream.rocketmq.bindings.<channelName>.producer.` 为前缀的 RocketMQ Producer 相关的配置。
enable::
是否启用 Producer。
+
默认值: `true`.
group::
Producer group name。
+
默认值: empty.
maxMessageSize::
消息发送的最大字节数。
+
默认值: `8249344`.
transactional::
是否发送事务消息。
+
默认值: `false`.
sync::
是否使用同步得方式发送消息。
+
默认值: `false`.
vipChannelEnabled::
是否在 Vip Channel 上发送消息。
+
默认值: `true`.
sendMessageTimeout::
发送消息的超时时间(毫秒)。
+
默认值: `3000`.
compressMessageBodyThreshold::
消息体压缩阀值(当消息体超过 4k 的时候会被压缩)。
+
默认值: `4096`.
retryTimesWhenSendFailed::
在同步发送消息的模式下,消息发送失败的重试次数。
+
默认值: `2`.
retryTimesWhenSendAsyncFailed::
在异步发送消息的模式下,消息发送失败的重试次数。
+
默认值: `2`.
retryNextServer::
消息发送失败的情况下是否重试其它的 broker。
+
默认值: `false`.
=== 阿里云 MQ 服务
使用阿里云 MQ 服务需要配置 AccessKey、SecretKey 以及云上的 NameServer 地址。
NOTE: 0.1.2 & 0.2.2 & 0.9.0 才支持该功能
```properties
spring.cloud.stream.rocketmq.binder.access-key=YourAccessKey
spring.cloud.stream.rocketmq.binder.secret-key=YourSecretKey
spring.cloud.stream.rocketmq.binder.name-server=NameServerInMQ
spring.cloud.stream.rocketmq.binder.access-channel=CLOUD
```
NOTE: topic 和 group 请以 实例id% 为前缀进行配置。比如 topic 为 "test",需要配置成 "实例id%test"
.NameServer 的获取(配置中请去掉 http:// 前缀)
image::https://spring-cloud-alibaba.oss-cn-beijing.aliyuncs.com/MQ.png[]

@ -1,186 +0,0 @@
== Spring Cloud Alibaba 2021.0.1.0 升级指南
=== 版本号
从 2021.0.1.0 开始SCA 版本将会对应 Spring Cloud 版本,
前三位为 Spring Cloud 版本,最后一位为扩展版本
=== 升级步骤
升级版本 (注意版本对应关系)
```xml
<dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
```
*注意事项:* `spring-cloud-starter-alibaba-nacos-config` 模块移除了 `spring-cloud-starter-bootstrap` 依赖,如果你想以旧版的方式使用,你需要手动加上该依赖,现在推荐使用 `spring.config.import` 方式引入配置
完成以上步骤就能无缝切换到 `spring cloud alibaba 2021.0.1.0` 版本
=== 新特性及其使用
==== 支持 spring.config.import
这里假设有一个配置文件(`bootstrap.yml`),升级到新版本应该怎么配置呢
```yaml
# bootstrap.yml
spring:
cloud:
nacos:
config:
name: test.yml
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848
extension-configs:
- dataId: test01.yml
group: group_01
- dataId: test02.yml
group: group_02
refresh: false
```
这两个配置是等价的
```yaml
# application.yml
spring:
cloud:
nacos:
config:
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848
config:
import:
- optional:nacos:test.yml # 监听 DEFAULT_GROUP:test.yml
- optional:nacos:test01.yml?group=group_01 # 覆盖默认 group监听 group_01:test01.yml
- optional:nacos:test02.yml?group=group_02&refreshEnabled=false # 不开启动态刷新
- nacos:test03.yml # 在拉取nacos配置异常时会快速失败会导致 spring 容器启动失败
```
注意事项:
- 如果使用 `spring.config.import` 就不能使用 bootstrap.yml/properties 引入配置的方式了 !!!
- 如果引入了 `spring-cloud-starter-alibaba-nacos-config`,并且使用 import 方式导入配置,
项目启动时会自动检测是否引入了 `nacos:` 条目,如果没有 import nacos 条目,会出现如下错误:
----
The spring.config.import property is missing a nacos: entry
Action:
Add a spring.config.import=nacos: property to your configuration.
If configuration is not required add spring.config.import=optional:nacos: instead.
To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.
----
你可以手动通设置 `spring.cloud.nacos.config.import-check.enabled=false` 关闭它,但是不建议这么做,这个功能可以帮助你检查是否引入多余依赖
- 假如想保留以前的使用方式 (bootstrap引入配置),你只需要添加依赖 `spring-cloud-starter-bootstrap` 依赖,不需要修改一行代码
你可以前往 https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/nacos-example/nacos-config-2.4.x-example[这里] 查看具体example
==== Nacos 容错能力
新增配置项 `spring.cloud.nacos.discovery.failure-tolerance-enabled`
设置为 true (默认 false) 开启 nacos 服务发现失败容错能力,该功能会在 nacos 获取实例失败时返回上一次获取的实例,可以在 nacos server 网络不稳定时提供容错能力,不会导致请求全部挂掉
==== 支持 feign 灵活的熔断配置
当 Sentinel 作为 Spring Cloud 断路器实现时,支持为每个 FeignClient 添加断路器配置
添加依赖
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
</dependency>
```
这里有两个 FeignClient
```java
@FeignClient(value = "user", fallback = UserFallback.class)
public interface UserClient {
@GetMapping("/{success}")
String success(@PathVariable Boolean success);
}
@FeignClient(value = "order", fallback = OrderFallback.class)
public interface OrderClient {
@GetMapping("/{success}")
String success(@PathVariable Boolean success);
@GetMapping("/{success}")
String error(@PathVariable Boolean success);
}
```
现在有这些需求:
1. 我想要对全局的 FeignClient 配置一个默认熔断规则
2. 我想要对 user FeignClient 配置熔断规则
3. 我想要对 order FeignClient 的指定方法(error)配置熔断规则
添加以下配置
```yaml
feign:
circuitbreaker:
enabled: true
sentinel:
default-rule: default # 全局规则名称
rules:
# 全局配置,这些参数的意思请查看 com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule
# 可配置多条规则
default:
- grade: 2
count: 1
timeWindow: 1
statIntervalMs: 1000
minRequestAmount: 5
- grade: 2
count: 1
# 针对 user FeignClient
user:
- grade: 2
count: 1
timeWindow: 1
statIntervalMs: 1000
minRequestAmount: 5
# 针对 order FeignClient error 方法,注意中括号,不然会解析出来的值会不一致
"[order#error(Boolean)]":
- grade: 2
count: 1
timeWindow: 1
statIntervalMs: 1000
minRequestAmount: 5
```
该功能还支持从配置中心动态刷新,可以将上述配置放入配置中心(nacosconsul),修改规则会立刻生效,如果不需要该功能可以通过 `feign.sentinel.enable-refresh-rules=false` 来禁用它
*注意事项:* 如果你使用的是 `spring-cloud-starter-alibaba-sentinel`,请**不要**配置 `feign.sentinel.enable=true`,会使配置失效
你可以前往 https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-circuitbreaker-example[这里] 查看具体 example
=== 对升级的一点建议
1. 在 spring boot 2.6 之后默认开启了禁止循环引入,建议大家不要关闭,这是一种不好的编码习惯,如果你的项目里出现了循环引用,请选择重构它
2. 抛弃 bootstrap 引入配置的方式,使用 `spring.config.import` 方式引入配置spring boot 2.4 对这一块做了很大的优化工作,不再需要全量启动一个容器来刷新配置

@ -1,114 +0,0 @@
== Spring Cloud AliCloud SchedulerX
SchedulerX分布式任务调度 是隶属于阿里云EDAS产品的组件 Spring Cloud AliCloud SchedulerX 提供了在Spring Cloud的配置规范下分布式任务调度的功能支持。SchedulerX可提供秒级、精准、高可靠、高可用的定时任务调度服务并支持多种类型的任务调度如简单单机任务、简单多机任务、脚本任务以及网格任务。
=== 如何引入 Spring Cloud AliCloud SchedulerX
如果要在您的项目中引入 SchedulerX使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-schedulerX` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-schedulerX</artifactId>
</dependency>
----
=== 启动SchedulerX任务调度
当客户端引入了 Spring Cloud AliCloud SchedulerX Starter 以后只需要进行一些简单的配置就可以自动初始化SchedulerX的任务调度服务。
以下是一个简单的应用示例。
[source,java]
----
@SpringBootApplication
public class ScxApplication {
public static void main(String[] args) {
SpringApplication.run(ScxApplication.class, args);
}
}
----
在application.properties中需要加上以下配置。
[source,properties]
----
server.port=18033
# 其中cn-test是SchedulerX的测试区域
spring.cloud.alicloud.scx.group-id=***
spring.cloud.alicloud.edas.namespace=cn-test
----
在获取group-id之前需要首先 https://account.aliyun.com/register/register.htm?spm=5176.8142029.388261.26.e9396d3eEIv28g&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F[注册阿里云账号] ,然后 https://common-buy.aliyun.com/?spm=5176.11451019.0.0.6f5965c0Uq5tue&commodityCode=edaspostpay#/buy[开通EDAS服务] ,并 https://edas.console.aliyun.com/#/edasTools[开通分布式任务管理组件] 。
其中group-id的获取请参考 https://help.aliyun.com/document_detail/98784.html?spm=a2c4g.11186623.2.17.23c87da9P2F3tG[这里]。
NOTE: 在创建group的时候要选择"测试"区域。
=== 编写一个简单任务
简单任务是最常用的任务类型,只需要实现 ScxSimpleJobProcessor 接口即可。
以下是一个简单的单机类型任务示例。
[source,java]
----
public class SimpleTask implements ScxSimpleJobProcessor {
@Override
public ProcessResult process(ScxSimpleJobContext context) {
System.out.println("-----------Hello world---------------");
ProcessResult processResult = new ProcessResult(true);
return processResult;
}
}
----
=== 对任务进行调度
进入 https://edas.console.aliyun.com/#/edasSchedulerXJob?regionNo=cn-test[SchedulerX任务列表] 页面,选择上方"测试"区域,点击右上角"新建Job"创建一个Job即如下所示。
[source,text]
----
Job分组测试——***-*-*-****
Job处理接口org.springframework.cloud.alibaba.cloud.examples.SimpleTask
类型简单Job单机版
定时表达式默认选项——0 * * * * ?
Job描述
自定义参数:无
----
以上任务类型选择了"简单Job单机版"并且制定了Cron表达式为"0 * * * * ?",这意味着,每过一分钟,任务将会被执行且只执行一次。
更多任务类型,请参考 https://help.aliyun.com/document_detail/43136.html[SchedulerX官方文档]。
=== 生产环境使用
以上使用的都是SchedulerX的"测试"区域,主要用于本地调试和测试。
在生产级别除了上面的group-id和namespace以外还需要一些额外的配置如下所示。
[source,properties]
----
server.port=18033
# 其中cn-test是SchedulerX的测试区域
spring.cloud.alicloud.scx.group-id=***
spring.cloud.alicloud.edas.namespace=***
# 当应用运行在EDAS上时以下配置不需要手动配置。
spring.cloud.alicloud.access-key=***
spring.cloud.alicloud.secret-key=***
# 以下配置不是必须的请参考SchedulerX文档
spring.cloud.alicloud.scx.domain-name=***
----
其中group-id与之前的获取方式一样namespace则是从EDAS控制台左侧"命名空间"列表中获取命名空间ID。
NOTE: group-id必须创建在namespace当中。
access-key以及secret-key为阿里云账号的AK/SK信息如果应用在EDAS上部署则不需要填写这两项信息否则请前往 https://usercenter.console.aliyun.com/#/manage/ak[安全信息管理]获取。
domain-name并不是必须的具体请参考 https://help.aliyun.com/document_detail/35359.html[SchedulerX官方文档]。

@ -1,85 +0,0 @@
== Spring Cloud Alibaba Seata
=== Seata 介绍
Seata是一个分布式事务框架, 用于保证在微服务架构下每个服务的数据一致性。
=== 如何使用seata
如果要在您的项目中引入 Seata使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-seata` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
----
项目提供了相关实例 https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/seata-example[Example],在运行之前,您需要完成以下步骤:
1. 保证本地已经运行 `nacos-server` 在 `8848` 端口。
2. 配置数据库,将 `account-server`、`order-service`、`storage-service` 这三个应用中的 resources 目录下的 `application.yml` 文件中的如下配置修改成你运行环境中的实际配置。
base:
config:
mdb:
hostname: 127.0.0.1 #your mysql server ip address
dbname: seata #your database name for test
port: 3306 #your mysql server listening port
username: root #your mysql server username
password: root #your mysql server password
3. 创建数据库表,可根据 `spring-cloud-alibaba-examples/seata-example` 下的 `all.sql` 快速操作。
- 根据选择的事务模式,创建 https://github.com/seata/seata/tree/develop/script/client[事务日志表]。比如默认为AT模式需要使用到 undo_log 表,则进入 at/db 下选择对应的数据库脚本执行。
- 创建 seata-server db模式所需要的 https://github.com/seata/seata/tree/develop/script/server/db[状态记录表] ,包括 `global_table` 、`branch_table` 、`lock_table` 、`distributed_lock`。
- 创建 `spring-cloud-alibaba-examples/seata-example` 示例中所需的数据库表。
4. 创建 `spring-cloud-alibaba-examples/seata-example` 所需要的Nacos配置。
data id: seata.properties,
Group: SEATA_ Group(Seata 1.5.1 默认组)
配置内容:
service.vgroupMapping.order-service-tx-group=default
service.vgroupMapping.account-service-tx-group=default
service.vgroupMapping.business-service-tx-group=default
service.vgroupMapping.storage-service-tx-group=default
5. 启动 Seata Server有SpringBoot 和下载server两种方式。
- 运行 `spring-cloud-alibaba-examples/seata-example` 下的seata-server 启动Seata server。
- 根据seata官方提供的 https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html[seata-server.jar]启动Seata Server。
6. 在本地启动 `spring-cloud-alibaba-examples/seata-example` 文件夹下的子服务 `account-service` , `order-service` , `storage-service` ,最后启动全局事务控制服务 `business-service`。
7. 启动示例后,通过 HTTP 的 GET 方法访问如下 URL可以分别验证在 `business-service` 中 通过 RestTemplate 和 FeignClient 调用其他服务的场景。
http://127.0.0.1:18081/seata/feign
http://127.0.0.1:18081/seata/rest
=== Seata Dashboard
- Seata 1.5.1支持Seata控制台本地访问控制台地址`http://127.0.0.1:7091`。
- 通过Seata控制台可以观察到正在执行的事务信息和全局锁信息并且在事务完成时删除相关信息。
=== 如何验证分布式事务的成功?
==== Xid 信息是否成功传递
在 `account-server`、`order-service` 和 `storage-service` 三个 服务的 Controller 中,第一个执行的逻辑都是输出 RootContext 中的 Xid 信息,如果看到都输出了正确的 Xid 信息,即每次都发生变化,且同一次调用中所有服务的 Xid 都一致。则表明 Seata 的 Xid 的传递和还原是正常的。
==== 数据库中数据的一致性
在这个例子中我们模拟一个用户购买商品的场景StorageService 负责扣除库存数量OrderService 负责保存订单BusinessService 负责扣除用户账户余额,AccountService 负责更新账号的余额,并作为全局事务控制入口。
为了演示示例,我们在 OrderService 和 AcountService 中使用了 Random。NextBoolean() 随机抛出异常,模拟调用服务时随机发生异常的场景。
如果分布式事务是有效的,那么下面的等式应该是正确的
- 用户原始金额1000=用户现有金额+商品单价2*订单数量*每个订单的商品数量2
- 初始商品数量 (100) = 现有商品数量 + 订单数量 * 每个订单的商品数量 (2)
=== Spring Cloud 支持点
- 通过 Spring MVC 提供服务的服务提供者在收到 HTTP 请求时,可以自动恢复 Seata 上下文,该请求在 header 中包含 Seata 信息。
- 当服务调用者通过 RestTemplate 调用时,支持自动传递 Seata 上下文。
- 当服务调用者通过 FeignClient 调用时,支持自动传递 Seata 上下文。
- 支持同时使用 SeataClient 和 Hystrix 的场景。
- 支持 SeataClient 和 Sentinel 使用的场景。

@ -1,425 +0,0 @@
== Spring Cloud Alibaba Sentinel
=== Sentinel 介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 https://github.com/alibaba/Sentinel[Sentinel] 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
https://github.com/alibaba/Sentinel[Sentinel] 具有以下特征:
* *丰富的应用场景* Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
* *完备的实时监控* Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
* *广泛的开源生态* Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
* *完善的 SPI 扩展点* Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。
=== 如何使用 Sentinel
如果要在您的项目中引入 Sentinel使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-sentinel` 的 starter。
```xml
[source,yaml]
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
```
下面这个例子就是一个最简单的使用 Sentinel 的例子:
```java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
@RestController
public class TestController {
@GetMapping(value = "/hello")
@SentinelResource("hello")
public String hello() {
return "Hello Sentinel";
}
}
```
@SentinelResource 注解用来标识资源是否被限流、降级。上述例子上该注解的属性 'hello' 表示资源名。
@SentinelResource 还提供了其它额外的属性如 `blockHandler``blockHandlerClass``fallback` 用于表示限流或降级的操作,更多内容可以参考 https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81[Sentinel注解支持]。
以上例子都是在 WebServlet 环境下使用的Sentinel 目前已经支持 WebFlux需要配合 `spring-boot-starter-webflux` 依赖触发 sentinel-starter 中 WebFlux 相关的自动化配置。
```java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
@RestController
public class TestController {
@GetMapping("/mono")
@SentinelResource("hello")
public Mono<String> mono() {
return Mono.just("simple string")
.transform(new SentinelReactorTransformer<>("otherResourceName"));
}
}
```
===== Sentinel 控制台
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。
*注意*: 集群资源汇总仅支持 500 台以下的应用集群,有大概 1 - 2 秒的延时。
.Sentinel Dashboard
image::https://github.com/alibaba/Sentinel/wiki/image/dashboard.png[]
开启该功能需要3个步骤
====== 获取控制台
您可以从 https://github.com/alibaba/Sentinel/releases[release 页面] 下载最新版本的控制台 jar 包。
您也可以从最新版本的源码自行构建 Sentinel 控制台:
* 下载 https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard[控制台] 工程
* 使用以下命令将代码打包成一个 fat jar: `mvn clean package`
====== 启动控制台
Sentinel 控制台是一个标准的 SpringBoot 应用,以 SpringBoot 的方式运行 jar 包即可。
```shell
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
```
如若8080端口冲突可使用 `-Dserver.port=新端口` 进行设置。
==== 配置控制台信息
.application.yml
----
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
----
这里的 `spring.cloud.sentinel.transport.port` 端口配置会在应用对应的机器上启动一个 Http Server该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则会把规则数据 push 给这个 Http Server 接收Http Server 再将规则注册到 Sentinel 中。
更多 Sentinel 控制台的使用及问题参考: https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0[Sentinel控制台]
=== OpenFeign 支持
Sentinel 适配了 https://github.com/OpenFeign/feign[OpenFeign] 组件。如果想使用,除了引入 `sentinel-starter` 的依赖外还需要 2 个步骤:
* 配置文件打开 sentinel 对 feign 的支持:`feign.sentinel.enabled=true`
* 加入 `openfeign starter` 依赖使 `sentinel starter` 中的自动化配置类生效:
```xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
```
这是一个 `FeignClient` 的简单使用示例:
```java
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@GetMapping(value = "/echo/{str}")
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
```
NOTE: Feign 对应的接口中的资源名策略定义httpmethod:protocol://requesturl。`@FeignClient` 注解中的所有属性Sentinel 都做了兼容。
`EchoService` 接口中方法 `echo` 对应的资源名为 `GET:http://service-provider/echo/{str}`。
=== RestTemplate 支持
Spring Cloud Alibaba Sentinel 支持对 `RestTemplate` 的服务调用使用 Sentinel 进行保护,在构造 `RestTemplate` bean的时候需要加上 `@SentinelRestTemplate` 注解。
```java
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
```
`@SentinelRestTemplate` 注解的属性支持限流(`blockHandler`, `blockHandlerClass`)和降级(`fallback`, `fallbackClass`)的处理。
其中 `blockHandler` 或 `fallback` 属性对应的方法必须是对应 `blockHandlerClass` 或 `fallbackClass` 属性中的静态方法。
该方法的参数跟返回值跟 `org.springframework.http.client.ClientHttpRequestInterceptor#interceptor` 方法一致,其中参数多出了一个 `BlockException` 参数用于获取 Sentinel 捕获的异常。
比如上述 `@SentinelRestTemplate` 注解中 `ExceptionUtil` 的 `handleException` 属性对应的方法声明如下:
```java
public class ExceptionUtil {
public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
...
}
}
```
NOTE: 应用启动的时候会检查 `@SentinelRestTemplate` 注解对应的限流或降级方法是否存在,如不存在会抛出异常
`@SentinelRestTemplate` 注解的限流(`blockHandler`, `blockHandlerClass`)和降级(`fallback`, `fallbackClass`)属性不强制填写。
当使用 `RestTemplate` 调用被 Sentinel 熔断后,会返回 `RestTemplate request block by sentinel` 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 `SentinelClientHttpResponse` 用于构造返回信息。
Sentinel RestTemplate 限流的资源规则提供两种粒度:
* `httpmethod:schema://host:port/path`:协议、主机、端口和路径
* `httpmethod:schema://host:port`:协议、主机和端口
NOTE: 以 `https://www.taobao.com/test` 这个 url 并使用 GET 方法为例。对应的资源名有两种粒度,分别是 `GET:https://www.taobao.com` 以及 `GET:https://www.taobao.com/test`
=== 动态数据源支持
`SentinelProperties` 内部提供了 `TreeMap` 类型的 `datasource` 属性用于配置数据源信息。
比如配置 4 个数据源:
[source,properties]
----
spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
#spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter
#spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel
spring.cloud.sentinel.datasource.ds2.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
spring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOW
spring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181
spring.cloud.sentinel.datasource.ds3.zk.rule-type=authority
spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application
spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinel
spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = test
spring.cloud.sentinel.datasource.ds4.apollo.rule-type=param-flow
----
这种配置方式参考了 Spring Cloud Stream Binder 的配置,内部使用了 `TreeMap` 进行存储comparator 为 `String.CASE_INSENSITIVE_ORDER` 。
NOTE: d1, ds2, ds3, ds4 是 `ReadableDataSource` 的名字,可随意编写。后面的 `file` `zk` `nacos` , `apollo` 就是对应具体的数据源。 它们后面的配置就是这些具体数据源各自的配置。
每种数据源都有两个共同的配置项: `data-type`、 `converter-class` 以及 `rule-type`。
`data-type` 配置项表示 `Converter` 类型Spring Cloud Alibaba Sentinel 默认提供两种内置的值,分别是 `json` 和 `xml` (不填默认是json)。 如果不想使用内置的 `json` 或 `xml` 这两种 `Converter`,可以填写 `custom` 表示自定义 `Converter`,然后再配置 `converter-class` 配置项,该配置项需要写类的全路径名(比如 `spring.cloud.sentinel.datasource.ds1.file.converter-class=org.springframework.cloud.alibaba.cloud.examples.JsonFlowRuleListConverter`)。
`rule-type` 配置表示该数据源中的规则属于哪种类型的规则(`flow``degrade``authority``system`, `param-flow`, `gw-flow`, `gw-api-group`)。
NOTE: 当某个数据源规则信息加载失败的情况下,不会影响应用的启动,会在日志中打印出错误信息。
NOTE: 默认情况下xml 格式是不支持的。需要添加 `jackson-dataformat-xml` 依赖后才会自动生效。
关于 Sentinel 动态数据源的实现原理,参考: https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95[动态规则扩展]
=== Spring Cloud Gateway 支持
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81[参考 Sentinel 网关限流]
若想跟 Sentinel Starter 配合使用,需要加上 `spring-cloud-alibaba-sentinel-gateway` 依赖,同时需要添加 `spring-cloud-starter-gateway` 依赖来让 `spring-cloud-alibaba-sentinel-gateway` 模块里的 Spring Cloud Gateway 自动化配置类生效:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
```
=== Sentinel 对外暴露的 Endpoint
Sentinel 内部提供了一个 Endpoint, 对应的 endpoint id 为 `sentinel`。
Endpoint 暴露的 json 中包含了多种属性:
1. appName: 应用名
2. logDir: 日志所在目录
3. logUsePid: 日志文件名是否带上进程id
4. blockPage: 限流 block 之后跳转的页面
5. metricsFileSize: metrics 文件的大小
6. metricsFileCharset: metrics 文件对应的字符集
7. totalMetricsFileCount: metrics 最多保留的文件数
8. consoleServer: sentinel dashboard 地址
9. clientIp: 客户端 ip
10. heartbeatIntervalMs: 客户端跟 dashboard 的心跳间隔时间
11. clientPort: 客户端需要暴露的端口跟 dashboard 进行交互
12. coldFactor: 冷启动因子
13. filter: CommonFilter 相关的属性, 比如 order, urlPatterns 以及 enable
14. datasource: 客户端配置的数据源信息
15. rules: 客户端生效的规则,内部含有 flowRules, degradeRules, systemRules, authorityRule, paramFlowRule
这是 Endpoint 暴露的 json 示例:
[source,json,indent=0]
----
{
"blockPage": null,
"appName": "sentinel-example",
"consoleServer": "localhost:8080",
"coldFactor": "3",
"rules": {
"flowRules": [{
"resource": "GET:http://www.taobao.com",
"limitApp": "default",
"grade": 1,
"count": 0.0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}, {
"resource": "/test",
"limitApp": "default",
"grade": 1,
"count": 0.0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}, {
"resource": "/hello",
"limitApp": "default",
"grade": 1,
"count": 1.0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}]
},
"metricsFileCharset": "UTF-8",
"filter": {
"order": -2147483648,
"urlPatterns": ["/*"],
"enabled": true
},
"totalMetricsFileCount": 6,
"datasource": {
"ds1": {
"file": {
"dataType": "json",
"ruleType": "FLOW",
"converterClass": null,
"file": "...",
"charset": "utf-8",
"recommendRefreshMs": 3000,
"bufSize": 1048576
},
"nacos": null,
"zk": null,
"apollo": null,
"redis": null
}
},
"clientIp": "30.5.121.91",
"clientPort": "8719",
"logUsePid": false,
"metricsFileSize": 52428800,
"logDir": "...",
"heartbeatIntervalMs": 10000
}
----
=== 关于 Sentinel Starter 更多的配置项信息
下表显示当应用的 `ApplicationContext` 中存在对应的Bean的类型时会进行自动化设置
|===
|存在Bean的类型 |操作 |作用
|`UrlCleaner`|`WebCallbackManager.setUrlCleaner(urlCleaner)`|资源清理(资源(比如将满足 /foo/:id 的 URL 都归到 /foo/* 资源下))
|`UrlBlockHandler`|`WebCallbackManager.setUrlBlockHandler(urlBlockHandler)`|自定义限流处理逻辑
|`RequestOriginParser`|`WebCallbackManager.setRequestOriginParser(requestOriginParser)`|设置来源信息
|===
Spring Cloud Alibaba Sentinel 提供了这些配置选项
|===
|配置项 |含义 |默认值
|`spring.application.name` or `project.name`|Sentinel项目名|
|`spring.cloud.sentinel.enabled`|Sentinel自动化配置是否生效|true
|`spring.cloud.sentinel.eager`|是否提前触发 Sentinel 初始化|false
|`spring.cloud.sentinel.transport.port`|应用与Sentinel控制台交互的端口应用本地会起一个该端口占用的HttpServer|8719
|`spring.cloud.sentinel.transport.dashboard`|Sentinel 控制台地址|
|`spring.cloud.sentinel.transport.heartbeat-interval-ms`|应用与Sentinel控制台的心跳间隔时间|
|`spring.cloud.sentinel.transport.client-ip`|此配置的客户端IP将被注册到 Sentinel Server 端|
|`spring.cloud.sentinel.filter.order`|Servlet Filter的加载顺序。Starter内部会构造这个filter|Integer.MIN_VALUE
|`spring.cloud.sentinel.filter.url-patterns`|数据类型是数组。表示Servlet Filter的url pattern集合|/*
|`spring.cloud.sentinel.filter.enabled`|Enable to instance CommonFilter|true
|`spring.cloud.sentinel.metric.charset`|metric文件字符集|UTF-8
|`spring.cloud.sentinel.metric.file-single-size`|Sentinel metric 单个文件的大小|
|`spring.cloud.sentinel.metric.file-total-count`|Sentinel metric 总文件数量|
|`spring.cloud.sentinel.log.dir`|Sentinel 日志文件所在的目录|
|`spring.cloud.sentinel.log.switch-pid`|Sentinel 日志文件名是否需要带上pid|false
|`spring.cloud.sentinel.servlet.block-page`| 自定义的跳转 URL当请求被限流时会自动跳转至设定好的 URL |
|`spring.cloud.sentinel.flow.cold-factor`| https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---
%E5%86%B7%E5%90%AF%E5%8A%A8[冷启动因子] |3
|`spring.cloud.sentinel.scg.fallback.mode`| Spring Cloud Gateway 熔断后的响应模式(选择 `redirect` or `response`) |
|`spring.cloud.sentinel.scg.fallback.redirect`| Spring Cloud Gateway 响应模式为 'redirect' 模式对应的重定向 URL |
|`spring.cloud.sentinel.scg.fallback.response-body`| Spring Cloud Gateway 响应模式为 'response' 模式对应的响应内容 |
|`spring.cloud.sentinel.scg.fallback.response-status`| Spring Cloud Gateway 响应模式为 'response' 模式对应的响应码 | 429
|`spring.cloud.sentinel.scg.fallback.content-type`| Spring Cloud Gateway 响应模式为 'response' 模式对应的 content-type | application/json
|===
NOTE: 请注意。这些配置只有在 Servlet 环境下才会生效RestTemplate 和 Feign 针对这些配置都无法生效

@ -1,194 +0,0 @@
== Spring Cloud Alibaba Sidecar
`Spring Cloud Alibaba Sidecar` 是一个用来快速**完美整合** Spring Cloud
与 *异构微服务* 的框架,灵感来自
https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-sidecar[Spring
Cloud Netflix Sidecar],目前支持的服务发现组件:
* Nacos
* Consul
=== 术语
==== 异构微服务
非Spring Cloud应用统称异构微服务。比如你的遗留项目或者非JVM应用。
==== "完美整合"的三层含义
* 享受服务发现的优势
* 有负载均衡
* 有断路器
=== Why or Why not?
==== 为什么要编写Alibaba Sidecar
原因有两点:
* Spring Cloud子项目 `Spring Cloud Netflix Sidecar`
是可以快速整合异构微服务的。然而Sidecar只支持使用Eureka作为服务发现*如果使用其他服务发现组件就抓瞎了*。
* *Sidecar是基于Zuul 1.x的*Spring
Cloud官方明确声明未来将会逐步淘汰Zuul。今年早些时候我有给Spring
Cloud官方提出需求希望官方实现一个基于Spring Cloud
Gateway的新一代Sidecar然而官方表示并没有该计划。详见https://github.com/spring-cloud/spring-cloud-gateway/issues/735
既然没有,索性自己写了。
==== 为什么不用Service Mesh
* 目前Mesh主要使用场景在Kubernetes领域Istio、Linkerd
2等大多将Kubernetes作为First
Class支持虽然Istio也可部署在非Kubernetes环境而目前业界Spring
Cloud应用未必有 Service Mesh 的环境;
* 使用Alibaba
Sidecar一个小组件就能解决问题了核心代码不超过200行引入整套Mesh方案颇有点屠龙刀杀黄鳝的意思。
=== 原理
* Alibaba
Sidecar根据配置的异构微服务的IP、端口等信息*将异构微服务的IP/端口注册到服务发现组件上*
* Alibaba Sidecar实现了 *健康检查* Alibaba
Sidecar会定时检测异构微服务是否健康。如果发现异构微服务不健康Alibaba
Sidecar会自动将代表异构微服务的Alibaba
Sidecar实例下线如果异构微服务恢复正常则会自动上线。最长延迟是30秒详见
`Alibaba SidecarChecker#check` 。
=== 要求
* 【必须】你的异构微服务需使用HTTP通信。这一点严格来说不算要求因为Spring
Cloud本身就是基于HTTP的
* 【可选】如果微服务配置了 `sidecar.health-check-url`
,则表示开启健康检查,此时,你的异构微服务需实现健康检查(可以是空实现,只要暴露一个端点,返回类似
`{"status": "UP"}` 的字符串即可)。
=== 使用示例
* 如使用Nacos作为服务发现组件详见`spring-cloud-alibaba-examples/spring-cloud-alibaba-sidecar-examples/spring-cloud-alibaba-sidecar-nacos-example`
* 如使用Consul作为服务发现组件详见`spring-cloud-alibaba-examples/spring-cloud-alibaba-sidecar-examples/spring-cloud-alibaba-sidecar-consul-example`
==== 示例代码以Nacos服务发现为例
* 加依赖:
+
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sidecar</artifactId>
</dependency>
----
* 写配置:
+
[source,yaml]
----
server:
port: 8070
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
enabled: true
application:
name: node-service
sidecar:
# 异构微服务的IP
ip: 127.0.0.1
# 异构微服务的端口
port: 8060
# 异构微服务的健康检查URL
health-check-url: http://localhost:8060/health.json
management:
endpoint:
health:
show-details: always
----
+
配置比较简单就是把Alibaba Sidecar注册到Nacos上然后添加了几行Alibaba
Sidecar的配置。
==== 异构微服务
我准备了一个NodeJS编写的简单微服务。
[source,javascript]
----
var http = require('http');
var url = require("url");
var path = require('path');
// 创建server
var server = http.createServer(function(req, res) {
// 获得请求的路径
var pathname = url.parse(req.url).pathname;
res.writeHead(200, { 'Content-Type' : 'application/json; charset=utf-8' });
// 访问http://localhost:8060/,将会返回{"index":"欢迎来到首页"}
if (pathname === '/') {
res.end(JSON.stringify({ "index" : "欢迎来到首页" }));
}
// 访问http://localhost:8060/health将会返回{"status":"UP"}
else if (pathname === '/health.json') {
res.end(JSON.stringify({ "status" : "UP" }));
}
// 其他情况返回404
else {
res.end("404");
}
});
// 创建监听,并打印日志
server.listen(8060, function() {
console.log('listening on localhost:8060');
});
----
==== 测试
===== 测试1Spring Cloud微服务完美调用异构微服务
为你的Spring Cloud微服务整合Ribbon然后构建 `http://node-service/**`
,就可以请求到异构微服务的 `/**` 了。
示例:
Ribbon请求 `http://node-service/` 会请求到 `http://localhost:8060/`
,以此类推。
至于断路器正常为你的Spring
Cloud微服务整合Sentinel或者Hystirx、Resilience4J即可 。
===== 测试2异构微服务完美调用Spring Cloud微服务
由于Alibaba Sidecar基于Spring Cloud Gateway而网关自带转发能力。
示例:
如果你有一个Spring Cloud微服务叫做 `spring-cloud-microservice`
那么NodeJS应用只需构建
`http://localhost:8070/spring-cloud-microservice/**` Alibaba
Sidecar就会把请求转发到 `spring-cloud-microservice` 的 `/**` 。
而Spring Cloud Gateway是整合了Ribbon的所以实现了负载均衡Spring Cloud
Gateway还可以整合Sentinel或者Hystirx、Resilience4J所以也带有了断路器。
=== Alibaba Sidecar优缺点分析
Alibaba
Sidecar的设计和 Netfix Sidecar 基本一致,优缺点和 Netfix Sidecar 的优缺点也是一样的。
优点:
* 接入简单几行代码就可以将异构微服务整合到Spring Cloud生态
* 不侵入原代码
缺点:
* 每接入一个异构微服务实例都需要额外部署一个Alibaba
Sidecar实例增加了部署成本虽然这个成本在Kubernetes环境中几乎可以忽略不计只需将Alibaba
Sidecar实例和异构微服务作为一个Pod部署即可
* 异构微服务调用Spring Cloud微服务时本质是把Alibaba
Sidecar当网关在使用经过了一层转发性能有一定下降。

@ -1,253 +0,0 @@
== Spring Cloud AliCloud SMS
短信服务Short Message Service是阿里云为用户提供的一种通信服务的能力。 Spring Cloud AliCloud SMS 实现了与 SMS 的简单集成,提供更为简单易用的 API可以基于 Spring Cloud Alibaba SMS 来快速的接入阿里云的 SMS 服务。
=== 如何引入 Spring Cloud AliCloud SMS
如果要在您的项目中引入 SMS使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-sms` 的 starter。
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-sms</artifactId>
</dependency>
----
=== 如何使用 SMS API
==== 配置 SMS
使用 Spring Cloud AliCloud SMS 之前,需要在 application.properties 中加入以下配置。
[source,properties]
----
spring.cloud.alicloud.access-key=你的阿里云 AK
spring.cloud.alicloud.secret-key=你的阿里云 SK
----
access-key 和 secret-key 是阿里云账号的 AK/SK需要首先注册阿里云账号然后登陆 https://usercenter.console.aliyun.com/#/manage/ak[阿里云AK/SK管理页面] ,即可看到 AccessKey ID 和 Access Key Secret ,如果没有的话,需要点击"创建AccessKey"按钮创建。
==== 引入 SMS API
Spring Cloud Alicloud SMS 中的 SMS API 基于阿里云官方 SMS SDK ,提供具备单个短信发送、多个短信批量发送、短信查询、短信消息(`短信回执消息` 和 `上行短信消息`) 类型操作API。
一个简单的使用 SMS API 发送短信的应用如下。
[source,java]
----
@SpringBootApplication
public class SmsApplication {
@Autowired
private ISmsService smsService;
/**
* 短信发送 Example
* @param code
* @return
*/
@RequestMapping("/batch-sms-send.do")
public SendBatchSmsResponse batchsendCheckCode(
@RequestParam(name = "code") String code) {
// 组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
// 必填:待发送手机号
request.setPhoneNumbers("152******");
// 必填:短信签名-可在短信控制台中找到
request.setSignName("******");
// 必填:短信模板-可在短信控制台中找到
request.setTemplateCode("******");
// 可选:模板中的变量替换JSON串,如模板内容为"【企业级分布式应用服务】,您的验证码为${code}"时,此处的值为
request.setTemplateParam("{\"code\":\"" + code + "\"}");
SendSmsResponse sendSmsResponse ;
try {
sendSmsResponse = smsService.sendSmsRequest(request);
}
catch (ClientException e) {
e.printStackTrace();
sendSmsResponse = new SendSmsResponse();
}
return sendSmsResponse ;
}
public static void main(String[] args) throws URISyntaxException {
SpringApplication.run(SmsApplication.class, args);
}
}
----
在发送短信之前,首先需要 https://account.aliyun.com/register/register.htm?spm=5176.8142029.388261.26.e9396d3eaYK2sG&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F[注册阿里云账号] ,如果已经有的话,请 https://dysms.console.aliyun.com/dysms.htm?spm=5176.8195934.1283918..18924183bHPct2&accounttraceid=c8cb4243-3080-4eb1-96b0-1f2316584269#/[开通 SMS 服务]。
更多关于 SMS 发送短信的步骤,可以参考 SMS 官方 https://help.aliyun.com/document_detail/55284.html?spm=a2c4g.11186623.6.568.715e4f30ZiVkbI[短信发送API(SendSms)---JAVA] 文档。
NOTE: 由于早期的 SMS sdk 版本的问题,如果短信发送失败,请将代码中含有明确指定 MethodType 为 POST 的这行代码给删除掉。如果还有问题,请第一时间联系我们。
=== SMS Api 的高级功能
Spring Cloud Alicloud SMS 封装的 API 接口为了降低学习的成本,尽量保持和官网提供的 API 以及 Example 保持一致。
* 批量短信发送
参考以下的 Example ,来快速开发一个具有批量短信发送的功能。在 Controller 中或者新建一个 Controler 新增如下代码:
[source,java]
----
/**
* 批量短信发送 Example
* @param code
* @return
*/
@RequestMapping("/batch-sms-send.do")
public SendBatchSmsResponse batchsendCheckCode(
@RequestParam(name = "code") String code) {
// 组装请求对象
SendBatchSmsRequest request = new SendBatchSmsRequest();
// 使用 GET 提交
request.setMethod(MethodType.GET);
// 必填:待发送手机号。支持JSON格式的批量调用批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
request.setPhoneNumberJson("[\"177********\",\"130********\"]");
// 必填:短信签名-支持不同的号码发送不同的短信签名
request.setSignNameJson("[\"*******\",\"*******\"]");
// 必填:短信模板-可在短信控制台中找到
request.setTemplateCode("******");
// 必填:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
request.setTemplateParamJson(
"[{\"code\":\"" + code + "\"},{\"code\":\"" + code + "\"}]");
SendBatchSmsResponse sendSmsResponse ;
try {
sendSmsResponse = smsService
.sendSmsBatchRequest(request);
return sendSmsResponse;
}
catch (ClientException e) {
e.printStackTrace();
sendSmsResponse = new SendBatchSmsResponse();
}
return sendSmsResponse ;
}
----
NOTE: 这里设置请求的 MethodType 为 GET和官网给出的例子还有些不一样。这是因为依赖的阿里云 POP API 版本不一致导致不兼容的问题,设置为 GET 即可。
更多的参数说明可 https://help.aliyun.com/document_detail/66041.html?spm=a2c4g.11186623.6.571.631315e8AauJhP[参考这里]
* 短信查询
参考以下的 Example ,可以快速开发根据某个指定的号码查询短信历史发送状态。在 Controller 中或者新建一个 Controler 新增如下代码:
[source,java]
----
/**
*
* 短信查询 Example
* @param telephone
* @return
*/
@RequestMapping("/query.do")
public QuerySendDetailsResponse querySendDetailsResponse(
@RequestParam(name = "tel") String telephone) {
// 组装请求对象
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
// 必填-号码
request.setPhoneNumber(telephone);
// 必填-短信发送的日期 支持30天内记录查询可查其中一天的发送数据格式yyyyMMdd
request.setSendDate("20190103");
// 必填-页大小
request.setPageSize(10L);
// 必填-当前页码从1开始计数
request.setCurrentPage(1L);
try {
QuerySendDetailsResponse response = smsService.querySendDetails(request);
return response;
}
catch (ClientException e) {
e.printStackTrace();
}
return new QuerySendDetailsResponse();
}
----
更多的参数说明,可 https://help.aliyun.com/document_detail/55289.html?spm=a2c4g.11186623.6.569.4f852c78mugEfx[参考这里]
* 短信回执消息
通过订阅 SmsReport 短信状态报告,可以获知每条短信的发送情况,了解短信是否达到终端用户的状态与相关信息。这些工作已经都被 Spring Cloud AliCloud SMS 封装在内部了。你只需要完成以下两步即可。
1、在 `application.properties` 配置文件中(也可以是 application.yaml)配置 SmsReport 的队列名称。
.application.properties
[source,properties]
----
spring.cloud.alicloud.sms.report-queue-name=Alicom-Queue-********-SmsReport
----
2、 实现 SmsReportMessageListener 接口,并初始化一个 Spring Bean 。
[source,java]
----
/**
* 如果需要监听短信是否被对方成功接收,只需实现这个接口并初始化一个 Spring Bean 即可。
*/
@Component
public class SmsReportMessageListener
implements org.springframework.cloud.alicloud.sms.SmsReportMessageListener {
@Override
public boolean dealMessage(Message message) {
// 在这里添加你的处理逻辑
//do something
System.err.println(this.getClass().getName() + "; " + message.toString());
return true;
}
}
----
更多关于 Message 的消息体格式可 https://help.aliyun.com/document_detail/55496.html?spm=a2c4g.11186623.6.570.7f792c78rOiWXO[参考这里]。
* 上行短信消息
通过订阅SmsUp上行短信消息可以获知终端用户回复短信的内容。这些工作也已经被 Spring Cloud AliCloud SMS 封装好了。你只需要完成以下两步即可。
1、 在 `application.properties` 配置文件中(也可以是 application.yaml)配置 SmsReport 的队列名称。
.application.properties
----
spring.cloud.alicloud.sms.up-queue-name=Alicom-Queue-********-SmsUp
----
2、实现 SmsUpMessageListener 接口,并初始化一个 Spring Bean 。
[source,java]
----
/**
* 如果发送的短信需要接收对方回复的状态消息,只需实现该接口并初始化一个 Spring Bean 即可。
*/
@Component
public class SmsUpMessageListener
implements org.springframework.cloud.alicloud.sms.SmsUpMessageListener {
@Override
public boolean dealMessage(Message message) {
// 在这里添加你的处理逻辑
//do something
System.err.println(this.getClass().getName() + "; " + message.toString());
return true;
}
}
----
更多关于 Message 的消息体格式可 https://help.aliyun.com/document_detail/55496.html?spm=a2c4g.11186623.6.570.7f792c78rOiWXO[参考这里]。

@ -1,36 +0,0 @@
[[spring-cloud-alibaba-reference]]
= Spring Cloud Alibaba 参考文档
Jim Fang, Jing Xiao, Mercy Ma, Xiaolong Zuo, Bingting Peng, Yuxin Wang
:doctype: book
:toc:
:toclevels: 4
:source-highlighter: prettify
:numbered:
include::introduction.adoc[]
include::dependency-management.adoc[]
include::nacos-discovery.adoc[]
include::nacos-config.adoc[]
include::sentinel.adoc[]
include::rocketmq-new.adoc[]
include::ans.adoc[]
include::acm.adoc[]
include::oss.adoc[]
include::schedulerx.adoc[]
include::sms.adoc[]
include::sidecar.adoc[]
include::graalvm.adoc[]

@ -1,178 +0,0 @@
== Spring Cloud Alibaba Cloud ACM
Spring Cloud AliCloud ACM is an implementation of the commercial product Application Configuration Management(ACM) in the client side of Spring Cloud, and is free of charge.
Use Spring Cloud AliCloud ACM to quickly access ACM configuration management capabilities based on Spring Cloud's programming model.
NOTE: Currently EDAS already supports direct deployment of the Nacos Config app.
=== How to Introduce Spring Cloud Alibaba Cloud ACM
If you want to use ACM in your project, please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alicloud-acm`.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-acm</artifactId>
</dependency>
----
=== Use ACM to Manage Configurations
When Spring Cloud Alibaba Cloud ACM Starter is introduced into the client, the application will automatically get configuration information from the configuration management server when it starts, and inject the configuration into Spring Environment.
The following is a simple illustration.
[source,java]
----
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" +userName+"; age: "+userAge);
}
}
----
As we need to obtain configuration information from the configuration server, we will need to configure the address of the server. We also need to add the following information in bootstrap.properties.
[source,properties]
----
# Required. The application name will be used as part of the keyword to get the configuration key from the server.
spring.application.name=acm-config
server.port=18081
# The following is the IP and port number of the configuration server.
spring.cloud.alicloud.acm.server-list=127.0.0.1
spring.cloud.alicloud.acm.server-port=8080
----
NOTE: By now the configuration center is not started yet, so you will get an error message if your application is started. Therefore, start the configuration center before you start your application.
==== Start Configuration Center
ACM uses two types of configuration centers. One is lightweight configuration center, the other is ACM which is used on Alibaba Cloud. Generally, you can use the lightweight version for application development and local testing, and use ACM for canary deployment or production.
===== Use Lightweight Configuration Center
Refer to the https://help.aliyun.com/document_detail/44163.html[Configure Lightweight Configuration Center] for details about how to download and install lightweight configuration center.
NOTE: You only need to perform step 1(Download lightweight configuration center) and step 2(Start lightweight configuration center).
===== Use ACM on the Alibaba Cloud
Using ACM on the cloud saves you from the tedious work of server maintenance while at the same time provides a better stability. There is no difference at the code level between using ACM on cloud and lightweight configuration center, but there are some differences in configurations.
The following is a simple sample of using ACM. You can view configuration details on https://acm.console.aliyun.com[ACM Console]
[source,properties]
----
# The application name will be used as part of the keyword to obtain configuration key from the server, and is mandatory.
spring.application.name=acm-config
# Configure your own port number
server.port=18081
# The following is the IP and port number of the configuration center.
spring.cloud.alicloud.acm.server-mode=EDAS
spring.cloud.alicloud.access-key=Your Alibaba Cloud AK
spring.cloud.alicloud.secret-key=Your Alibaba Cloud SK
spring.cloud.alicloud.acm.endpoint=acm.aliyun.com
spring.cloud.alicloud.acm.namespace=Your ACM namespace(You can find the namespace on the ACM console)
----
NOTE: EDAS provides application hosting service and will fill in all configurations about ACM automatically for the hosted applications.
==== Add Configuration in the Configuration Center
1. After you start the lightweight configuration center, add the following configuration on the console.
[source,subs="normal"]
----
Group: DEFAULT_GROOUP
DataId: acm-config.properties
Content: user.name=james
user.age=18
----
NOTE: The format of dataId is `{prefix}. {file-extension}`. “prefix” is obtained from spring.application.name by default, and the value of “file-extension” is "properties” by default.
==== Start Application Verification
Start the following example and you can see that the value printed on the console is the value we configured in the lightweight configuration center.
[source,subs="normal"]
----
user name :james; age: 18
----
=== Modify Configuration File Extension
The default file extension of dataId in spring-cloud-starter-alicloud-acm is properties. In addition to properties, yaml is also supported.
You can set the file extension using spring.cloud.alicloud.acm.file-extension. Just set it to `yaml` or `yml`for yaml format.
NOTE: After you change the file extension, you need to make corresponding format changes in the DataID and content of the configuration center.
=== Dynamic Configuration Refresh
spring-cloud-starter-alicloud-acm supports dynamic configuration updates. RefreshEvent in Spring is published when you update configuration in the configuration center.
All classes with @RefreshScope and @ConfigurationProperties annotations will be refreshed automatically.
NOTE: You can disable automatic refresh by this setting: spring.cloud.alicloud.acm.refresh.enabled=false
=== Configure Profile Granularity
When configuration is loaded by spring-cloud-starter-alicloud-acm, configuration with DataId {spring.application.name}. {file-extension} will be loaded first. If there is content in spring.profiles.active, the content of spring.profile, and configuration with the dataid format of{spring.application.name}-{profile}. {file-extension} will also be loaded in turn, and the latter has higher priority.
spring.profiles.active is the configuration metadata, and should also be configured in bootstrap.properties or bootstrap.yaml. For example, you can add the following content in bootstrap.properties.
[sources,properties]
----
spring.profiles.active={profile-name}
----
Note: You can also configure the granularity through JVM parameters such as -Dspring.profiles.active=develop or --spring.profiles.active=develop, which have higher priority. Just follow the specifications of Spring Boot.
=== Support Custom ACM Timeout
the default timeout of ACM client get config from sever is 3000 ms . If you need to define a timeout, set configuration `spring.cloud.alicloud.acm.timeout`,the unit is millisecond.
=== Support Custom Group Configurations
DEFAULT_GROUP is used by default when no `{spring.cloud.alicloud.acm.group}` configuration is defined. If you need to define your own group, you can use the following method:
[source,properties]
----
spring.cloud.alicloud.acm.group=DEVELOP_GROUP
----
NOTE: This configuration must be placed in the bootstrap.properties file, and the value of Group must be the same with the value of `spring.cloud.alicloud.acm.group`.
==== Support Shared Configurations
ACM provides a solution to share the same configuration across multiple applications. You can do this by adding the `spring.application.group` configuration in Bootstrap.
[source,properties]
----
spring.application.group=company.department.team
----
Then, you application will retrieve configurations from the following DataId in turn before it retrieves its own configuration: company:application.properties, company.department:application.properties, company.department.team:application.properties.
After that, it also retrieves configuration from {spring.application.group}: {spring.application.name}. {file-extension}
The later in order, the higer the priority, and the unique configuration of the application itself has the highest priority.
NOTE: The default suffix of DataId is properties, and you can change it using spring.cloud.alicloud.acm.file-extension. `{spring.application.group}: {spring.application.name}. {file-extension}` .
NOTE: If you configured `spring.profiles.active` , then the DataId format of `{spring.application.group}: {spring.application.name}-{spring.profiles.active}. {file-extension}` is also supported, and has higher priority than `{spring.application.group}: {spring.application.name}. {file-extension}`
=== Actuator Endpoint
the Actuator endpoint of ACM is `/acm`, `config` represents the ACM metadata configuration information, `runtime.sources` corresponds to the configuration information obtained from the ACM server and the last refresh time, `runtime.refreshHistory` corresponds to the dynamic refresh history.

@ -1,96 +0,0 @@
== Spring Cloud Alibaba Cloud ANS
ANS(Application Naming Service) is a component of EDAS. Spring Cloud Alibaba Cloud ANS provides the commercial version of service registration and discovery in conformity with the Spring Cloud specifications, so that you can develop your applications locally and run them on the cloud.
NOTE: EDAS currently supports direct deployment of Nacos Discovery applications
=== How to Introduce Spring Cloud Alibaba Cloud ANS
If you want to use ANS in your project, please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alicloud-ans`.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-ans</artifactId>
</dependency>
----
=== Use ANS to Register Service
When Spring Cloud AliCloud ANS Starter is introduced on the client, the metadata of the service such as IP, port number and weight will be registered to the registration center automatically. The client will maintain heartbeat with the server to prove that it is capable of providing service properly.
The following is a simple illustration.
[source,java]
----
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ProviderApplication {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
----
As the service will registered to the registration center, we will need to configure the address of the registration center. We also need to add the following address in application.properties.
[source,properties]
----
# The application name will be used as the service name, therefore it is mandatory.
spring.application.name=ans-provider
server.port=18081
# The following is the IP and port number of the registration center.
spring.cloud.alicloud.ans.server-list=127.0.0.1
spring.cloud.alicloud.ans.server-port=8080
----
NOTE: By now the registration center is not started yet, so you will get an error message if your application is started. Therefore, start the registration center before you start your application.
=== Start Registration Center
ANS uses two types of registration centers. One is the free lightweight configuration center and the other is the registration center on cloud, which is provided through EDAS. Generally, you can use the lightweight version for application development and local testing, and use EDAS for canary deployment or production.
==== Start Lightweight Configuration Center
Refer to the https://help.aliyun.com/document_detail/44163.html[Configure Lightweight Configuration Center] for details about how to download and install lightweight configuration center.
NOTE: You only need to perform step 1(Download lightweight configuration center) and step 2(Start lightweight configuration center). Step 3(Configure hosts) is not required if you use ANS at the same time.
After you start the lightweight configuration center, start ProviderApplication directly, and you will be able to register your service to the configuration center. The default port of the lightweight configuration center is 8080, therefore you can open http://127.0.0.1:8080, click “Services” on the left and see the registered service.
==== User Registration Center on the Cloud
Using the registration center on the cloud saves you from the tedious work of server maintenance while at the same time provides a better stability. There is no difference at the code level between using the registration center on cloud and lightweight configuration center, but there are some differences in configurations.
The following is a simple sample of using the registration center on the cloud.
[source,properties]
----
# The application name will be used the service name, and is therefore mandatory.
spring.application.name=ans-provider
# Configure your own port number
server.port=18081
# The following is the IP and port number of the configuration center. The default value is 127.0.0.1 and 8080, so the following lines can be omitted.
spring.cloud.alicloud.ans.server-mode=EDAS
spring.cloud.alicloud.access-key=Your Alibaba Cloud AK
spring.cloud.alicloud.secret-key=Your Alibaba Cloud SK
spring.cloud.alicloud.edas.namespace=cn-xxxxx
----
The default value of server-mode is LOCAL. If you want to use the registration center on cloud, you need to change it to EDAS.
Access-key and secret-key are the AK/SK of your Alibaba Cloud account. Register an Alibaba Cloud account first and log on to the Cloud Console https://usercenter.console.aliyun.com/#/manage/ak[Alibaba Cloud AK/SK] to copy your AccessKey ID and Access Key Secret. If you havent created one, click the “Create AccessKey” button.
Namespace is a concept in EDAS, which is used to isolate environments, such as testing environment and production environment. To find your namespace, click to https://common-buy.aliyun.com/?spm=5176.11451019.0.0.6f5965c0Uq5tue&commodityCode=edaspostpay#/buy[Sign up for EDAS] first. You will not be charged under the pay-as-you-go mode. Then log on to the https://edas.console.aliyun.com/#/namespaces?regionNo=cn-hangzhou[EDAS Console] and you will be able to see your namespace, for example cn-hangzhou.
NOTE: EDAS provides application hosting service and will fill in all configurations automatically for the hosted applications.

@ -1,73 +0,0 @@
=== Circuit Breaker: Spring Cloud Circuit Breaker With Sentinel & Configuring Sentinel Circuit Breakers
==== Default Configuration
To provide a default configuration for all of your circuit breakers create a `Customizer` bean that is passed a
`SentinelCircuitBreakerFactory` or `ReactiveSentinelCircuitBreakerFactory`.
The `configureDefault` method can be used to provide a default configuration.
====
[source,java]
----
@Bean
public Customizer<SentinelCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new SentinelConfigBuilder(id)
.build());
}
----
====
You can choose to provide default circuit breaking rules via `SentinelConfigBuilder#rules(rules)`.
You can also choose to load circuit breaking rules later elsewhere using
`DegradeRuleManager.loadRules(rules)` API of Sentinel, or via Sentinel dashboard.
===== Reactive Example
====
[source,java]
----
@Bean
public Customizer<ReactiveSentinelCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new SentinelConfigBuilder(id)
.build());
}
----
====
==== Specific Circuit Breaker Configuration
Similarly to providing a default configuration, you can create a `Customizer` bean this is passed a
`SentinelCircuitBreakerFactory`.
====
[source,java]
----
@Bean
public Customizer<SentinelCircuitBreakerFactory> slowCustomizer() {
String slowId = "slow";
List<DegradeRule> rules = Collections.singletonList(
new DegradeRule(slowId).setGrade(RuleConstant.DEGRADE_GRADE_RT)
.setCount(100)
.setTimeWindow(10)
);
return factory -> factory.configure(builder -> builder.rules(rules), slowId);
}
----
====
===== Reactive Example
====
[source,java]
----
@Bean
public Customizer<ReactiveSentinelCircuitBreakerFactory> customizer() {
List<DegradeRule> rules = Collections.singletonList(
new DegradeRule().setGrade(RuleConstant.DEGRADE_GRADE_RT)
.setCount(100)
.setTimeWindow(10)
);
return factory -> factory.configure(builder -> builder.rules(rules), "foo", "bar");
}
----
====

@ -1,19 +0,0 @@
== Dependency Management
If youre a Maven Central user, add our BOM to your pom.xml <dependencyManagement> section. This will allow you to omit versions for any of the Maven dependencies and instead delegate versioning to the BOM.
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
In the following sections, it will be assumed you are using the Spring Cloud Alibaba BOM and the dependency snippets will not contain versions.

@ -1,138 +0,0 @@
== AOT and Native Image Support
=== Introduction to GraalVM
One of the biggest changes of Spring Boot 3.0 is the support for GraalVM native images, which the official takes a lot of time and effort. GraalVM, as an alternative to JRE, precompels java applications through technologies such as Ahead Of Time (AOT), which enables Spring to grasp more information about applications when running applications and makes the whole application start faster. In addition, the final application is smaller and has a lower memory footprint by eliminating unnecessary content during the compilation process through the compilation tool. It is excellent for some scenarios that require very high startup speed, such as Serverless and FaaS scenarios. This Spring Boot 3.0 directly moves it from Spring Native to Spring Boot, which also indicates that this technology begins to mature gradually and Spring ecology begins to enter the GraalVM stage!
*GraalVM has the following features compared to the JVM compilation deployment:*
* During the application construction phase, static analysis of the application begins at the main entry point.
* When the native image is created, code analysis removes the inaccessible code and does not become part of the executable file, thus reducing the package size to some extent.
* GraalVM cannot directly sense the dynamic elements of the code. Therefore, for applications with reflection, serialization, and dynamic proxies, hint configuration files need to be provided in advance to help resolve the application. Refer to the official documents for related operations.
* The application classpath is fixed at build time and cannot be changed.
* Without lazy class loading, everything in the executable will be loaded into memory at startup.
* The supported Java applications have some limitations in some aspects. Therefore, it is not guaranteed that all the previous Java applications can directly use GraalVM technology for application construction, and there is a certain probability of incompatible exceptions.
Part of the middleware clients included in Spring Cloud Alibaba 2022.0.0.0 version of this release have completed the adaptation of constructing GraalVM native applications. The following is a sample application related to service registration, discovery module supported by the community. After upgrading to Spring Boot 3.0, GraalVM is used to build a native application image to test the startup speed and runtime usage. The following test process is simulated for 3 times respectively under the environment of MacOS 11.4, 2.6GHz 6-Core Intel Core i7 processor and 16G memory) :
image::https://sca-storage.oss-cn-hangzhou.aliyuncs.com/website/docs/en/graalvm-performance_en.jpg[]
From the above comparison, we can see that the latest Spring Cloud Alibaba application that supports Spring Boot 3.0 based on GraalVM will reduce application's startup time, runtime memory usage and application package size. For example, Among them, the startup speed of the service registration consumption application is increased by nearly 10 times, and the running memory usage is reduced by nearly 2/3 compared with the original, which has a very obvious effect. This gives the cloud native era, hosting in the cloud application has brought significant advantages, so that it can be faster elastic expansion and contraction capacity and reduce the overall cost of the enterprise cloud!
=== Build Application by GraalVM
==== Build the project
Among all the components supported by Spring Cloud Alibaba for Spring Boot 3.0 this time, Nacos 2.1.1 already supports GraalVM technology to build applications. Next, we'll look at the components that use GraalVM to compile and run the application
The project construction can be carried out according to the general Spring Cloud Alibaba application construction method. The following are the relevant dependencies that must be added:
```xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
The above are necessary dependencies for registering Nacos through Spring Cloud Alibaba. Please adjust other dependencies according to your own needs. Please note that It is critical to use the GraalVM `spring-boot-starter-parent` parent module, which declares a native profile that contains the necessary information to create and run GraalVM native images. There are two ways to build a Spring Boot native image application:
1. Use Spring Boot's support for Cloud Native Buildpacks to generate lightweight containers containing native executables.
2. Use GraalVM Native Build Tools to generate a local executable file. As the first method has certain requirements on the local environment, If you need to use can refer to https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.introducing-graalvm-native[Spring Boot 3.0] related user documents. The rest of this article demonstrates the second approach to GraalVM application building.
==== Preparation
To Build a Native image using Native Build Tools, you need to firstly install the GraalVM distribution on your machine. You can download it manually on the Liberica Native Image Kit page, or you can use tools like SDKMAN!. Run the following command to install the GraalVM environment:
[source,shell]
----
sdk install java 22.3.r17-nik
sdk use java 22.3.r17-nik
----
Verify that the correct version is configured by checking the output of java -version:
[source,shell]
----
$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)
----
==== Generate hint file
Generate hint configuration files required for reflection, serialization, and dynamic proxies in your application by using the following command.
[source,shell]
----
mvn -Pnative spring-boot:run
----
After our example application is launched, we need to test all functions of example as completely as possible to ensure that most code of the application is covered by test cases, so as to ensure that all necessary dynamic properties during the application operation are generated completely.
After running all the test cases, we found the following hint files are generated in ``resource/META-INF/native image`` directory:
- resource-config.jsonResource hint file
- reflect-config.jsonReflection definition hint file
- serialization-config.jsonSerialization hint file
- proxy-config.jsonProxy hint file
- jni-config.jsonJNI hint file
Note: During the generation of the hint file by the RocketMQ application through the above command, incomplete scanning of configuration information may occur, please refer to https://github.com/alibaba/spring-cloud-alibaba/issues/3101[related issues], During the generation of the hint file by the above command, the Sentinel application may encounter the following problems, please refer to https://github.com/alibaba/Sentinel/issues/3012[related issues].
==== Build native image
After all the above steps are in place, use the following command to build the native image:
```shell
mvn -Pnative native:compile
```
After that, we can see the executable we generated in the ``/target`` directory.
==== Run native image
Like a normal executable file, launch this example with ``target/nacos-config-example``,
You can observe output similar to the following:
```shell
2022-12-22T16:28:51.006+08:00 INFO 75439 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''
2022-12-22T16:28:51.008+08:00 INFO 75439 --- [ main] c.a.cloud.imports.examples.Application : Started Application in 0.653 seconds (process running for 0.662)
```
You can see that the application starts up much faster.
We can see the memory usage through ` vmmap pid | grep Physical ` command
The memory usage of applications started using native image is as follows
```
Physical footprint: 59.2M
Physical footprint (peak): 59.2M
```
The memory usage of starting normal Java applications is as follows
```
Physical footprint: 214.0M
Physical footprint (peak): 256.8M
```
As you can see, the memory usage is greatly reduced when the Java application is launched using the native image.
After the application is started, its abilities are the same as if it were started through a jar.

@ -1,19 +0,0 @@
== Introduction
Spring Cloud Alibaba aims to provide a one-stop solution for microservices development. This project includes the required components for developing distributed applications and services, so that developers can develop distributed applications easily with the Spring Cloud programming models.
With Spring Cloud Alibaba, you only need to add a few annotations and configurations, and you will be able to use the distributed solutions of Alibaba for your applications, and build a distributed system of your own with Alibaba middleware.
The features of Spring Cloud Alibaba:
1. **Flow control and service degradation**support WebServlet, WebFlux, OpenFeign, RestTemplate, Dubbo access to the function of limiting and degrading flow. It can modify the rules of limiting and degrading flow in real time through the console at run time, and it also supports the monitoring of limiting and degrading Metrics.
2. **Service registration and discovery**Service can be registered and clients can discover the instances using Spring-managed beans, auto integration Ribbon.
3. **Distributed configuration**support for externalized configuration in a distributed system, auto refresh when configuration changes.
4. **Rpc Service**extend Spring Cloud client RestTemplate and OpenFeign to support calling Dubbo RPC services.
5. **Event-driven**support for building highly scalable event-driven microservices connected with shared messaging systems.
6. **Distributed Transaction**support for distributed transaction solution with high performance and ease of use.
7. **Alibaba Cloud Object Storage**massive, secure, low-cost, and highly reliable cloud storage services. Support for storing and accessing any type of data in any application, anytime, anywhere.
8. **Alibaba Cloud SchedulerX**accurate, highly reliable, and highly available scheduled job scheduling services with response time within seconds.
9. **Alibaba Cloud SMS** A messaging service that covers the globe, Alibaba SMS provides convenient, efficient, and intelligent communication capabilities that help businesses quickly contact their customers.
Spring Cloud Alibaba also provide rich https://github.com/alibaba/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples[examples].

@ -1,452 +0,0 @@
== Spring Cloud Alibaba Nacos Config
Nacos is an easy-to-use dynamic service discovery, configuration and service management platform for building cloud native applications.
Use Spring Cloud Alibaba Nacos Config to quickly access Nacos configuration management capabilities based on Spring Cloud's programming model.
=== How to Introduce Nacos Config for configuration
please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alibaba-nacos-config`.
[source,xml,indent=0]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
----
=== Quickstart
Nacos Config uses DataId and GROUP to determine a configuration.
The following figure shows that the DataId uses `myDataid`, GROUP uses `DEFAULT_GROUP`, and configures a configuration item of the format Properties:
.Nacos Config Item
image::https://img.alicdn.com/tfs/TB1N2nxbRr0gK0jSZFnXXbRRXXa-2448-1194.png[]
==== Initialize Nacos Server
For specific startup methods, refer to the "Nacos Server Startup" section of the Spring Cloud Alibaba Nacos Discovery section.
After the Nacos Server is started, add how to configure it:
[source,subs="normal"]
----
Data ID: nacos-config.properties
Group : DEFAULT_GROUP
Configuration format: Properties
Configuration content:
user.name=jack
user.age=90
----
NOTE: The default file extension of DataId is properties.
===== Usage on the Client
If you want to use Nacos to manage externalized configurations for your applications, please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alibaba-nacos-config`.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
----
Now we can create a standard Spring Boot application.
[source,java]
----
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" +userName+"; age: "+userAge);
}
}
----
NOTE: After ``spring-cloud-alibaba`` ``2021.0.1.0``,we use ``spring.config.import`` import configuration by default,
if you want to continue to use ``bootstrap``,you can add the following dependencies to the project root ``pom.xml`` file:
[source,xml]
----
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>4.0.0</version>
</dependency>
----
Before running this example, we need to configure the address of the Nacos server in `application.yaml`. For example:
.`application.yaml`
[source,yaml]
----
# GROUP is not configured to use DEFAULT_GROUP by default.
spring:
application:
name: nacos-config
cloud:
nacos:
config:
serverAddr: 127.0.0.1:8848
config:
import:
- nacos:nacos-config.properties
----
NOTE: If you use domain name to access Nacos, the format of `spring.cloud.nacos.config.server-addr` should be `Domain name:port`.
For example, if the Nacos domain name is abc.com.nacos, and the listerner port is 80, then the configuration should be `spring.cloud.nacos.config.server-addr=abc.com.nacos:80`.
Port 80 cannot be omitted.
Run this example and you can see the following output:
[source,subs="normal"]
----
2018-11-02 14:24:51.638 INFO 32700 --- [main] c.a.demo.provider.NacosConfigApplication : Started NacosConfigApplication in 14.645 seconds (JVM running for 15.139)
user name :jack; age: 90
----
=== Add Configurations with DataId in YAML Format
Nacos Config supports yaml format as well. You only need to complete the following 2 steps.
1、In the application.yaml file, add the following line to claim that the format of DataId is yaml. As follows:
.application.yaml
[source,yaml]
----
spring:
application:
name: nacos-config
cloud:
nacos:
config:
serverAddr: 127.0.0.1:8848
config:
import:
- nacos:nacos-config.yaml
----
2、Add a configuration with the DataId in yaml format on the Nacos console, as shown below:
[source,subs="normal"]
----
Data ID: nacos-config.yaml
Group : DEFAULT_GROUP
Configuration format: YAML
Configuration content:
user:
name: rose
age: 68
----
After completing the preivous two steps, restart the testing program and you will see the following result.
[source,subs="normal"]
----
user name :rose; age: 68
----
=== Support Dynamic Configuration Updates
Nacos Config also supports dynamic configuration updates. The code for starting Spring Boot application testing is as follows:
[source,java]
----
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
while(true) {
//When configurations are refreshed dynamically, they will be updated in the Enviroment, therefore here we retrieve configurations from Environment every other second.
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(1);
}
}
}
----
When user.name is changed, the latest value can be retrieved from the application, as shown below:
[source,subs="normal"]
----
user name :nacos-config-yaml; age: 68
user name :nacos-config-yaml; age: 68
user name :nacos-config-yaml; age: 68
2018-11-02 15:04:25.069 INFO 32957 --- [-127.0.0.1:8848] o.s.boot.SpringApplication : Started application in 0.144 seconds (JVM running for 71.752)
2018-11-02 15:04:25.070 INFO 32957 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@10c89124: startup date [Fri Nov 02 15:04:25 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@6520af7
2018-11-02 15:04:25.071 INFO 32957 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6520af7: startup date [Fri Nov 02 15:04:24 CST 2018]; root of context hierarchy
//Read the updated value from Enviroment
user name :nacos-config-yaml-update; age: 68
user name :nacos-config-yaml-update; age: 68
----
NOTE: You can disable automatic refresh with this setting`spring.cloud.nacos.config.refresh.enabled=false`.
=== Support configurations at the profile level
When configurations are loaded by Nacos Config, basic configurations with DataId of `${spring.application.name}. ${file-extension:properties}` , and DataId of `${spring.application.name}-${profile}. ${file-extension:properties}` are also loaded. If you need to use different configurations from different environments, you can use the `${spring.profiles.active}` configuration provided by Spring.
[source,properties]
----
spring.profiles.active=develop
----
NOTE: When specified in configuration files, ${spring.profiles.active} must be placed in bootstrap.properties.
Add a basic configuration in Nacos, with a DataId of nacos-config-develop.yaml, as shown below:
[source,subs="normal"]
----
Data ID: nacos-config-develop.yaml
Group : DEFAULT_GROUP
Configuration format: YAML
Configuration content: current.env: develop-env
----
Run the following Spring Boot application testing code:
[source,java]
----
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
while(true) {
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
//Get the current deployment environment
String currentEnv = applicationContext.getEnvironment().getProperty("current.env");
System.err.println("in "+currentEnv+" enviroment; "+"user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(1);
}
}
}
----
After started, you can see the output as follows in the console:
[source,subs="normal"]
----
in develop-env enviroment; user name :nacos-config-yaml-update; age: 68
2018-11-02 15:34:25.013 INFO 33014 --- [ Thread-11] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6f1c29b7: startup date [Fri Nov 02 15:33:57 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@63355449
----
To switch to the production environment, you only need to change the parameter of `${spring.profiles.active}`. As show below:
[source,properties]
----
spring.profiles.active=product
----
At the same time, add the basic configuration with the DataId in the Nacos of your production environment. For example, you can add the configuration with the DataId of nacos-config-product.yaml in Nacos of your production environment:
[source,subs="normal"]
----
Data ID: nacos-config-product.yaml
Group : DEFAULT_GROUP
Configuration format: YAML
Configuration content: current.env: product-env
----
Start the testing program and you will see the following result:
[source,subs="normal"]
----
in product-env enviroment; user name :nacos-config-yaml-update; age: 68
2018-11-02 15:42:14.628 INFO 33024 --- [Thread-11] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6aa8e115: startup date [Fri Nov 02 15:42:03 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@19bb07ed
----
NOTE: In this example, we coded the configuration in the configuration file by using the `spring.profiles.active=<profilename>` method. In real scenarios, this variable needs to be different in different environment. You can use the `-Dspring.profiles.active=<profile>` parameter to specify the configuration so that you can switch between different environments easily.
=== Support Custom Namespaces
For details about namespaces in Nacos, refer to https://nacos.io/zh-cn/docs/concepts.html[Nacos Concepts]
[quote]
Namespaces are used to isolate configurations for different tenants. Groups and Data IDs can be the same across different namespaces. Typical scenarios of namespaces is the isolation of configurations for different environments, for example, isolation between development/testing environments and production environments(configurations and services and so on).
The “Public” namespace of Nacos is used if no namespace is specified in `${spring.cloud.nacos.config.namespace}`. You can also specify a custom namespace in the following way
[source,properties]
----
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
----
NOTE: This configuration must be in the bootstrap.properties file. The value of `spring.cloud.nacos.config.namespace` is the id of the namespace, and the value of id can be retrieved from the Nacos console. Do not select other namespaces when adding configurations. Otherwise configurations cannot be retrieved properly.
=== Support Custom Groups
DEFAULT_GROUP is used by default when no `{spring.cloud.nacos.config.group}` configuration is defined. If you need to define your own group, you can define it in the following property:
[source,properties]
----
spring.cloud.nacos.config.group=DEVELOP_GROUP
----
NOTE: This configuration must be in the bootstrap.properties file, and the value of Group must be the same with the value of `spring.cloud.nacos.config.group`.
=== Support Custom Data Id
As of Spring Cloud Alibaba Nacos Config, data id can be self-defined. For detailed design of this part, refer to https://github.com/alibaba/spring-cloud-alibaba/issues/141[Github issue].
The following is a complete sample:
[source,properties]
----
spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1. Data Id is in the default group of DEFAULT_GROUP, and dynamic refresh of configurations is not supported.
spring.cloud.nacos.config.ext-config[0].data-id=ext-config-common01.properties
# 2. Data Id is not in the default group, and dynamic refresh of configurations is not supported.
spring.cloud.nacos.config.ext-config[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.ext-config[1].group=GLOBALE_GROUP
# 3. Data Id is not in the default group and dynamic referesh of configurations is supported.
spring.cloud.nacos.config.ext-config[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.ext-config[2].group=REFRESH_GROUP
spring.cloud.nacos.config.ext-config[2].refresh=true
----
We can see that:
* Support multiple data ids by configuring `spring.cloud.nacos.config.ext-config[n].data-id`.
* Customize the group of data id by configuring `spring.cloud.nacos.config.ext-config[n].group`. If not specified, DEFAULT_GROUP is used.
* Control whether this data id supports dynamic refresh of configurations is supported when configurations are changed by configuring `spring.cloud.nacos.config.ext-config[n].refresh`.
Its not supported by default.
NOTE: When multiple Data Ids are configured at the same time, the priority is defined by the value of “n” in `spring.cloud.nacos.config.ext-config[n].data-id`. The bigger the value, the higher the priority.
NOTE: The value of `spring.cloud.nacos.config.ext-config[n].data-id` must have a file extension, and it could be properties or yaml/yml.
The setting in `spring.cloud.nacos.config.file-extension` does not have any impact on the custom Data Id file extension.
The configuration of custom Data Id allows the sharing of configurations among multiple applications, and also enables support of multiple configurations for one application.
To share the data id among multiple applications in a clearer manner, you can also use the following method:
[source,properties]
----
spring.cloud.nacos.config.shared-dataids=bootstrap-common.properties,all-common.properties
spring.cloud.nacos.config.refreshable-dataids=bootstrap-common.properties
----
We can see that:
* Multiple shared data ids can be configured using `spring.cloud.nacos.config.shared-dataids` , and the data ids are separted by commas.
* `spring.cloud.nacos.config.refreshable-dataids` is used to control which data ids will be refreshed dynamically when configurations are updated, and that the latest configuration values can be retrieved by applications. Data ids are separated with commas.
If not specified, all shared data ids will not be dynamically refreshed.
NOTE: When using `spring.cloud.nacos.config.shared-dataids` to configure multiple shared data ids,
we agree on the following priority between the shared configurations: Priorities are decided based on the order in which the configurations appear. The one that occurs later is higher in priority than the one that appears first.
NOTE: When using `spring.cloud.nacos.config.shared-dataids`, the data Id must have a file extension, and it could be properties or yaml/yml.
And the configuration in `spring.cloud.nacos.config.file-extension` does not have any impact on the customized Data Id file extension.
NOTE: When `spring.cloud.nacos.config.refreshable-dataids` specifies the data ids that support dynamic refresh, the corresponding values of the data ids should also specify file extensions.
=== Nacos Config Endpoint
Nacos Config provides an Endpoint internally with a corresponding endpoint id of `nacos-config`.
Endpoint exposed json contains three properties:
1. Sources: Current application configuration data information
2. RefreshHistory: Configuration refresh history
3. NacosConfigProperties: Shows the current basic Nacos configurations of the current service
The followings shows how a service instance accesses the Endpoint:
[source,json,indent=0]
----
{
"NacosConfigProperties": {
"serverAddr": "127.0.0.1:8848",
"encode": null,
"group": "DEFAULT_GROUP",
"prefix": null,
"fileExtension": "properties",
"timeout": 3000,
"endpoint": null,
"namespace": null,
"accessKey": null,
"secretKey": null,
"contextPath": null,
"clusterName": null,
"name": null,
"sharedDataids": "base-common.properties,common.properties",
"refreshableDataids": "common.properties",
"extConfig": null
},
"RefreshHistory": [{
"timestamp": "2019-07-29 11:20:04",
"dataId": "nacos-config-example.properties",
"md5": "7d5d7f1051ff6571e2ec9f90887d9d91"
}],
"Sources": [{
"lastSynced": "2019-07-29 11:19:04",
"dataId": "common.properties"
}, {
"lastSynced": "2019-07-29 11:19:04",
"dataId": "base-common.properties"
}, {
"lastSynced": "2019-07-29 11:19:04",
"dataId": "nacos-config-example.properties"
}]
}
----
=== Disable Nacos Config AutoConfiguration
set spring.cloud.nacos.config.enabled = false to disable Spring Cloud Nacos Config AutoConfiguration.
=== More Information about Nacos Config Starter Configurations
The following shows the other configurations of the starter of Nacos Config:
|===
|Configuration |Key |Default Value |Description
|Server address|`spring.cloud.nacos.config.server-addr`|| IP and port of the Nacos Server listener
|Dataid from nacos config|`spring.cloud.nacos.config.name`|| First take the prefix, then go to the name, and finally take spring.application.name
|Dataid from nacos config|`spring.cloud.nacos.config.prefix`|| First take the prefix, then go to the name, and finally take spring.application.name
|Encode for nacos config content|`spring.cloud.nacos.config.encode`||Encode for nacos config content
|GROUP for nacos config|`spring.cloud.nacos.config.group`|`DEFAULT_GROUP`|GROUP for nacos config
|The suffix of nacos config dataId, also the file extension of config content.|`spring.cloud.nacos.config.fileExtension`|`properties`|The suffix of nacos config dataId, also the file extension of config content(now support properties or yaml(yml))
|Timeout for get config from nacos|`spring.cloud.nacos.config.timeout`|`3000`|Timeout for get config from nacos
|Endpoint|`spring.cloud.nacos.config.endpoint`||Endpoint
|Namespace|`spring.cloud.nacos.config.namespace`||Namespace
|AccessKey|`spring.cloud.nacos.config.accessKey`||Alibaba Cloud account accesskey
|SecretKey|`spring.cloud.nacos.config.secretKey`||Alibaba Cloud account secretkey
|The context path of Nacos Server|`spring.cloud.nacos.config.contextPath`||The context path of Nacos Server
|Cluster name|`spring.cloud.nacos.config.clusterName`||Cluster name
|Dataid for Shared Configuration|`spring.cloud.nacos.config.sharedDataids`||Dataid for Shared Configuration, split by ","
|Dynamic refresh dataid for Shared Configuration|`spring.cloud.nacos.config.refreshableDataids`||Dynamic refresh dataid for Shared Configuration, split by ","
|custom dataid|`spring.cloud.nacos.config.extConfig`||It's a Listbuild up by `Config` POJO. `Config` has 3 attributes, `dataId`, `group` and `refresh`
|===

@ -1,363 +0,0 @@
== Spring Cloud Alibaba Nacos Discovery
Nacos is an easy-to-use dynamic service discovery, configuration and service management platform for building cloud native applications.
With Spring Cloud Alibaba Nacos Discovery, you can quickly access the Nacos service registration feature based on Spring Cloud's programming model.
=== Service Registration/Discovery: Nacos Discovery
Service discovery is one of the key components in the microservices architecture. In such a architecture, configuring a service list for every client manually could be a daunting task, and makes dynamic scaling extremely difficult.
Nacos Discovery helps you to register your service to the Nacos server automatically, and the Nacos server keeps track of the services and refreshes the service list dynamically. In addition, Nacos
Discovery registers some of the metadata of the service instance, such as host, port, health check URL, homepage to Nacos. For details about how to download and start Nacos, refer to the https://nacos.io/zh-cn/docs/quick-start.html[Nacos Website].
=== How to Introduce Nacos Discovery for service registration/discovery
please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alibaba-nacos-discovery`.
[source,xml,indent=0]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
----
=== An example of using Nacos Discovery for service registration/discovery and call
Nacos Discovery integrate with the Netflix Ribbon, RestTemplate or OpenFeign can be used for service-to-service calls.
==== Nacos Server Startup
For details about how to download and start Nacos, refer to the https://nacos.io/zh-cn/docs/quick-start.html[Nacos Website].
After Nacos Server starts, go to http://ip:8848 to view the console (default account name/password is nacos/nacos):
.Nacos Dashboard
image::https://img.alicdn.com/tfs/TB1XEfwbQH0gK0jSZPiXXavapXa-2790-1060.png[]
For more Nacos Server versions, you can download the latest version from https://github.com/alibaba/nacos/releases[release page].
==== Start a Provider Application
The following sample illustrates how to register a service to Nacos.
* Configuration of pom.xml The following is a complete example of pom.xml
.pom.xml
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>open.source.test</groupId>
<artifactId>nacos-discovery-test</artifactId>
<version>1.0-SNAPSHOT</version>
<name>nacos-discovery-test</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
----
* Configuration of application.properties Some of the basic configurations of Nacos must be included in application.properties(or application.yaml), as shown below
.application.properties
[source,properties]
----
server.port=8081
spring.application.name=nacos-provider
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*
----
NOTE: If you do not want to use Nacos for service registration and discovery, you can set `spring.cloud.nacos.discovery` to `false`.
* The following is a sample for starting Provider:
[source,java,indent=0]
----
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderDemoApplication {
public static void main(String[] args) {
SpringApplication.run(NacosProviderDemoApplication.class, args);
}
@RestController
public class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Discovery " + string;
}
}
}
----
Now you can see the registered services on the Nacos console.
NOTE: Before you start the provider application, please start Nacos first. Refer to https://nacos.io/zh-cn/docs/quick-start.html[Naco Website] for more details.
==== Start a Consumer Application
It might not be as easy as starting a provider application, because the consumer needs to call the RESTful service of the provider. In this example, we will use the most primitive way, that is,
combining the LoadBalanceClient and RestTemplate explicitly to access the RESTful service.
You can refer to section 1.2 for pom.xml and application.properties configurations. The following is the sample code for starting a consumer application.
NOTE: You can also access the service by using RestTemplate and FeignClient with load balancing.
[source, java]
----
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApp {
@RestController
public class NacosController{
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@Value("${spring.application.name}")
private String appName;
@GetMapping("/echo/app-name")
public String echoAppName(){
//Access through the combination of LoadBalanceClient and RestTemplate
ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider");
String path = String.format("http://%s:%s/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);
System.out.println("request path:" +path);
return restTemplate.getForObject(path,String.class);
}
}
//Instantiate RestTemplate Instance
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApp.class,args);
}
}
----
In this example, we injected a LoadBalancerClient instance, and instantiated a RestTemplate manually. At the same time, we injected the configuration value of `spring.application.name` into the application,
so that the current application name can be displayed when calling the service of the provider.
NOTE: Please start Nacos before you start the consumer application. For details, please refer to https://nacos.io/zh-cn/docs/quick-start.html[Nacos Website].
Next, access the `http://ip:port/echo/app-name` interface provided by the consumer. Here we started the port of 8082. The access result is shown below
Addresshttp://127.0.0.1:8082/echo/app-name
Access result Hello Nacos Discovery nacos-consumer
=== Nacos Discovery Endpoint
Nacos Discovery provides an Endpoint internally with a corresponding endpoint id of `nacosdiscovery`.
Endpoint exposed json contains two properties:
1. subscribe: Shows the current service subscribers
2. NacosDiscoveryProperties: Shows the current basic Nacos configurations of the current service
The followings shows how a service instance accesses the Endpoint:
[source, json]
----
{
"subscribe": [
{
"jsonFromServer": "",
"name": "nacos-provider",
"clusters": "",
"cacheMillis": 10000,
"hosts": [
{
"instanceId": "30.5.124.156#8081#DEFAULT#nacos-provider",
"ip": "30.5.124.156",
"port": 8081,
"weight": 1.0,
"healthy": true,
"enabled": true,
"cluster": {
"serviceName": null,
"name": null,
"healthChecker": {
"type": "TCP"
},
"defaultPort": 80,
"defaultCheckPort": 80,
"useIPPort4Check": true,
"metadata": {
}
},
"service": null,
"metadata": {
}
}
],
"lastRefTime": 1541755293119,
"checksum": "e5a699c9201f5328241c178e804657e11541755293119",
"allIPs": false,
"key": "nacos-provider",
"valid": true
}
],
"NacosDiscoveryProperties": {
"serverAddr": "127.0.0.1:8848",
"endpoint": "",
"namespace": "",
"logName": "",
"service": "nacos-provider",
"weight": 1.0,
"clusterName": "DEFAULT",
"metadata": {
},
"registerEnabled": true,
"ip": "30.5.124.201",
"networkInterface": "",
"port": 8082,
"secure": false,
"accessKey": "",
"secretKey": ""
}
}
----
=== Weight Route
==== Spring Cloud LoadBalancer
.pom.xml
[source,xml]
----
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
</dependencies>
----
.application.properties
[source,properties]
----
spring.cloud.loadbalancer.ribbon.enabled=false
spring.cloud.loadbalancer.nacos.enabled=true
----
=== IPv4 to IPv6 address migration scheme
==== Both register IPv4 and IPv6 address
After configuring above Spring Cloud LoadBalancer as the load balancing policy, the IPv4 address and IPv6 address of the microservice will be registered with the registry by default after the application is started, where the IPv4 address will be stored in the IP field of the Nacos service list, the IPv6 address will be in the metadata field of Nacos, and its corresponding Key will be IPv6. When a service consumer calls a service provider, it selects the appropriate IP address type to initiate a service call based on its IP address stack support. Specific rules:
(1) If the service consumer itself supports IPv4 and IPv6 dual address stacks or only supports IPv6 address stacks, the service consumer will use the IPv6 address provided by the service to initiate a service call, and if the IPv6 address call fails, if it also supports the IPv4 address stack, it is temporarily not supported to switch to IPv4 and then initiate a retry call;
(2) If the service consumer itself only supports IPv4 single-address stack, the service consumer will use the IPv4 address provided by the service to initiate service calls.
==== Only Register IPv4 address
If you only want to register IPv4 address.Config in application.properties as follows:
[source,properties]
----
spring.cloud.nacos.discovery.ip-type=IPv4
----
==== Only Register IPv6 address
If you only want to register IPv6 address.Config in application.properties as follows:
[source,properties]
----
spring.cloud.nacos.discovery.ip-type=IPv6
----
=== More Information about Nacos Discovery Starter Configurations
The following shows the other configurations of the starter of Nacos Discovery:
|===
|Configuration |Key |Default Value |Description
|Server address|`spring.cloud.nacos.discovery.server-addr`||IP and port of the Nacos Server listener
|Service name|`spring.cloud.nacos.discovery.service`|`${spring.application.name}`|Name the current service
|Weight|`spring.cloud.nacos.discovery.weight`|`1`|Value range: 1 to 100. The bigger the value, the greater the weight
|Network card name|`spring.cloud.nacos.discovery.network-interface`||If the IP address is not specified, the registered IP address is the IP address of the network card. If this is not specified either, the IP address of the first network card will be used by default.
|Registered IP address|`spring.cloud.nacos.discovery.ip`||Highest priority
|Registered IP address Type|`spring.cloud.nacos.discovery.ip-type`|`IPv4`|IPv4 and IPv6 can be configured, If there are multiple IP addresses of the same type of network card, and you want to specify a specific network segment address, you can use `spring.cloud.inetutils.preferred-networks` to configure the filter address
|Registered port|`spring.cloud.nacos.discovery.port`|`-1`|Will be detected automatically by default. Do not need to be configured.
|Namespace|`spring.cloud.nacos.discovery.namespace`||A typical scenario is to isolate the service registration for different environment, such as resource (configurations, services etc.) isolation between testing and production environment
|AccessKey|`spring.cloud.nacos.discovery.access-key`||Alibaba Cloud account accesskey
|SecretKey|`spring.cloud.nacos.discovery.secret-key`||Alibaba Cloud account secretkey
|Metadata|`spring.cloud.nacos.discovery.metadata`||You can define some of the metadata for your services in the Map format
|Log file name|`spring.cloud.nacos.discovery.log-name`||
|Cluster Name|`spring.cloud.nacos.discovery.cluster-name`|`DEFAULT`|Cluster name of Nacos
|Endpoint|`spring.cloud.nacos.discovery.endpoint`||The domain name of a certain service in a specific region. You can retrieve the server address dynamically with this domain name
|Integrate LoadBalancer or not|`spring.cloud.loadbalancer.nacos.enabled`|`false`|
|Enable Nacos Watch|`spring.cloud.nacos.discovery.watch.enabled`|`false`|set to true to enable watch
|Enable Nacos Discovery HeartBeat|`spring.cloud.nacos.discovery.heart-beat.enabled`|`false`|set to true to enable heart beat
|===

@ -1,157 +0,0 @@
== Spring Cloud Alibaba Cloud OSS
OSSObject Storage Serviceis a storage product on Alibaba Cloud. Spring Cloud Alibaba Cloud OSS provides the commercialized storage service in conformity with Spring Cloud specifications. We provide easy-to-use APIs and supports the integration of Resource in the Spring framework.
=== How to Introduce Spring Cloud Alibaba Cloud OSS
Weve released Spring Cloud Alibaba version 0.2.1. You will need to add dependency management POM first.
[source,xml]
----
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.2.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
----
Next we need to introduce Spring Cloud Alibaba Cloud OSS Starter.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
----
=== How to Use OSS API
==== Configure OSS
Before you start to use Spring Cloud Alibaba Cloud OSS, please add the following configurations in application.properties.
[source,properties]
----
spring.cloud.alicloud.access-key=Your Alibaba Cloud AK
spring.cloud.alicloud.secret-key=Your Alibaba Cloud SK
spring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
----
access-key and secret-key is the AK/SK of your Alibaba Cloud account. If you dont have one, please register an account first, and log on to https://usercenter.console.aliyun.com/#/manage/ak[Alibaba Cloud AK/SK Management] to get your AccessKey ID and Access Key Secret . If you havent create the AccessKeys, click “Create AccessKey” to create one.
For endpoint information, please refer to the OSS https://help.aliyun.com/document_detail/31837.html[Documentation] and get the endpoint for your region.
==== Introduce OSS API
The OSS API of Spring Cloud Alibaba Cloud OSS is based on the official OSS SDK, and includes APIs for uploading, downloading, viewing files.
Here is a simple application that uses the OSS API.
[source,java]
----
@SpringBootApplication
public class OssApplication {
@Autowired
private OSS ossClient;
@RequestMapping("/")
public String home() {
ossClient.putObject("bucketName", "fileName", new FileInputStream("/your/local/file/path"));
return "upload success";
}
public static void main(String[] args) throws URISyntaxException {
SpringApplication.run(OssApplication.class, args);
}
}
----
Before you upload your files, please https://account.aliyun.com/register/register.htm?spm=5176.8142029.388261.26.e9396d3eaYK2sG&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F[Register an Alibaba Cloud Account]. If you already have one, please https://common-buy.aliyun.com/?spm=5176.8465980.unusable.dopen.4cdf1450rg8Ujb&commodityCode=oss#/open[Sign up for OSS].
Log on to the https://oss.console.aliyun.com/overview[OSS Console], click “Create New Bucket” and create a bucket as instructed. Replace the bucket name in the “bucketname” of the previous code with your new bucket name. "fileName” can be any name you like, and "/your/local/file/path” can be any local file path. Next you can run `curl http://127.0.0.1:port number/ to upload your files, and you will see your file on the https://oss.console.aliyun.com/overview[OSS Console].
For more instructions on OSS APIs, please refer to https://help.aliyun.com/document_detail/32008.html[OSS SDK Documentation].
=== Integrate with the Resource Specifications of Spring
Spring Cloud Alibaba Cloud OSS integrates the Resource of the Spring framework, which allows you to use the OSS resources easily.
The following is a simple example of how to use Resource.
[source,java]
----
@SpringBootApplication
public class OssApplication {
@Value("oss://bucketName/fileName")
private Resource file;
@GetMapping("/file")
public String fileResource() {
try {
return "get file resource success. content: " + StreamUtils.copyToString(
file.getInputStream(), Charset.forName(CharEncoding.UTF_8));
} catch (Exception e) {
return "get resource fail: " + e.getMessage();
}
}
public static void main(String[] args) throws URISyntaxException {
SpringApplication.run(OssApplication.class, args);
}
}
----
NOTE: A prerequisite for the above sample is that you need to have a bucket named “bucketName” on OSS, and you have a file named “fileName” in this bucket.
=== Use STS Authentication
In addition to AccessKeys, Spring Cloud Alibaba Cloud OSS also supports STS authentication. STS is an authentication method with temporary security tokens, and is usually used for a third party to access its resources temporarily.
For a third party to access resources temporarily, it only needs to complete the following configurations.
[source,properties]
----
spring.cloud.alicloud.oss.authorization-mode=STS
spring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
spring.cloud.alicloud.oss.sts.access-key=Your authenticated AK
spring.cloud.alicloud.oss.sts.secret-key=Your authenticated SK
spring.cloud.alicloud.oss.sts.security-token=Your authenticated ST
----
Among which, spring.cloud.alicloud.oss.authorization-mode is the enumeration type. Fill in STS here means that STS authentication is used. For endpoint information, refer to the https://help.aliyun.com/document_detail/31837.html[OSS Documentation] and fill in the endpoint for your region.
Access-key, secret-key and the security-token need to be issued by the authentication side. For more information about STS, refer to https://help.aliyun.com/document_detail/31867.html[STS Documentation].
=== More Configurations for the Client
In addition to basic configurations, Spring Cloud Alibaba Cloud OSS also supports many other configurations, which are also included in the application.properties file.
Here are some examples.
[source,properties]
----
spring.cloud.alicloud.oss.authorization-mode=STS
spring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
spring.cloud.alicloud.oss.sts.access-key=Your authenticated AK
spring.cloud.alicloud.oss.sts.secret-key=Your authenticated SK
spring.cloud.alicloud.oss.sts.security-token=Your authenticated ST
spring.cloud.alicloud.oss.config.connection-timeout=3000
spring.cloud.alicloud.oss.config.max-connections=1000
----
For more configurations, refer to the table at the bottom of https://help.aliyun.com/document_detail/32010.html[OSSClient Configurations].
NOTE: In most cases, you need to connect the parameter names with “-” for the parameters in the table of https://help.aliyun.com/document_detail/32010.html[OSSClient Configurations] with “-”, and all letters should be in lowercase. For example, ConnectionTimeout should be changed to connection-timeout.

@ -1,298 +0,0 @@
== Spring Cloud Alibaba RocketMQ Binder
=== Introduction of RocketMQ
https://rocketmq.apache.org[RocketMQ] is an open-source distributed message system. It is based on highly available distributed cluster technologies and provides message publishing and subscription service with low latency and high stability. RocketMQ is widely used in a variety of industries, such as decoupling of asynchronous communication, enterprise solutions, financial settlements, telecommunication, e-commerce, logistics, marketing, social media, instant messaging, mobile applications, mobile games, videos, IoT, and Internet of Vehicles.
It has the following features:
* Strict order of message sending and consumption
* Rich modes of message pulling
* Horizontal scalability of consumers
* Real-time message subscription
* Billion-level message accumulation capability
=== RocketMQ Usages
* Download RocketMQ
Download https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip[Latest Binary File of RocketMQ], and decompress it.
The decompressed directory is as follows:
```
apache-rocketmq
├── LICENSE
├── NOTICE
├── README.md
├── benchmark
├── bin
├── conf
└── lib
```
* Start NameServer
```bash
nohup sh bin/mqnamesrv &
tail -f ~/logs/rocketmqlogs/namesrv.log
```
* Start Broker
```bash
nohup sh bin/mqbroker -n localhost:9876 &
tail -f ~/logs/rocketmqlogs/broker.log
```
* Send and Receive Messages
Send messages:
```bash
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
```
Output when the message is successfully sent: `SendResult [sendStatus=SEND_OK, msgId= ...`
Receive messages:
```bash
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
```
Output when the message is successfully received `ConsumeMessageThread_%d Receive New Messages: [MessageExt...`
* Disable Server
```bash
sh bin/mqshutdown broker
sh bin/mqshutdown namesrv
```
=== Introduction of Spring Cloud Stream
Spring Cloud Stream is a microservice framework used to build architectures based on messages. It helps you to create production-ready single-server Spring applications based on SpringBoot, and connects with Broker using `Spring Integration`.
Spring Cloud Stream provides unified abstractions of message middleware configurations, and puts forward concepts such as publish-subscribe, consumer groups and partition.
There are two concepts in Spring Cloud Stream: Binder and Binding
* Binder: A component used to integrate with external message middleware, and is used to create binding. Different message middleware products have their own binder implementations.
For example, `Kafka` uses `KafkaMessageChannelBinder`, `RabbitMQ` uses `RabbitMessageChannelBinder`, while `RocketMQ` uses `RocketMQMessageChannelBinder`.
* Binding: Includes Input Binding and Output Binding.
Binding serves as a bridge between message middleware and the provider and consumer of the applications. Developers only need to use the Provider or Consumer to produce or consume data, and do not need to worry about the interactions with the message middleware.
.Spring Cloud Stream
image::https://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/images/SCSt-overview.png[]
Now lets use Spring Cloud Stream to write a simple code for sending and receiving messages:
```java
MessageChannel messageChannel = new DirectChannel();
// Message subscription
((SubscribableChannel) messageChannel).subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<? > message) throws MessagingException {
System.out.println("receive msg: " + message.getPayload());
}
});
// Message sending
messageChannel.send(MessageBuilder.withPayload("simple msg").build());
```
All the message types in this code are provided by the `spring-messaging`module. It shields the lower-layer implementations of message middleware. If you would like to change the message middleware, you only need to configure the related message middleware information in the configuration file and modify the binder dependency.
**The lower layer of Spring Cloud Stream also implements various code abstractions based on the previous code.**
=== How to use Spring Cloud Alibaba RocketMQ Binder
For using the Spring Cloud Alibaba RocketMQ Binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
</dependency>
```
Alternatively, you can also use the Spring Cloud Stream RocketMQ Starter:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
```
=== How Spring Cloud Alibaba RocketMQ Binder Works
This is the implementation architecture of Spring Cloud Stream RocketMQ Binder:
.SCS RocketMQ Binder
image::https://img.alicdn.com/tfs/TB1v8rcbUY1gK0jSZFCXXcwqXXa-1236-773.png[]
The implementation of RocketMQ Binder depend on the https://github.com/apache/rocketmq-spring[RocketMQ-Spring] framework.
RocketMQ Spring framework is an integration of RocketMQ and Spring Boot. It provides three main features:
1. `RocketMQTemplate`: Sending messages, including synchronous, asynchronous, and transactional messages.
2. `@RocketMQTransactionListener`: Listen and check for transaction messages.
3. `@RocketMQMessageListener`: Consume messages.
`RocketMQMessageChannelBinder` is a standard implementation of Binder, it will build `RocketMQInboundChannelAdapter` and `RocketMQMessageHandler` internally.
`RocketMQMessageHandler` will construct `RocketMQTemplate` based on the Binding configuration. `RocketMQTemplate` will convert the `org.springframework.messaging.Message` message class of `spring-messaging` module to the RocketMQ message class `org.apache.rocketmq.common .message.Message` internally, then send it out.
`RocketMQInboundChannelAdapter` will also construct `RocketMQListenerBindingContainer` based on the Binding configuration, and `RocketMQListenerBindingContainer` will start the RocketMQ `Consumer` to receive the messages.
NOTE: RocketMQ Binder Application can also be used to configure rocketmq.** to trigger RocketMQ Spring related AutoConfiguration
Currently Binder supports setting the relevant key in `Header` to set the properties of the RocketMQ message.
For example, `TAGS`, `DELAY`, `TRANSACTIONAL_ARG`, `KEYS`, `WAIT_STORE_MSG_OK`, `FLAG` represent the labels corresponding to the RocketMQ message.
```java
MessageBuilder builder = MessageBuilder.withPayload(msg)
.setHeader(RocketMQHeaders.TAGS, "binder")
.setHeader(RocketMQHeaders.KEYS, "my-key")
.setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");
Message message = builder.build();
output().send(message);
```
Or use StreamBridge
```java
MessageBuilder builder = MessageBuilder.withPayload(msg)
.setHeader(RocketMQHeaders.TAGS, "binder")
.setHeader(RocketMQHeaders.KEYS, "my-key")
.setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");
Message message = builder.build();
streamBridge.send("producer-out-0", message);
```
NOTE: More Examples: https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/rocketmq-example[RocketMQ Example]
=== Configuration Options
==== RocketMQ Binder Properties
spring.cloud.stream.rocketmq.binder.name-server::
The name server of RocketMQ Server(Older versions use the namesrv-addr configuration item).
+
Default: `127.0.0.1:9876`.
spring.cloud.stream.rocketmq.binder.access-key::
The AccessKey of Alibaba Cloud Account.
+
Default: null.
spring.cloud.stream.rocketmq.binder.secret-key::
The SecretKey of Alibaba Cloud Account.
+
Default: null.
spring.cloud.stream.rocketmq.binder.enable-msg-trace::
Enable Message Trace feature for all producers and consumers.
+
Default: `true`.
spring.cloud.stream.rocketmq.binder.customized-trace-topic::
The trace topic for message trace.
+
Default: `RMQ_SYS_TRACE_TOPIC`.
+
spring.cloud.stream.rocketmq.binder.access-channel::
The commercial version of rocketmq message trajectory topic is adaptive,the value is CLOUD
+
Default: null.
==== RocketMQ Consumer Properties
The following properties are available for RocketMQ producers only and must be prefixed with `spring.cloud.stream.rocketmq.bindings.<channelName>.consumer.`.
enable::
Enable Consumer Binding.
+
Default: `true`.
tags::
Consumer subscription tags expression, tags split by `||`.
+
Default: empty.
sql::
Consumer subscription sql expression.
+
Default: empty.
broadcasting::
Control message mode, if you want all subscribers receive message all message, broadcasting is a good choice.
+
Default: `false`.
orderly::
Receiving message concurrently or orderly.
+
Default: `false`.
delayLevelWhenNextConsume::
Message consume retry strategy for concurrently consume:
* -1,no retry,put into DLQ directly
* 0,broker control retry frequency
* >0,client control retry frequency
+
Default: `0`.
suspendCurrentQueueTimeMillis::
Time interval of message consume retry for orderly consume.
+
Default: `1000`.
==== RocketMQ Provider Properties
The following properties are available for RocketMQ producers only and must be prefixed with `spring.cloud.stream.rocketmq.bindings.<channelName>.producer.`.
enable::
Enable Producer Binding.
+
Default: `true`.
group::
Producer group name.
+
Default: empty.
maxMessageSize::
Maximum allowed message size in bytes.
+
Default: `8249344`.
transactional::
Send Transactional Message.
+
Default: `false`.
sync::
Send message in synchronous mode.
+
Default: `false`.
vipChannelEnabled::
Send message with vip channel.
+
Default: `true`.
sendMessageTimeout::
Millis of send message timeout.
+
Default: `3000`.
compressMessageBodyThreshold::
Compress message body threshold, namely, message body larger than 4k will be compressed on default.
+
Default: `4096`.
retryTimesWhenSendFailed::
Maximum number of retry to perform internally before claiming sending failure in synchronous mode.
+
Default: `2`.
retryTimesWhenSendAsyncFailed::
Maximum number of retry to perform internally before claiming sending failure in asynchronous mode.
+
Default: `2`.
retryNextServer::
Indicate whether to retry another broker on sending failure internally.
+
Default: `false`.

@ -1,185 +0,0 @@
== Spring Cloud Alibaba 2021.0.1.0 Upgrade Guide
=== Version Number
Starting from 2021.0.1.0, the SCA version will correspond to the Spring Cloud version, the first three are the Spring Cloud version, and the last one is the extended version.
=== Upgrade Steps
Upgrade version (note the version correspondence)
```xml
<dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
```
*Note:* The `spring-cloud-starter-alibaba-nacos-config` module removes the `spring-cloud-starter-bootstrap` dependency. If you want to use with the bootstrap way, you need to manually add this dependency, now recommended to import configuration using `spring.config.import`.
After completing the above steps, you can smoothly switch to the `Spring Cloud Alibaba 2021.0.1.0` version.
=== New Features and Usage
==== Support `spring.config.import`
Suppose there is a configuration file (`bootstrap.yml`) here, how should it be configured to upgrade to a new version?
```yaml
# bootstrap.yml
spring:
cloud:
nacos:
config:
name: test.yml
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848
extension-configs:
- dataId: test01.yml
group: group_01
- dataId: test02.yml
group: group_02
refresh: false
```
The two configurations are equivalent.
```yaml
# application.yml
spring:
cloud:
nacos:
config:
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848
config:
import:
- optional:nacos:test.yml # Listening DEFAULT_GROUP:test.yml
- optional:nacos:test01.yml?group=group_01 # Override default grouplistening group_01:test01.yml
- optional:nacos:test02.yml?group=group_02&refreshEnabled=false # Do not enable dynamic refresh
- nacos:test03.yml # When the nacos configuration is pulled abnormally, it will fail quickly, which will cause the Spring container to fail to start.
```
Note:
- If you use `spring.config.import`, you can't use bootstrap.yml/properties.
- If `spring-cloud-starter-alibaba-nacos-config` is using and the configuration is imported using the `spring.config.import` way, the project will automatically detect whether the `nacos:` entry has been imported. If there is no import nacos entry, the following error will occur:
----
The spring.config.import property is missing a nacos: entry
Action:
Add a spring.config.import=nacos: property to your configuration.
If configuration is not required add spring.config.import=optional:nacos: instead.
To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.
----
You can manually turn it off by setting `spring.cloud.nacos.config.import-check.enabled=false`, but it is not recommended to do so, this function can help you check whether to introduce unnecessary dependencies.
- If you want to keep the previous usage (bootstrap way), you only need to add the dependency `spring-cloud-starter-bootstrap` dependency and don't need modifying a line of code.
you can go https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/nacos-example/nacos-config-2.4.x-example[here] to see the complete example.
==== Nacos Failure Tolerance
Add new configuration item `spring.cloud.nacos.discovery.failure-tolerance-enabled`. Set to true (default false) to enable acos service discovery failure fault tolerance. This feature will return the last instance obtained when nacos fails to get instances. It can provide fault tolerance when the nacos server network is unstable, and will not cause all requests to hang up.
==== Support Feign Circuit Breaker Configuration
When Sentinel is implemented as a Spring Cloud circuit breaker, support for adding circuit breaker configuration for each FeignClient.
Add dependency.
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-circuitbreaker-sentinel</artifactId>
</dependency>
```
And here are two FeignClient
```java
@FeignClient(value = "user", fallback = UserFallback.class)
public interface UserClient {
@GetMapping("/{success}")
String success(@PathVariable Boolean success);
}
@FeignClient(value = "order", fallback = OrderFallback.class)
public interface OrderClient {
@GetMapping("/{success}")
String success(@PathVariable Boolean success);
@GetMapping("/{success}")
String error(@PathVariable Boolean success);
}
```
Now there are these requirements:
1. I want to configure a default circuit breaker for the global FeignClient.
2. I want to configure a circuit breaker rule for user FeignClient.
3. I want to configure a circuit breaker for the specified method (error) of order FeignClient.
Add the following configuration.
```yaml
feign:
circuitbreaker:
enabled: true
sentinel:
default-rule: default # global rule name
rules:
# global configuration, the meaning of these parameters, please see com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule
# you can configure multiple rules
default:
- grade: 2
count: 1
timeWindow: 1
statIntervalMs: 1000
minRequestAmount: 5
- grade: 2
count: 1
# for user FeignClient
user:
- grade: 2
count: 1
timeWindow: 1
statIntervalMs: 1000
minRequestAmount: 5
# for order FeignClient 'error' methodnote the square brackets, otherwise the parsed value will be inconsistent.
"[order#error(Boolean)]":
- grade: 2
count: 1
timeWindow: 1
statIntervalMs: 1000
minRequestAmount: 5
```
This feature also supports dynamic refresh from the configuration center. You can put the above configuration into the configuration center (nacos, consul), and the modified rules will take effect immediately. If you do not need this feature, you can set `feign.sentinel.enable-refresh-rules=false` to disable it.
*Note:* If you are using `spring-cloud-starter-alibaba-sentinel`, please *DO NOT* configure `feign.sentinel.enable=true`, it will invalidate the configuration.
You can go https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-circuitbreaker-example[here] to see the complete example.
=== Little Advice For Upgrading
1. After Spring Boot 2.6, the prohibition of circular reference is enabled by default. It is recommended that you do not change it. This is a bad coding practice. If there is a circular reference in your project, please choose to refactor it.
2. Abandoning the way of importing configuration from the bootstrap way and using `spring.config.import` to import configuration, Spring Boot 2.4 has done a lot of optimization work on this, and it is no longer necessary to start a full container to refresh the environment.

@ -1,114 +0,0 @@
== Spring Cloud Alibaba Cloud SchedulerX
SchedulerXDistributed job scheduling is a component of EDAS, an Alibaba Cloud product. Spring Cloud Alibaba Cloud SchedulerX provides distributed job scheduling in conformity with the Spring Cloud specifications. SchedulerX provides timed job scheduling service with high accuracy with seconds, high stability and high availabiliy, and supports multiple job types, such as simple single-server jobs, simple multi-host jobs, script jobs, and grid jobs.
=== How to Introduce Spring Cloud Alibaba Cloud SchedulerX
If you want to use SchedulerX in your project, please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alicloud-schedulerX`.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-schedulerX</artifactId>
</dependency>
----
=== Start SchedulerX
After Spring Cloud Alibaba Cloud SchedulerX Starter is introduced into the client, you only need to complete a few simple configurations and you will be able to initialize the SchedulerX service automatically.
The following is a simple example.
[source,java]
----
@SpringBootApplication
public class ScxApplication {
public static void main(String[] args) {
SpringApplication.run(ScxApplication.class, args);
}
}
----
Add the following configurations in the application.properties file.
[source,properties]
----
server.port=18033
# cn-test is the test region of SchedulerX
spring.cloud.alicloud.scx.group-id=***
spring.cloud.alicloud.edas.namespace=cn-test
----
Before getting the group-id, please https://account.aliyun.com/register/register.htm?spm=5176.8142029.388261.26.e9396d3eEIv28g&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F[Register an Alibaba Cloud account], and then https://common-buy.aliyun.com/?spm=5176.11451019.0.0.6f5965c0Uq5tue&commodityCode=edaspostpay#/buy[Sign up for EDAS] and https://edas.console.aliyun.com/#/edasTools[Sign up for SchedulerX] as well.
To get the group-id, refer to the https://help.aliyun.com/document_detail/98784.html[SchedulerX Documentation].
NOTE: When you create a group, please select the “test” region.
=== Compile a simple job
Simple job is the most commonly used job type. You only need to implement the ScxSimpleJobProcessor interface.
The following is a sample of a simple single-server job.
[source,java]
----
public class SimpleTask implements ScxSimpleJobProcessor {
@Override
public ProcessResult process(ScxSimpleJobContext context) {
System.out.println("-----------Hello world---------------");
ProcessResult processResult = new ProcessResult(true);
return processResult;
}
}
----
=== Job Scheduling
Go to the https://edas.console.aliyun.com/#/edasSchedulerXJob?regionNo=cn-test[SchedulerX Jobs] page, select the “Test” region, and click “Create Job” on the upper-right corner to create a job, as shown below.
[source,text]
----
Job Group Test——***-*-*-****
Job process interfaceSimpleTask
Type Simple Single-Server Job
Quartz Cron Expression Default Option——0 * * * * ?
Job Description Empty
Custom Parameters Empty
----
The job above is a “Simple Single-Server Job”, and specified a Cron expression of "0 * * * * ?" . This means that the job will be executed once and once only in every minute.
For more job types, refer to https://help.aliyun.com/document_detail/43136.html[SchedulerX Documentation].
=== Usage in Production Environment
The previous examples shows how to use SchedulerX in the “Test” region, which is mainly used for local testing.
At the production level, you need to complete some other configurations in addition to the group-id and namespace as mentioned above. See examples below:
[source,properties]
----
server.port=18033
# cn-test is the test region of SchedulerX
spring.cloud.alicloud.scx.group-id=***
spring.cloud.alicloud.edas.namespace=***
# If your application runs on EDAS, you do not need to configure the following.
spring.cloud.alicloud.access-key=***
spring.cloud.alicloud.secret-key=***
# The following configurations are not mandatory. You can refer to the SchedulerX documentation for details.
spring.cloud.alicloud.scx.domain-name=***
----
The way to get the group-id is the same as described in the previous examples, and you can get the namespace by clicking “Namespaces” in the left-side navigation pane of the EDAS console.
NOTE: Group-id must be created within a namespace.
Access-key and secret-key are the AK/SK of your Alibaba Cloud account. If you deploy you applications on EDAS, then you do not need to fill in this information. Otherwise please go to https://usercenter.console.aliyun.com/#/manage/ak[Security Information] to get your AccessKeys.
Domain-name is not mandatory. You can refer to https://help.aliyun.com/document_detail/35359.html[SchedulerX Documentation] for details.

@ -1,87 +0,0 @@
== Spring Cloud Alibaba Seata
=== Introducing Seata
Seata is a distributed transaction framework to ensure the data consistency of each service under the microservice architecture.
=== How to use seata
To include Seata in your project, use the starter with group ID `com.alibaba.cloud` and artifact ID `spring-cloud-starter-alibaba-seata`.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
----
The project provides relevant https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/seata-example[Example], before running it, you need to complete the following steps:
1. Ensure that `nacos-server` is running locally on the `8848` port.
2. Configuration database, will application in the resources directory of the `account-server`, `order-service`, `storage-service` three applications. The following configuration in the yml file is modified to the actual configuration in your running environment.
base:
config:
mdb:
hostname: 127.0.0.1 #your mysql server ip address
dbname: seata #your database name for test
port: 3306 #your mysql server listening port
username: root #your mysql server username
password: root #your mysql server password
3. Create the database tables, you can refer to `all.sql` under `spring-cloud-alibaba-examples/seata-example` for a quick operation.
- According to the selected transaction mode, create a https://github.com/seata/seata/tree/develop/script/client[transaction log table]. For example, the default is AT mode, then enter at/db and select the corresponding database script executes
- Create a https://github.com/seata/seata/tree/develop/script/server/db[status record table] related to seata transactions, including `global_table` , `branch_table` , `lock_table` , `distributed_lock`.
- Create the database tables required by `spring-cloud-alibaba-examples/seata-example` .
4. Create the Nacos configuration in `spring-cloud-alibaba-examples/seata-example` .
data id: seata.properties,
Group: SEATA_ Group(Seata 1.5.1 default group)
Configuration Content:
service.vgroupMapping.order-service-tx-group=default
service.vgroupMapping.account-service-tx-group=default
service.vgroupMapping.business-service-tx-group=default
service.vgroupMapping.storage-service-tx-group=default
5. Start Seata Server This describes SpringBoot and download server in two ways.
- Run seata-server from `spring-cloud-alibaba-examples/seata-example` to start Seata server.
- Run https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html[seata-server.jar] provided by official website to start Seata server.
6. Start the sub-services under the `spring-cloud-alibaba-examples/seata-example` including `account-service` , `order-service` , `storage-service` , and finally start the global transaction control service `business-service`。
7. After launching the example, the following URLs are accessed through the GET method of HTTP to validate scenarios where other services are invoked through RestTemplate and FeignClient in `business-service` respectively.
http://127.0.0.1:18081/seata/feign
http://127.0.0.1:18081/seata/rest
=== Seata Dashboard
- Seata 1.5.1 supports Seata console local access console address: `http://127.0.0.1:7091`。
- Through the Seata console, you can observe the executing transaction information and global lock information, and delete the relevant information when the transaction is completed.
=== How do I verify the success of a distributed transaction?
==== Whether Xid information was successfully transmitted
In the Controller of the three services `account-server`, `order-service` and `storage-service`, the first logic executed is to output the Xid information in the RootContext. If you see that the correct Xid information is output, it changes every time and the Xid of all services in the same call is consistent. This indicates that the transfer and restore of Seata's Xid are normal.
==== Consistency of data in database
In this example, we simulate a scenario where a user purchases goods, StorageService is responsible for deducting the inventory quantity, OrderService is responsible for saving the order, and AccountService is responsible for deducting the user account balance.
To demonstrate the sample, we used Random in OrderService and AcountService. NextBoolean () randomly throws exceptions, simulating a scenario in which exceptions occur randomly when a service is invoked.
If the distributed transaction is valid, then the following equation should be true
- User Original Amount (1000) = User Existing Amount + Goods Unit Price (2) * Order Quantity * Goods Quantity per Order (2)
- Initial Quantity of Goods (100) = Existing Quantity of Goods + Order Quantity * Quantity of Goods per Order (2)
=== Support points for Spring Cloud
- Service providers that provide services through Spring MVC can automatically restore the Seata context when they receive HTTP requests with Seata information in the header.
- Support for automatic delivery of Seata context when service callers invoke through RestTemplate.
- Supports automatic delivery of the Seata context when a service caller invokes through a FeignClient.
- Supports scenarios where both SeataClient and Hystrix are used.
- Supports scenarios used by both SeataClient and Sentinel.

@ -1,426 +0,0 @@
== Spring Cloud Alibaba Sentinel
=== Introduction of Sentinel
As microservices become popular, the stability of service calls is becoming increasingly important. https://github.com/alibaba/Sentinel[Sentinel] takes "flow" as the breakthrough point, and works on multiple fields including flow control, circuit breaking and load protection to protect service reliability.
https://github.com/alibaba/Sentinel[Sentinel] has the following features:
* *Rich Scenarios* Sentinel has supported the key scenarios of Alibabas Double 11 Shopping Festivals for over 10 years, such as second kill(i.e., controlling sudden bursts of traffic flow so that its within the acceptable range of the system capacity), message load shifting, circuit breaking of unreliable downstream applications.
* *Comprehensive Real-Time Monitoring* Sentinel provides real-time monitoring capability. You can see the monitoring data of your servers at the accuracy of seconds, and even the overall runtime status of a cluster with less than 500 nodes.
* *Extensive Open-Source Ecosystem* Sentinel provides out-of-box modules that can be easily integrated with other open-source frameworks/libraries, such as Spring Cloud, Dubbo, and gRPC. To use Sentinel, you only need to introduce the related dependency and make a few simple configurations.
* *Sound SPI Extensions* Sentinel provides easy-to-use and sound SPI extension interfaces. You can customize logics with the SPI extensions quickly, for example, you can define your own rule management, or adapt to specific data sources.
=== How to Use Sentinel
If you want to use Sentinel in your project, please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alibaba-sentinel`.
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
```
The following is a simple example of how to use Sentinel:
```java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
@RestController
public class TestController {
@GetMapping(value = "/hello")
@SentinelResource("hello")
public String hello() {
return "Hello Sentinel";
}
}
```
The @SentinelResource annotation is used to identify if a resource is rate limited or degraded. In the above sample, the 'hello' attribute of the annotation refers to the resource name.
@SentinelResource also provides attributes such as `blockHandler`, `blockHandlerClass`, and `fallback` to identify rate limiting or degradation operations. For more details, refer to https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81[Sentinel Annotation Support].
The above examples are all used in the WebServlet environment. Sentinel currently supports WebFlux and needs to cooperate with the `spring-boot-starter-webflux` dependency to trigger the WebFlux-related automation configuration in sentinel starter.
```java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
@RestController
public class TestController {
@GetMapping("/mono")
@SentinelResource("hello")
public Mono<String> mono() {
return Mono.just("simple string")
.transform(new SentinelReactorTransformer<>("otherResourceName"));
}
}
```
===== Sentinel Dashboard
Sentinel dashboard is a lightweight console that provides functions such as machine discovery, single-server resource monitoring, overview of cluster resource data, as well as rule management. To use these features, you only need to complete a few steps.
*Note*: The statistics overview for clusters only supports clusters with less than 500 nodes, and has a latency of about 1 to 2 seconds.
.Sentinel Dashboard
image::https://github.com/alibaba/Sentinel/wiki/image/dashboard.png[]
To use the Sentinel dashboard, simply complete the following 3 steps.
====== Get the Dashboard
You can download the latest dashboard JAR file from the https://github.com/alibaba/Sentinel/releases[Release Page].
You can also get the latest source code to build your own Sentinel dashboard
* Download the https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard[Dashboard] project.
* Run the following command to package the code into a FatJar: `mvn clean package`
====== Start the Dashboard
Sentinel dashboard is a standard SpringBoot application, and you can run the JAR file in the Spring Boot mode.
```shell
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
```
If there is conflict with the 8080 port, you can use `-Dserver.port=new port` to define a new port.
==== Configure the Dashboard
.application.yml
[source,yaml]
----
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
----
The port number specified in `spring.cloud.sentinel.transport.port` will start an HTTP Server on the corresponding server of the application, and this server will interact with the Sentinel dashboard. For example, if a rate limiting rule is added in the Sentinel dashboard, the the rule data will be pushed to and recieved by the HTTP Server, which in turn registers the rule to Sentinel.
For more information about Sentinel dashboard, please refer to https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0[Sentinel Dashboard].
=== OpenFeign Support
Sentinel is compatible with the https://github.com/OpenFeign/feign[OpenFeign] component. To use it, in addition to introducing the `sentinel-starter` dependency, complete the following 2 steps:
* Enable the Sentinel support for feign in the properties file. `feign.sentinel.enabled=true`
* Add the `openfeign starter` dependency to trigger and enable `sentinel starter`:
```xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
```
This is a simple usage of `FeignClient`:
```java
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@GetMapping(value = "/echo/{str}")
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
```
NOTE: The resource name policy in the corresponding interface of Feign ishttpmethod:protocol://requesturl. All the attributes in the `@FeignClient` annotation is supported by Sentinel.
The corresponding resource name of the `echo` method in the `EchoService` interface is `GET:http://service-provider/echo/{str}`.
=== RestTemplate Support
Spring Cloud Alibaba Sentinel supports the protection of `RestTemplate` service calls using Sentinel. To do this, you need to add the `@SentinelRestTemplate` annotation when constructing the `RestTemplate` bean.
```java
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
```
The attribute of the `@SentinelRestTemplate` annotation support flow control(`blockHandler`, `blockHandlerClass`) and circuit breaking(`fallback`, `fallbackClass`).
==
The `blockHandler` or `fallback` is the static method of `blockHandlerClass` or `fallbackClass`.
The parameter and return value of method in `@SentinelRestTemplate` is same as `org.springframework.http.client.ClientHttpRequestInterceptor#interceptor`, but it has one more parameter `BlockException` to catch the exception by Sentinel.
The method signature of `handleException` in `ExceptionUtil` above should be like this:
```java
public class ExceptionUtil {
public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
...
}
}
```
NOTE: When the application starts, it will check if the `@SentinelRestTemplate` annotation corresponding to the flow control or circuit breaking method exists, if it does not exist, it will throw an exception.
The attribute of the `@SentinelRestTemplate` annotation is optional.
It will return `RestTemplate request block by sentinel` when you using `RestTemplate` blocked by Sentinel. You can override it by your own logic. We provide `SentinelClientHttpResponse` to handle the response.
Sentinel RestTemplate provides two granularities for resource rate limiting:
* `httpmethod:schema://host:port/path` Protocol, host, port and path
* `httpmethod:schema://host:port` Protocol, host and port
NOTE: Take Http GET `https://www.taobao.com/test` as an example. The corresponding resource names have two levels of granularities, `GET:https://www.taobao.com` and `GET:https://www.taobao.com/test`.
=== Dynamic Data Source Support
`SentinelProperties` provide `datasource` attribute to configure datasource.
For example, 4 data sources are configures
[source,properties]
----
spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.json
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
#spring.cloud.sentinel.datasource.ds1.file.data-type=custom
#spring.cloud.sentinel.datasource.ds1.file.converter-class=JsonFlowRuleListConverter
#spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel
spring.cloud.sentinel.datasource.ds2.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
spring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOW
spring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181
spring.cloud.sentinel.datasource.ds3.zk.rule-type=authority
spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application
spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinel
spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = test
spring.cloud.sentinel.datasource.ds4.apollo.rule-type=param-flow
----
This method follows the configuration of Spring Cloud Stream Binder. `TreeMap` is used for storage internally, and comparator is `String.CASE_INSENSITIVE_ORDER`.
NOTE: d1, ds2, ds3, ds4 are the names of `ReadableDataSource`, and can be coded as you like. The `file`, `zk`, `nacos` , `apollo` refer to the specific data sources. The configurations following them are the specific configurations of these data sources respecitively.
Every data source has 3 common configuration items: `data-type`, `converter-class` and `rule-type`.
`data-type` refers to `Converter`. Spring Cloud Alibaba Sentinel provides two embedded values by default: `json` and `xml` (the default is json if not specified). If you do not want to use the embedded `json` or `xml` `Converter`, you can also fill in `custom` to indicate that you will define your own `Converter`, and then configure the `converter-class`. You need to specify the full path of the class for this configuration.
`rule-type` refers to the rule type in datasource(`flow``degrade``authority``system`, `param-flow`, `gw-flow`, `gw-api-group`).
NOTE: XML format is not supported by default. To make it effective, you need to add the `jackson-dataformat-xml` dependency.
To learn more about how dynamic data sources work in Sentinel, refer to https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95[Dynamic Rule Extension].
=== Support Spring Cloud Gateway
Refer https://github.com/alibaba/Sentinel/wiki/API-Gateway-Flow-Control[API Gateway Flow Control]
If you want to use Sentinel Starter with Spring Cloud Gateway, you need to add the `spring-cloud-alibaba-sentinel-gateway` dependency and add the `spring-cloud-starter-gateway` dependency to let Spring Cloud Gateway AutoConfiguration class in the module takes effect:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
```
include::circuitbreaker-sentinel.adoc[]
=== Sentinel Endpoint
Sentinel provides an Endpoint internally with a corresponding endpoint id of `sentinel`.
Endpoint exposed json contains multi properties:
1. appName: application name
2. logDir: the directory of log
3. logUsePid: log name with pid ot not
4. blockPage: redirect page after sentinel block
5. metricsFileSize: the size of metrics file
6. metricsFileCharset: metrics file charset
7. totalMetricsFileCount: the total file count of of metrics file
8. consoleServer: sentinel dashboard address
9. clientIp: client ip
10. heartbeatIntervalMs: client heartbeat interval with dashboard
11. clientPort: the client needs to expose the port to interact with the dashboard
12. coldFactor: cold factor
13. filter: CommonFilter related properties, such as order, urlPatterns and enable
14. datasource: datasource configuration info by client
15. rules: the rule that the client takes effect internally contains flowRules, degradeRules, systemRules, authorityRule, paramFlowRule
The followings shows how a service instance accesses the Endpoint:
[source,json,indent=0]
----
{
"blockPage": null,
"appName": "sentinel-example",
"consoleServer": "localhost:8080",
"coldFactor": "3",
"rules": {
"flowRules": [{
"resource": "GET:http://www.taobao.com",
"limitApp": "default",
"grade": 1,
"count": 0.0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}, {
"resource": "/test",
"limitApp": "default",
"grade": 1,
"count": 0.0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}, {
"resource": "/hello",
"limitApp": "default",
"grade": 1,
"count": 1.0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}]
},
"metricsFileCharset": "UTF-8",
"filter": {
"order": -2147483648,
"urlPatterns": ["/*"],
"enabled": true
},
"totalMetricsFileCount": 6,
"datasource": {
"ds1": {
"file": {
"dataType": "json",
"ruleType": "FLOW",
"converterClass": null,
"file": "...",
"charset": "utf-8",
"recommendRefreshMs": 3000,
"bufSize": 1048576
},
"nacos": null,
"zk": null,
"apollo": null,
"redis": null
}
},
"clientIp": "30.5.121.91",
"clientPort": "8719",
"logUsePid": false,
"metricsFileSize": 52428800,
"logDir": "...",
"heartbeatIntervalMs": 10000
}
----
=== Configuration
The following table shows that when there are corresponding bean types in `ApplicationContext`, some actions will be taken:
|===
|Existing Bean Type |Action |Function
|`UrlCleaner`|`WebCallbackManager.setUrlCleaner(urlCleaner)`|Resource cleaning(resource(for example, classify all URLs of /foo/:id to the /foo/* resource))
|`UrlBlockHandler`|`WebCallbackManager.setUrlBlockHandler(urlBlockHandler)`|Customize rate limiting logic
|`RequestOriginParser`|`WebCallbackManager.setRequestOriginParser(requestOriginParser)`|Setting the origin
|===
The following table shows all the configurations of Spring Cloud Alibaba Sentinel:
|===
|Configuration |Description |Default Value
|`spring.application.name` or `project.name`|Project Name Of Sentinel|
|`spring.cloud.sentinel.enabled`|Whether Sentinel automatic configuration takes effect|true
|`spring.cloud.sentinel.eager`|Whether to trigger Sentinel initialization in advance|false
|`spring.cloud.sentinel.transport.port`|Port for the application to interact with Sentinel dashboard. An HTTP Server which uses this port will be started in the application|8719
|`spring.cloud.sentinel.transport.dashboard`|Sentinel dashboard address|
|`spring.cloud.sentinel.transport.heartbeatIntervalMs`|Hearbeat interval between the application and Sentinel dashboard|
|`spring.cloud.sentinel.transport.client-ip`|The client IP of this configuration will be registered to the Sentinel Server side.|
|`spring.cloud.sentinel.filter.order`|Loading order of Servlet Filter. The filter will be constructed in the Starter|Integer.MIN_VALUE
|`spring.cloud.sentinel.filter.url-patterns`|Data type is array. Refers to the collection of Servlet Filter ULR patterns|/*
|`spring.cloud.sentinel.filter.enabled`|Enable to instance CommonFilter|true
|`spring.cloud.sentinel.metric.charset`|metric file character set|UTF-8
|`spring.cloud.sentinel.metric.fileSingleSize`|Sentinel metric single file size|
|`spring.cloud.sentinel.metric.fileTotalCount`|Sentinel metric total file number|
|`spring.cloud.sentinel.log.dir`|Directory of Sentinel log files|
|`spring.cloud.sentinel.log.switch-pid`|If PID is required for Sentinel log file names|false
|`spring.cloud.sentinel.servlet.blockPage`| Customized redirection URL. When rate limited, the request will be redirected to the pre-defined URL |
|`spring.cloud.sentinel.flow.coldFactor`| https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8[ColdFactor] |3
|`spring.cloud.sentinel.scg.fallback.mode`| Response mode after Spring Cloud Gateway circuit break (select `redirect` or `response`) |
|`spring.cloud.sentinel.scg.fallback.redirect`| Spring Cloud Gateway response mode is the redirect URL corresponding to 'redirect' mode |
|`spring.cloud.sentinel.scg.fallback.response-body`| Spring Cloud Gateway response mode is response content corresponding to 'response' mode |
|`spring.cloud.sentinel.scg.fallback.response-status`| Spring Cloud Gateway response mode is the response code corresponding to 'response' mode | 429
|`spring.cloud.sentinel.scg.fallback.content-type`| The Spring Cloud Gateway response mode is the content-type corresponding to the 'response' mode. | application/json
|===
NOTE: These configurations will only take effect in servlet environment. RestTemplate and Feign will not take effect for these configurations.

@ -1,193 +0,0 @@
== Spring Cloud Alibaba Sidecar
`Spring Cloud Alibaba Sidecar` is a Spring Cloud for quick and perfect integration
with * heterogeneous microservices * framework, inspired by
https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-sidecar[Spring
Cloud Netflix Sidecar]currently supported service discovery components:
* Nacos
* Consul
=== Terminology
==== Heterogeneous microservice
Non-spring Cloud applications are referred to as heterogeneous micro-services. Such as your legacy projects, or non-JVM applications.
==== Three meanings of "perfect integration"
* Take advantage of service discovery
* There is load balancing
* with circuit breaker
=== Why or Why not?
==== Why write Alibaba Sidecar?
There are two reasons:
* Spring Cloud subproject 'Spring Cloud Netflix Sidecar'
It is possible to integrate heterogeneous microservices quickly. However, Sidecar only supports the use of Eureka as a service discovery, * if you use other service discovery components you are blinded *.
* *Sidecar is based on Zuul 1.x *, Spring
Cloud has officially stated that Zuul will be phased out in the future. Earlier this year, I gave it to Spring
The Cloud official requested an official implementation based on the Spring Cloud
Gateway's new Sidecar, though officials say there are no plans for it. See: https://github.com/spring-cloud/spring-cloud-gateway/issues/735
Since I didn't, I wrote it myself.
==== Why not use a Service Mesh?
* Currently, Mesh is mainly used in Kubernetes (Istio, Linkerd
2, etc., most of the Kubernetes as the First
Class support, although Istio can also be deployed in non-Kubernetes environments), unlike the current industry, Spring
Cloud applications may not have Service Mesh environments;
* Use Alibaba
Sidecar solves the problem in a single widget (no more than 200 lines of core code) and introduces a complete Mesh scheme, which is a bit like killing eel.
=== principle
* Alibaba
Sidecar registers the IP/ port of heterogeneous micro-services to the service discovery component based on the configured IP and port of heterogeneous micro-services*
.
* Alibaba Sidecar implements * Health Check *, Alibaba
Sidecar periodically checks whether heterogeneous microservices are healthy. If heterogeneous microservices are found to be unhealthy, Alibaba
Sidecar will automatically represent the heterogeneous micro services of Alibaba
Sidecar instance is offline. If the heterogeneous microservice recovers, it automatically goes online. The maximum delay is 30 seconds, see details
`Alibaba SidecarChecker#check.`
=== requirement
* [Must] Your heterogeneous microservice needs to communicate using HTTP. This is not strictly a requirement because of Spring
The Cloud itself is based on HTTP;
* 【 Optional 】 If the microservice is configured with `sidecar.health-check-url`
In this case, your heterogeneous micro service needs to implement health check (can be empty implementation, as long as an endpoint is exposed, return similar
`{"status": "UP"}` is a string).
=== Use an example
* If Nacos is used as a service discovery component, See `spring-cloud-alibaba-examples/spring-cloud-alibaba-sidecar-examples/spring-cloud-alibaba-sidecar-nacos-example` for details
* If you use Consul as a service discovery component, See `spring-cloud-alibaba-examples/spring-cloud-alibaba-sidecar-examples/spring-cloud-alibaba-sidecar-consul-example` for details
==== Sample code (using Nacos service discovery as an example)
* Plus dependence:
+
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sidecar</artifactId>
</dependency>
----
* Write configuration:
+
[source,yaml]
----
server:
port: 8070
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
enabled: true
application:
name: node-service
sidecar:
# IP address of the heterogeneous microservice
ip: 127.0.0.1
# Port of the heterogeneous microservice
port: 8060
# Health check URL for heterogeneous microservices
health-check-url: http://localhost:8060/health.json
management:
endpoint:
health:
show-details: always
----
+
The configuration was simple, registering Alibaba Sidecar with Nacos and adding a few lines of Alibaba
Sidecar configuration.
==== Heterogeneous microservice
I have prepared a simple microservice written in NodeJS.
[source,javascript]
----
var http = require('http');
var url = require("url");
var path = require('path');
// create server
var server = http.createServer(function(req, res) {
// Get the path to the request
var pathname = url.parse(req.url).pathname;
res.writeHead(200, { 'Content-Type' : 'application/json; charset=utf-8' });
// Visit http://localhost:8060/ and {"index":" Welcome to Home page"}
if (pathname === '/') {
res.end(JSON.stringify({ "index" : "Welcome to Home page" }));
}
// Visit http://localhost:8060/health, will return to {" status ":" UP "}
else if (pathname === '/health.json') {
res.end(JSON.stringify({ "status" : "UP" }));
}
// In other cases, 404 is returned
else {
res.end("404");
}
});
// Create a listener and print a log
server.listen(8060, function() {
console.log('listening on localhost:8060');
});
----
==== Test
===== Test 1: Spring Cloud microservices perfectly invoke heterogeneous microservices
Integrate the Ribbon for your Spring Cloud microservice and build `http://node-service/**`
, you can request the heterogeneous micro service `/**`.
Example:
Ribbon requests `http://node-service/` will request `http://localhost:8060/`
And so on.
As for the circuit breaker, normal for your Spring
Just integrate Sentinel, Hystirx and Resilience4J with Cloud microservices.
===== Test 2: Heterogeneous microservices perfectly invoke Spring Cloud microservices
Alibaba Sidecar is based on the Spring Cloud Gateway, and the gateway has its own forwarding capability.
Example:
If you have a Spring Cloud microservice called `spring-cloud-microservice`
Then the NodeJS application only needs to build
`http://localhost:8070/spring-cloud-microservice/**`, Alibaba
Sidecar then forwards the request to `spring-cloud-microservice`s `/**` 。
The Spring Cloud Gateway integrates the Ribbon to realize load balancing. Spring Cloud
Gateway also has a circuit breaker for integrating Sentinel or Hystirx, Resilience4J.
Analysis of advantages and disadvantages of Alibaba Sidecar
Alibaba
The design of Sidecar is basically the same as that of Netfix Sidecar, and the advantages and disadvantages are the same as those of Netfix Sidecar.
Advantages:
* Easy access, a few lines of code to integrate heterogeneous micro-services into the Spring Cloud ecosystem
* Does not hack the original code
Disadvantages:
* You need to deploy an additional Alibaba for each heterogeneous microservice instance you connect to
Sidecar instances, increasing the deployment cost (although this cost is almost negligible in a Kubernetes environment)
Sidecar instances and heterogeneous microservices can be deployed as a Pod));
* When a heterogeneous microservice calls a Spring Cloud microservice, it essentially takes Alibaba
Sidecar When the gateway is in use, the gateway performance deteriorates after layer 1 forwarding.

@ -1,210 +0,0 @@
== Spring Cloud Alibaba Cloud SMS
SMSShort Message Serviceis a messaging service that covers the globe, Alibaba SMS provides convenient, efficient, and intelligent communication capabilities that help businesses quickly contact their customers.
Spring Cloud Alibaba Cloud SMS provide an easier-to-use API for quick access to Alibaba Cloud's SMS service based on Spring Cloud Alibaba SMS.
=== How to Introduce Spring Cloud Alibaba Cloud SMS
If you want to use SMS in your project, please use the starter with the group ID as `com.alibaba.cloud` and the artifact ID as `spring-cloud-starter-alicloud-sms`.
[source,xml]
----
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-sms</artifactId>
</dependency>
----
=== How to use SMS API
==== Configure SMS
Before you start to use Spring Cloud Alibaba Cloud SMS, please add the following configurations in application.properties.
[source,properties]
----
spring.cloud.alicloud.access-key=AK
spring.cloud.alicloud.secret-key=SK
----
access-key and secret-key is the AK/SK of your Alibaba Cloud account. If you dont have one, please register an account first, and log on to https://usercenter.console.aliyun.com/#/manage/ak[Alibaba Cloud AK/SK Management] to get your AccessKey ID and Access Key Secret . If you havent create the AccessKeys, click “Create AccessKey” to create one.
==== Introduce SMS API
The SMS API in Spring Cloud Alicloud SMS is based on Alibaba Cloud SMS SDK. It has a single SMS sending, multiple SMS bulk sending, SMS query, SMS message (SMS receipt message and Upstream SMS message) class operation API.
The following is a simple example of how to use SMS api to send short message:
[source,java]
----
@SpringBootApplication
public class SmsApplication {
@Autowired
private ISmsService smsService;
@RequestMapping("/batch-sms-send.do")
public SendBatchSmsResponse batchsendCheckCode(
@RequestParam(name = "code") String code) {
SendSmsRequest request = new SendSmsRequest();
// Required:the mobile number
request.setPhoneNumbers("152******");
// Required:SMS-SignName-could be found in sms console
request.setSignName("******");
// Required:Template-could be found in sms console
request.setTemplateCode("******");
// Required:The param of sms template.For exmaple, if the template is "Hello,your verification code is ${code}". The param should be like following value
request.setTemplateParam("{\"code\":\"" + code + "\"}");
SendSmsResponse sendSmsResponse ;
try {
sendSmsResponse = smsService.sendSmsRequest(request);
}
catch (ClientException e) {
e.printStackTrace();
sendSmsResponse = new SendSmsResponse();
}
return sendSmsResponse ;
}
public static void main(String[] args) throws URISyntaxException {
SpringApplication.run(SmsApplication.class, args);
}
}
----
Before you send your messages, please https://account.aliyun.com/register/register.htm?spm=5176.8142029.388261.26.e9396d3eaYK2sG&oauth_callback=https%3A%2F%2Fwww.aliyun.com%2F[Register an Alibaba Cloud Account]. If you already have one, please https://dysms.console.aliyun.com/dysms.htm?spm=5176.8195934.1283918..18924183bHPct2&accounttraceid=c8cb4243-3080-4eb1-96b0-1f2316584269#/[Turn on SMS Service].
For more information about SMS , please refer to the SMS official https://help.aliyun.com/document_detail/55284.html?spm=a2c4g.11186623.6.568.715e4f30ZiVkbI[SMS] (SendSms)---JAVA] docs .
NOTE: Due to an issue with the earlier SMS sdk version, if the text message fails to be sent, please delete the line of code that contains the explicit MethodType as POST. If you still have problems, please contact us as soon as possible.
=== The Advanced Features of SMS Api
In order to reduce the cost of learning, the API interface of the Spring Cloud Alicloud SMS package is kept as consistent as the API and Example provided by the official website.
* Batch SMS sending
Refer to the following example to quickly develop a feature with bulk SMS sending. Add the following code in the Controller or create a new Controller:
[source,java]
----
@RequestMapping("/batch-sms-send.do")
public SendBatchSmsResponse batchsendCheckCode(
@RequestParam(name = "code") String code) {
SendBatchSmsRequest request = new SendBatchSmsRequest();
request.setMethod(MethodType.GET);
request.setPhoneNumberJson("[\"177********\",\"130********\"]");
request.setSignNameJson("[\"*******\",\"*******\"]");
request.setTemplateCode("******");
request.setTemplateParamJson(
"[{\"code\":\"" + code + "\"},{\"code\":\"" + code + "\"}]");
SendBatchSmsResponse sendSmsResponse ;
try {
sendSmsResponse = smsService
.sendSmsBatchRequest(request);
return sendSmsResponse;
}
catch (ClientException e) {
e.printStackTrace();
sendSmsResponse = new SendBatchSmsResponse();
}
return sendSmsResponse ;
}
----
NOTE: The MethodType of the request is set to GET, which is somewhat different from the example given by the official website. This is because the inconsistent version of the dependent Alibaba Cloud POP API version causes incompatibility issues, set to GET.
More parameter descriptions can be https://help.aliyun.com/document_detail/66041.html?spm=a2c4g.11186623.6.571.631315e8AauJhP[reference here]
* SMS Query
Refer to the following example to quickly develop a history of sending SMS messages based on a specified number. Add the following code in the Controller or create a new Controller:
[source,java]
----
@RequestMapping("/query.do")
public QuerySendDetailsResponse querySendDetailsResponse(
@RequestParam(name = "tel") String telephone) {
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
request.setPhoneNumber(telephone);
request.setSendDate("20190103");
request.setPageSize(10L);
request.setCurrentPage(1L);
try {
QuerySendDetailsResponse response = smsService.querySendDetails(request);
return response;
}
catch (ClientException e) {
e.printStackTrace();
}
return new QuerySendDetailsResponse();
}
----
More parameter descriptions can be found at https://help.aliyun.com/document_detail/55289.html?spm=a2c4g.11186623.6.569.4f852c78mugEfx[reference here]
* SMS receipt message
By subscribing to the SmsReport SMS status report, you can know the status of each SMS message and whether it knows the status and related information of the terminal user. These efforts have been encapsulated internally by Spring Cloud AliCloud SMS. You only need to complete the following two steps.
1、Configure the queue name for SmsReport in the `application.properties` configuration file (which can also be application.yaml).
.application.properties
----
spring.cloud.alicloud.sms.report-queue-name=Alicom-Queue-********-SmsReport
----
2、Implement the SmsReportMessageListener interface and initialize a Spring Bean.
[source,java]
----
@Component
public class SmsReportMessageListener
implements SmsReportMessageListener {
@Override
public boolean dealMessage(Message message) {
//do something
System.err.println(this.getClass().getName() + "; " + message.toString());
return true;
}
}
----
More message body format for Message can be https://help.aliyun.com/document_detail/55496.html?spm=a2c4g.11186623.6.570.7f792c78rOiWXO[reference here].
* Upstream SMS message
By subscribing to the SmsUp upstream SMS message, you can know the content of the end user replying to the SMS. These efforts have also been packaged by Spring Cloud AliCloud SMS. You only need to complete the following two steps.
1、Configure the queue name for SmsReport in the `application.properties` configuration file (which can also be application.yaml).
.application.properties
[source,properties]
----
spring.cloud.alicloud.sms.up-queue-name=Alicom-Queue-********-SmsUp
----
2、Implement the SmsUpMessageListener interface and initialize a Spring Bean.
[source,java]
----
@Component
public class SmsUpMessageListener
implements org.springframework.cloud.alicloud.sms.SmsUpMessageListener {
@Override
public boolean dealMessage(Message message) {
//do something
System.err.println(this.getClass().getName() + "; " + message.toString());
return true;
}
}
----
More message body format for Message can be https://help.aliyun.com/document_detail/55496.html?spm=a2c4g.11186623.6.570.7f792c78rOiWXO[reference here].

@ -1,34 +0,0 @@
[[spring-cloud-alibaba-reference]]
= Spring Cloud Alibaba Reference Documentation
Jim Fang, Jing Xiao, Mercy Ma, Xiaolong Zuo, Bingting Peng, Yuxin Wang
:doctype: book
:toc:
:toclevels: 4
:source-highlighter: prettify
:numbered:
include::introduction.adoc[]
include::dependency-management.adoc[]
include::nacos-discovery.adoc[]
include::nacos-config.adoc[]
include::sentinel.adoc[]
include::rocketmq.adoc[]
include::ans.adoc[]
include::acm.adoc[]
include::oss.adoc[]
include::schedulerx.adoc[]
include::sms.adoc[]
include::sidecar.adoc[]
include::graalvm.adoc[]

@ -188,10 +188,9 @@ SecretKey|spring.cloud.nacos.config.secret-key||
集群服务名|spring.cloud.nacos.config.cluster-name||
### Native Image构建
请参考`spring-cloud-alibaba-docs`中的`graalvm.adoc`文档
请参考 Spring Cloud Alibaba 官网中的 [Graalvm 快速开始](https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/user-guide/graalvm/quick-start)7
#### 更多介绍
Nacos为用户提供包括动态服务发现配置管理服务管理等服务基础设施帮助用户更灵活更轻松地构建交付和管理他们的微服务平台基于Nacos, 用户可以更快速的构建以“服务”为中心的现代云原生应用。Nacos可以和Spring Cloud、Kubernetes/CNCF、Dubbo 等微服务生态无缝融合,为用户提供更卓越的体验。更多 Nacos 相关的信息,请参考 [Nacos 项目](https://github.com/alibaba/Nacos)。
如果您对 Spring Cloud Nacos Config Starter 有任何建议或想法,欢迎在 issue 中或者通过其他社区渠道向我们提出。

@ -196,7 +196,7 @@ refresh|spring.cloud.nacos.config.refresh.enabled|true|enable auto refresh
cluster name|spring.cloud.nacos.config.cluster-name||
### Build Native Image
Please refer to `graalvm.adoc` document in `spring-cloud-alibaba-docs`
Please refer to [Graalvm Quick Start](https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/user-guide/graalvm/quick-start) in the Spring Cloud Alibaba official website.
#### More introduction
[Nacos](https://github.com/alibaba/Nacos) is committed to help you discover, configure, and manage your microservices. It provides a set of simple and useful features enabling you to realize dynamic service discovery, service configuration, service metadata and traffic management.

Loading…
Cancel
Save