mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
#734 -> update maven coordinates
This commit is contained in:
@@ -1,174 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud ACM
|
||||
|
||||
Spring Cloud AliCloud ACM 是阿里云提供的商业版应用配置管理(Application Configuration Management) 产品 在 Spring Cloud 应用侧的客户端实现,且目前完全免费。
|
||||
|
||||
Spring Cloud AliCloud ACM 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。
|
||||
|
||||
=== 如何引入 Spring Cloud AliCloud ACM
|
||||
|
||||
如果要在您的项目中引入 ACM,使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-acm` 的 starter。
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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,94 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud ANS
|
||||
|
||||
ANS(Application Naming Service) 是隶属于阿里云 EDAS 产品的组件, Spring Cloud AliCloud ANS 提供了 Spring Cloud 规范下商业版的服务注册与发现,可以让用户方便的在本地开发,同时也可以运行在云环境里。
|
||||
|
||||
=== 如何引入 Spring Cloud AliCloud ANS
|
||||
|
||||
如果要在您的项目中引入 ANS,使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-ans` 的 starter。
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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,42 +0,0 @@
|
||||
== 依赖管理
|
||||
|
||||
Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本。
|
||||
|
||||
### Spring Cloud Alibaba Bill of Materials (BOM)
|
||||
|
||||
如果您是 Maven Central 用户,请将我们的 BOM 添加到您的 pom.xml 中的 <dependencyManagement> 部分。 这将允许您省略任何Maven依赖项的版本,而是将版本控制委派给BOM。
|
||||
|
||||
```xml
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
```
|
||||
|
||||
### Spring Snapshots Maven Repository
|
||||
|
||||
如果要使用最新的 BUILD-SNAPSHOT 版本,请在 pom.xml 中添加 Spring Snapshot Repository,注意:BUILD-SNAPSHOT随时可能更新:
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring SnapShots</name>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
|
||||
举个例子, 0.2.0.BUILD-SNAPSHOT 版本就在这个仓库中可用。
|
||||
|
||||
|
@@ -1,116 +0,0 @@
|
||||
= SCA Nacos Config 共享配置方案设计
|
||||
|
||||
随着社区的回馈,发现 Spring Cloud Alibaba Nacos Config Starter 目前不能完美的来支持多个应用间的一些共享配置。
|
||||
在实际的业务场景中应用和共享配置间的关系可能如下图所示:
|
||||
|
||||
image::http://edas.oss-cn-hangzhou.aliyuncs.com/sca/sca_shared_01.png[]
|
||||
|
||||
* 从单个应用的角度来看: 应用可能会有多套(develop/beta/product)发布环境,多套发布环境之间有不同的基础配置,例如数据库。
|
||||
* 从多个应用的角度来看:多个应用间可能会有一些共享通用的配置,比如多个应用之间共用一套zookeeper集群。
|
||||
|
||||
目前 SCA Nacos Config 可以灵活的支持单个应用间在多套环境可灵活的切换,但是在多个应用间共享一些通用的配置支持的还不是很完美。
|
||||
本方案设计的目标就是来解决这个问题。目前有三种设计方案,分别是:
|
||||
|
||||
* 新增一个应用分组的配置,分组命名的格式是 通过域名的命名方式,来自动的生成共享配置的 Data Id。
|
||||
* 自定义命名的方式来命名 Data Id 。
|
||||
* 通过类似面向对象的方式自定义配置(相对于第二种的升级版)。
|
||||
|
||||
下面分别来分析三种方案的具体实现和优缺点。
|
||||
|
||||
== 基于域名的配置方式给应用分组
|
||||
|
||||
通过一个配置参数(例如:${spring.application.group}) 来指明当前应用所属的分组(或者说所属的域)。
|
||||
例如我有两个应用分别为Order_Application和Auth_Application,给这两个应用配置的分组名(域)是:
|
||||
|
||||
.bootstrap.properties
|
||||
----
|
||||
spring.application.group=com.alibaba.aliware.edas
|
||||
----
|
||||
|
||||
那对于Spring Cloud Alibaba Nacos Config 来说,多个应用可以属于 com.alibaba 这个应用分组(域),也可以属于
|
||||
com.alibaba.aliware 这个应用分组(域),当然也可以属于 com.alibaba.aliware.edas 这个应用分组(域)。
|
||||
罗里吧嗦了这么多,目的就是 Data Id 通过以这个分组(域)来命名,从而实现多个应用间在某个分组(域)下的共享配置。如下图所示:
|
||||
|
||||
image::http://edas.oss-cn-hangzhou.aliyuncs.com/sca/sca_shared_02.png[]
|
||||
|
||||
以这种方式来实现多个应用间的配置共享,可以看出他具有天然的局限性。
|
||||
|
||||
* 受到 ${spring.application.group }配置的影响,Data Id 的表现力是非常有限的(当然85%的场景应该够用了)。
|
||||
** 一方面是Data Id 的命名个数受到了限制。
|
||||
** 另一方面如果两个应用的 file-extension 不一致(一个是properties,一个是yaml),那这个时候共享配置的Data Id 必须同时要含有 properties 和 yaml 为扩展名的配置。
|
||||
** Data Id 的命名也受到了 ${spring.application.group } 配置的束缚。
|
||||
|
||||
* 学习成本偏高(当然还是可以学会的)。学习成本偏高体现在:
|
||||
** 要知道Data Id 的命名规则,才能在项目实施过程中对 Data Id 的命名运用自如。
|
||||
** 此外对于域名命名的层次个数也不太好把握。少了的话,担心dataid的个数不够用,多了的话看上去有显得的比较冗余。
|
||||
** 还需要学习并理解这里配置的优先级,不然在程序中有可能就会拿到意想不到的配置。
|
||||
|
||||
* 易出错(当然是可以克服的)。对于多级应用分组的配置共享,这个时候Data Id 的命名要格外注意了。注意他们的层次关系,Data Id 书写时不要张冠李戴。
|
||||
|
||||
* 实现起来稍微复杂
|
||||
|
||||
当然他的好处也非常明显,当你理解了他背后的设计理念时,这个共享配置的层次也非常明显。因为层次的关系天然依托于域名的层次关系。
|
||||
|
||||
== 自定义的方式来命名 Data Id
|
||||
|
||||
这种方式实现简单易懂,即 SCA Nacos Config 会新增加一个配置,用来配置可实现共享配置所有的 Data Id。如下所示:
|
||||
|
||||
.bootstrap.properties
|
||||
----
|
||||
spring.cloud.nacos.shared.dataids=global.yaml,app-common.yaml,app-local-common.yaml
|
||||
----
|
||||
|
||||
NOTE: 为了尽可能的和Nacos使用方式(即Data Id 是一个带有额外文件扩展名的)保持一致,这里配置的Data Id 是一定需要带上文件扩展名的。
|
||||
|
||||
这个时候两个应用(或多个应用)之间共享配置的 Data Id 关系如下图所示:
|
||||
|
||||
image::http://edas.oss-cn-hangzhou.aliyuncs.com/sca/sca_shared_03.png[]
|
||||
|
||||
Spring Boot 提倡约定大于配置。当使用这种方式来实现应用间的共享配置时,我们也继承了Spring Boot的这个优良传统,多个共享配置间的一个优先级的关系我们约定:按照配置出现的先后顺序,即后面的优先级要高于前面的。
|
||||
这种方式的优点在于:
|
||||
|
||||
* dataid的命名方式完全交给业务方本身,不受 SCA Nacos Config Starter 实现的束缚。
|
||||
* dataid的命名方式既可以参考第一种方式来命名,又可以充分的发挥主观能动性,结合自己实际的业务给dataid命名。
|
||||
* 减少了多个应用间如果file-extension不一致,为每个 file-extension 多加这么一个配置的麻烦。
|
||||
* 当使用这种方式时,不会为这些共享配置强制绑定一个 file-extenson,即可以直接在我们暴露出来的一个变量中 dataid以file-extension 结尾。如果没有显示的说明,这个时候就会以file-extenson为准。
|
||||
|
||||
当然这种方案的缺点在于扩展性不强。即如果对于某个共享配置需要做额外的配置,例如额外配置Group/是否需要刷新/是否需要从本地缓存加载等等。因此为了应对这种类型的场景,小组内讨论出了第三种方案。
|
||||
|
||||
== 通过类似面向对象方式的自定义配置
|
||||
|
||||
说明:Spring 可以支持在加了 ConfigurationProperties 注解配置类的内部某个对象实例来注入应用中的一些配置。
|
||||
这种使用方式查了一下官方和网络上没有一个大的标题总结,结合这种方式很像给某个实例中的字段赋值,所以这里先暂时取名:
|
||||
类似面向对象方式的自定义配置(有更好能够形象的标明其含义的命名可以在下面留下评论-_-)。
|
||||
|
||||
这种方案沿用了第二种设计方案的优点,同时又弥补了第二种方案的不足。我们通过内部定义一个对象,来支持一些灵活的扩展配置。
|
||||
我们给这个对象可以预留一些可扩展的配置字段。例如:
|
||||
|
||||
.Config.java
|
||||
----
|
||||
public class Config{
|
||||
private String dataId;
|
||||
private String group = "DEFAULT_GROUP";
|
||||
private Boolean refresh = false;
|
||||
//.....后期可能还有其他的一些配置
|
||||
|
||||
//省略 set/get 方法
|
||||
}
|
||||
----
|
||||
|
||||
最终在实现时是可以支持以list的方式来配置其值。如下是两个扩展配置的实例:
|
||||
|
||||
.bootstrap.properties
|
||||
----
|
||||
spring.cloud.nacos.config.ext-config[0].data-id=global-shared.properties # group 和referesh 使用默认值
|
||||
spring.cloud.nacos.config.ext-config[1].data-id=app-common.properties
|
||||
spring.cloud.nacos.config.ext-config[1].group=DEVELOP_GROUP #配置自定义所在的组
|
||||
spring.cloud.nacos.config.ext-config[1].refresh=true #需要刷新
|
||||
----
|
||||
|
||||
NOTE: 为了尽可能的和Nacos使用方式(即data id是一个带有额外文件扩展名的)保持一致,这里配置的dataid是一定需要带上文件扩展名的。
|
||||
|
||||
== 最终的实现
|
||||
|
||||
SCA Nacos Config 在第二种方案和第三种方案的实现上是并存的。如果你觉得第三种方案配置的比较麻烦,同时第二种方案就可以满足你的需求,这个时候就可以选择第二种方案。
|
||||
如果你需外可读性好、层级感比较明显、后期的扩展性更强,那这个时候第三种方案也是OK的。
|
||||
|
@@ -1,331 +0,0 @@
|
||||
== Spring Cloud Alibaba Nacos Config
|
||||
|
||||
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。
|
||||
|
||||
Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。
|
||||
|
||||
=== 快速开始
|
||||
|
||||
===== Nacos 服务端初始化
|
||||
|
||||
1、启动Nacos Server。启动方式可见 https://nacos.io/zh-cn/docs/quick-start.html[Nacos 官网]
|
||||
|
||||
2、启动好Nacos之后,在Nacos添加如下的配置:
|
||||
|
||||
[source,subs="normal"]
|
||||
----
|
||||
Data ID: nacos-config.properties
|
||||
|
||||
Group : DEFAULT_GROUP
|
||||
|
||||
配置格式: Properties
|
||||
|
||||
配置内容: user.name=nacos-config-properties
|
||||
user.age=90
|
||||
----
|
||||
|
||||
NOTE: 注意dataid是以 properties(默认的文件扩展名方式)为扩展名。
|
||||
|
||||
===== 客户端使用方式
|
||||
|
||||
如果要在您的项目中使用 Nacos 来实现应用的外部化配置,使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-nacos-config` 的 starter。
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
现在就可以创建一个标准的 Spring Boot 应用。
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
在运行此 Example 之前, 必须使用 bootstrap.properties 配置文件来配置Nacos Server 地址,例如:
|
||||
|
||||
.bootstrap.properties
|
||||
[source,properties]
|
||||
----
|
||||
spring.application.name=nacos-config
|
||||
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
|
||||
----
|
||||
|
||||
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.ProviderApplication : Started ProviderApplication in 14.645 seconds (JVM running for 15.139)
|
||||
user name :nacos-config-properties; age: 90
|
||||
2018-11-02 14:24:51.688 INFO 32700 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a8c5e74: startup date [Fri Nov 02 14:24:51 CST 2018]; root of context hierarchy
|
||||
2018-11
|
||||
----
|
||||
|
||||
=== 基于 dataid 为 yaml 的文件扩展名配置方式
|
||||
|
||||
spring-cloud-starter-alibaba-nacos-config 对于 yaml 格式也是完美支持的。这个时候只需要完成以下两步:
|
||||
|
||||
1、在应用的 bootstrap.properties 配置文件中显示的声明 dataid 文件扩展名。如下所示
|
||||
|
||||
.bootstrap.properties
|
||||
[source,yaml]
|
||||
----
|
||||
spring.cloud.nacos.config.file-extension=yaml
|
||||
----
|
||||
|
||||
2、在 Nacos 的控制台新增一个dataid为yaml为扩展名的配置,如下所示:
|
||||
|
||||
[source,subs="normal"]
|
||||
----
|
||||
Data ID: nacos-config.yaml
|
||||
|
||||
Group : DEFAULT_GROUP
|
||||
|
||||
配置格式: YAML
|
||||
|
||||
配置内容: user.name: nacos-config-yaml
|
||||
user.age: 68
|
||||
----
|
||||
|
||||
这两步完成后,重启测试程序,可以看到如下输出结果。
|
||||
|
||||
[source,subs="normal"]
|
||||
----
|
||||
2018-11-02 14:59:00.484 INFO 32928 --- [main] c.a.demo.provider.ProviderApplication:Started ProviderApplication in 14.183 seconds (JVM running for 14.671)
|
||||
user name :nacos-config-yaml; age: 68
|
||||
2018-11-02 14:59:00.529 INFO 32928 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@265a478e: startup date [Fri Nov 02 14:59:00 CST 2018]; root of context hierarchy
|
||||
----
|
||||
|
||||
=== 支持配置的动态更新
|
||||
|
||||
spring-cloud-starter-alibaba-nacos-config 也支持配置的动态更新,启动 Spring Boot 应用测试的代码如下:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@SpringBootApplication
|
||||
public class ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.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粒度的配置
|
||||
|
||||
spring-cloud-starter-alibaba-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 ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.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 的 Namespace 的概念, https://nacos.io/zh-cn/docs/concepts.html[Nacos 概念]
|
||||
|
||||
[quote]
|
||||
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
|
||||
|
||||
在没有明确指定 `${spring.cloud.nacos.config.namespace}` 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespae。如果需要使用自定义的命名空间,可以通过以下配置来实现:
|
||||
[source,properties]
|
||||
----
|
||||
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
|
||||
----
|
||||
|
||||
NOTE: 该配置必须放在 bootstrap.properties 文件中。此外 `spring.cloud.nacos.config.namespace` 的值是 namespace 对应的 id,id 值可以在 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 配置
|
||||
|
||||
Spring Cloud Alibaba Nacos Config 从 0.2.1 版本后,可支持自定义 Data Id 的配置。关于这部分详细的设计可参考 https://github.com/spring-cloud-incubator/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 的值也必须明确给出文件扩展名。
|
||||
|
||||
=== 配置的优先级
|
||||
|
||||
Spring Cloud Alibaba 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
|
@@ -1,297 +0,0 @@
|
||||
== Spring Cloud Alibaba Nacos Discovery
|
||||
|
||||
该项目通过自动配置以及其他 Spring 编程模型的习惯用法为 Spring Boot 应用程序在服务注册与发现方面提供和 Nacos 的无缝集成。
|
||||
通过一些简单的注解,您可以快速来注册一个服务,并使用经过双十一考验的 Nacos 组件来作为大规模分布式系统的服务注册中心。
|
||||
|
||||
=== 服务注册发现: Nacos Discovery Starter
|
||||
|
||||
服务发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于
|
||||
服务的动态扩缩容。Nacos Discovery Starter 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos
|
||||
Discovery Starter 也将服务实例自身的一些元数据信息-例如 host,port,健康检查URL,主页等-注册到 Nacos 。Nacos 的获取和启动方式可以参考 https://nacos.io/zh-cn/docs/quick-start.html[Nacos 官网]。
|
||||
|
||||
==== 如何引入 Nacos Discovery Starter
|
||||
|
||||
如果要在您的项目中使用 Nacos 来实现服务发现,使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-nacos-discovery` 的 starter。
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
==== 启动一个 Provider 应用
|
||||
|
||||
以下步骤向您展示了如何将一个服务注册到 Nacos。
|
||||
|
||||
1. 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>org.springframework.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>org.springframework.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>
|
||||
----
|
||||
|
||||
2. application.properties 配置。一些关于 Nacos 基本的配置也必须在 application.properties(也可以是application.yaml)配置,如下所示:
|
||||
application.properties
|
||||
[source,properties]
|
||||
----
|
||||
server.port=8081
|
||||
spring.application.name=nacos-producer
|
||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||
management.endpoints.web.exposure.include=*
|
||||
----
|
||||
|
||||
|
||||
NOTE: 如果不想使用 Nacos 作为您的服务注册与发现,可以将 `spring.cloud.nacos.discovery` 设置为 `false`。
|
||||
|
||||
3. 启动 Provider 示例。如下所示:
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class NacosProviderDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(NacosProducerDemoApplication.class, args);
|
||||
}
|
||||
|
||||
@RestController
|
||||
public class EchoController {
|
||||
@GetMapping(value = "/echo/{string}")
|
||||
public String echo(@PathVariable String string) {
|
||||
return "Hello Nacos Discovery " + string;
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
这个时候你就可以在 Nacos的控制台上看到注册上来的服务信息了。
|
||||
|
||||
NOTE: 再启动 Provider 应用之前 请先将 Nacos 服务启动。具体启动方式可参考 https://nacos.io/zh-cn/docs/quick-start.html[Nacos 官网]。
|
||||
|
||||
=== 服务的 EndPoint
|
||||
|
||||
spring-cloud-starter-alibaba-nacos-discovery 在实现的时候提供了一个EndPoint,EndPoint的访问地址为 `http://ip:port/actuator/nacos-discovery`。
|
||||
EndPoint 的信息主要提供了两类:
|
||||
|
||||
1、subscribe: 显示了当前有哪些服务订阅者
|
||||
2、NacosDiscoveryProperties: 显示了当前服务实例关于 Nacos 的基础配置
|
||||
|
||||
一个服务实例访问 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-producer",
|
||||
"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": ""
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
=== 启动一个 Consumer 应用
|
||||
|
||||
Consumer 的应用可能还没像启动一个 Provider 应用那么简单。因为在 Consumer 端需要去调用 Provider 端提供的REST 服务。例子中我们使用最原始的一种方式,
|
||||
即显示的使用 LoadBalanceClient 和 RestTemolate 结合的方式来访问。
|
||||
pom.xml 和 application.properties 的配置可以参考 1.2 小结。启动一个 Consumer应用的示例代码如下所示:
|
||||
|
||||
NOTE: 通过带有负载均衡的RestTemplate 和 FeignClient 也是可以访问的。
|
||||
|
||||
[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(){
|
||||
//使用 LoadBalanceClient 和 RestTemolate 结合的方式来访问
|
||||
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 Starter 更多的配置项信息
|
||||
|
||||
更多关于 spring-cloud-starter-alibaba-nacos-discovery 的 starter 配置项如下所示:
|
||||
|
||||
:frame: topbot
|
||||
[width="60%",options="header"]
|
||||
|====
|
||||
^|配置项 ^|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`|`无`|`优先级最高`
|
||||
|`注册的端口`|`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.enpoint`|`UTF-8`|`地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址`
|
||||
|`是否集成Ribbon`|`ribbon.nacos.enabled`|`true`|`一般都设置成true即可`
|
||||
|====
|
||||
|
@@ -1,140 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud OSS
|
||||
|
||||
OSS(Object 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>org.springframework.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,278 +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>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
或者可以使用 Spring Cloud Stream RocketMQ Starter:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Spring Cloud Alibaba RocketMQ Binder 实现
|
||||
|
||||
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("DELAY", "1");
|
||||
Message message = builder.build();
|
||||
output().send(message);
|
||||
```
|
||||
|
||||
### 配置选项
|
||||
|
||||
#### RocketMQ Binder Properties
|
||||
|
||||
spring.cloud.stream.rocketmq.binder.name-server::
|
||||
RocketMQ NameServer 地址。
|
||||
+
|
||||
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 相关的配置。
|
||||
|
||||
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`.
|
@@ -1,114 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud SchedulerX
|
||||
|
||||
SchedulerX(分布式任务调度) 是隶属于阿里云EDAS产品的组件, Spring Cloud AliCloud SchedulerX 提供了在Spring Cloud的配置规范下,分布式任务调度的功能支持。SchedulerX可提供秒级、精准、高可靠、高可用的定时任务调度服务,并支持多种类型的任务调度,如简单单机任务、简单多机任务、脚本任务以及网格任务。
|
||||
|
||||
=== 如何引入 Spring Cloud AliCloud SchedulerX
|
||||
|
||||
如果要在您的项目中引入 SchedulerX,使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-schedulerX` 的 starter。
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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,285 +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 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-sentinel` 的 starter。
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.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注解支持]。
|
||||
|
||||
##### 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控制台]
|
||||
|
||||
### Feign 支持
|
||||
|
||||
Sentinel 适配了 https://github.com/OpenFeign/feign[Feign] 组件。如果想使用,除了引入 `sentinel-starter` 的依赖外还需要 2 个步骤:
|
||||
|
||||
* 配置文件打开 sentinel 对 feign 的支持:`feign.sentinel.enabled=true`
|
||||
* 加入 `feign 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 {
|
||||
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
|
||||
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 限流的资源规则提供两种粒度:
|
||||
|
||||
* `schema://host:port/path`:协议、主机、端口和路径
|
||||
|
||||
* `schema://host:port`:协议、主机和端口
|
||||
|
||||
NOTE: 以 `https://www.taobao.com/test` 这个 url 为例。对应的资源名有两种粒度,分别是 `https://www.taobao.com` 以及 `https://www.taobao.com/test`
|
||||
|
||||
### 动态数据源支持
|
||||
|
||||
`SentinelProperties` 内部提供了 `TreeMap` 类型的 `datasource` 属性用于配置数据源信息。
|
||||
|
||||
比如配置 4 个数据源:
|
||||
|
||||
```
|
||||
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=localhost:8848
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.groupId=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.ds5.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`)。
|
||||
|
||||
如果数据源生效并且规则成功加载,控制台会打印类似如下信息:
|
||||
|
||||
```
|
||||
[Sentinel Starter] DataSource ds1-sentinel-file-datasource load 3 DegradeRule
|
||||
[Sentinel Starter] DataSource ds2-sentinel-nacos-datasource load 2 FlowRule
|
||||
```
|
||||
|
||||
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[动态规则扩展]
|
||||
|
||||
### Endpoint 支持
|
||||
|
||||
在使用 Endpoint 特性之前需要在 Maven 中添加 `spring-boot-starter-actuator` 依赖,并在配置中允许 Endpoints 的访问。
|
||||
|
||||
* Spring Boot 1.x 中添加配置 `management.security.enabled=false`。暴露的 endpoint 路径为 `/sentinel`
|
||||
* Spring Boot 2.x 中添加配置 `management.endpoints.web.exposure.include=*`。暴露的 endpoint 路径为 `/actuator/sentinel`
|
||||
|
||||
Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
|
||||
|
||||
### More
|
||||
|
||||
下表显示当应用的 `ApplicationContext` 中存在对应的Bean的类型时,会进行的一些操作:
|
||||
|
||||
:frame: topbot
|
||||
[width="60%",options="header"]
|
||||
|====
|
||||
^|存在Bean的类型 ^|操作 ^|作用
|
||||
|`UrlCleaner`|`WebCallbackManager.setUrlCleaner(urlCleaner)`|资源清理(资源(比如将满足 /foo/:id 的 URL 都归到 /foo/* 资源下))
|
||||
|`UrlBlockHandler`|`WebCallbackManager.setUrlBlockHandler(urlBlockHandler)`|自定义限流处理逻辑
|
||||
|`RequestOriginParser`|`WebCallbackManager.setRequestOriginParser(requestOriginParser)`|设置来源信息
|
||||
|====
|
||||
|
||||
下表显示 Spring Cloud Alibaba Sentinel 的所有配置信息:
|
||||
|
||||
:frame: topbot
|
||||
[width="60%",options="header"]
|
||||
|====
|
||||
^|配置项 ^|含义 ^|默认值
|
||||
|`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|
|
||||
|`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
|
||||
|====
|
||||
|
||||
NOTE: 请注意。这些配置只有在 Servlet 环境下才会生效,RestTemplate 和 Feign 针对这些配置都无法生效
|
@@ -1,234 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud SMS
|
||||
|
||||
短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。 Spring Cloud AliCloud SMS 实现了与 SMS 的简单集成,提供更为简单易用的 API,可以基于 Spring Cloud Alibaba SMS 来快速的接入阿里云的 SMS 服务。
|
||||
|
||||
=== 如何引入 Spring Cloud AliCloud SMS
|
||||
|
||||
如果要在您的项目中引入 SMS,使用 group ID 为 `org.springframework.cloud` 和 artifact ID 为 `spring-cloud-starter-alicloud-sms` 的 starter。
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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;
|
||||
|
||||
@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 中或者新建一个 Controller 新增如下代码:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@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 中或者新建一个 Controller 新增如下代码:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@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
|
||||
----
|
||||
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 参考文档
|
||||
xiaojing; xiaolongzuo; jim fang; bingting peng; wangyuxin
|
||||
:doctype: book
|
||||
:toc:
|
||||
:toclevels: 4
|
||||
:source-highlighter: prettify
|
||||
:numbered:
|
||||
|
||||
== 介绍
|
||||
|
||||
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
|
||||
|
||||
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
|
||||
|
||||
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[]
|
||||
|
||||
|
@@ -1,176 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud ACM
|
||||
|
||||
Spring Cloud Alibaba Cloud ACM is an implementation of the commercial product Application Configuration Management(ACM) in the client side of Spring Cloud, and is free of charge.
|
||||
|
||||
Spring Cloud Alibaba Cloud ACM is an alternative solution for Config Server and Client. The concepts on the client and server have the same abstractions with Spring Environment and PropertySource. In special Bootstrap phases, configurations are loaded to the Spring environment. During the application lifecycle from development, deployment, test to production, you can manage the configurations across all the environments, and make sure that all information required for application migration is ready when needed.
|
||||
|
||||
=== 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 `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alicloud-acm`.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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,94 +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.
|
||||
|
||||
=== 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 `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alicloud-ans`.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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 weright 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 haven’t 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,38 +0,0 @@
|
||||
== Dependency Management
|
||||
|
||||
### Spring Cloud Alibaba Bill of Materials (BOM)
|
||||
|
||||
If you’re 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>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
```
|
||||
|
||||
### Spring Snapshots Maven Repository
|
||||
|
||||
If you want to use the latest BUILD-SNAPSHOT version, add Spring Snapshot Repository in pom.xml , Attention: BUILD-SNAPSHOT may be updated in any time:
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring SnapShots</name>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
|
||||
For example, the 0.2.0.BUILD-SNAPSHOT is available from this repository.
|
@@ -1,321 +0,0 @@
|
||||
== Spring Cloud Alibaba Nacos Config
|
||||
|
||||
Nacos provides key/value storage of configurations and other metadata as well as server and client support for externalized configurations in distributed systems. With Spring Cloud Alibaba Nacos Config, you can manage externalized configurations of your Spring Cloud applications in the Nacos Server.
|
||||
|
||||
Spring Cloud Alibaba Nacos Config is an alternative solution for Config Server and Client. The concepts on the client and server have the same abstractions with Spring Environment and PropertySource. In special Bootstrap phases, configurations are loaded to the Spring environment. During the application lifecycle from development, deployment, test to production, you can manage the configurations across all the environments, and make sure that all information required for application migration is ready when needed.
|
||||
|
||||
=== Quickstart
|
||||
|
||||
===== Initialize Nacos Server
|
||||
|
||||
1. Start Nacos Server. Refer to https://nacos.io/zh-cn/docs/quick-start.html[Nacos Documentation] for details about how to start the Nacos server.
|
||||
|
||||
2. Add the following configurations in Nacos:
|
||||
|
||||
[source,subs="normal"]
|
||||
----
|
||||
Data ID: nacos-config.properties
|
||||
|
||||
Group : DEFAULT_GROUP
|
||||
|
||||
Configuration format: Properties
|
||||
|
||||
Configuration content: user.name=nacos-config-properties
|
||||
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 `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alibaba-nacos-config`.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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 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);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Before running this example, we need to configure the address of the Nacos server in bootstrap.properties. For example:
|
||||
|
||||
.bootstrap.properties
|
||||
[source,properties]
|
||||
----
|
||||
spring.application.name=nacos-config
|
||||
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
|
||||
----
|
||||
|
||||
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.ProviderApplication : Started ProviderApplication in 14.645 seconds (JVM running for 15.139)
|
||||
user name :nacos-config-properties; age: 90
|
||||
2018-11-02 14:24:51.688 INFO 32700 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a8c5e74: startup date [Fri Nov 02 14:24:51 CST 2018]; root of context hierarchy
|
||||
2018-11
|
||||
----
|
||||
|
||||
=== Add Configurations with DataId in YAML Format
|
||||
|
||||
spring-cloud-starter-alibaba-nacos-config supports yaml format as well. You only need to complete the following 2 steps.
|
||||
|
||||
1. In the bootstrap.properties file, add the following line to claim that the format of dataid is yaml. As follows:
|
||||
|
||||
.bootstrap.properties
|
||||
[source,yaml]
|
||||
----
|
||||
spring.cloud.nacos.config.file-extension=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: nacos-config-yaml
|
||||
user.age: 68
|
||||
----
|
||||
|
||||
After completing the preivous two steps, restart the testing program and you will see the following result.
|
||||
|
||||
[source,subs="normal"]
|
||||
----
|
||||
2018-11-02 14:59:00.484 INFO 32928 --- [main] c.a.demo.provider.ProviderApplication:Started ProviderApplication in 14.183 seconds (JVM running for 14.671)
|
||||
user name :nacos-config-yaml; age: 68
|
||||
2018-11-02 14:59:00.529 INFO 32928 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@265a478e: startup date [Fri Nov 02 14:59:00 CST 2018]; root of context hierarchy
|
||||
----
|
||||
|
||||
=== Support Dynamic Configuration Udpates
|
||||
|
||||
spring-cloud-starter-alibaba-nacos-config also supports dynamic configuration updates. The code for starting Spring Boot application testing is as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@SpringBootApplication
|
||||
public class ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.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 spring-cloud-starter-alibaba-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 ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.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/spring-cloud-incubator/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`.
|
||||
It’s 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.
|
@@ -1,296 +0,0 @@
|
||||
== Spring Cloud Alibaba Nacos Discovery
|
||||
|
||||
This project provides seamless integration with Nacos for Spring Boot applications in terms of service registration and discovery through automatic configurations and other standard usages of the Spring programming model.
|
||||
Nacos has endured the tough tests of the Double 11 Shopping festivals for years. By adding a few simple annotations, you can register a service quickly and use Nacos as the service registration center for a large scale distributed system.
|
||||
|
||||
=== Service Registration and Discovery: Nacos Discovery Starter
|
||||
|
||||
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 Starter 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 Starter 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 Starter
|
||||
|
||||
please use the starter with the group ID as `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alibaba-nacos-discovery`.
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
==== Start a Provider Application
|
||||
|
||||
The following sample illustrates how to register a service to Nacos.
|
||||
|
||||
1. Configuration of pom.xml The following is a complete example of 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>org.springframework.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>org.springframework.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>
|
||||
----
|
||||
|
||||
2. 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-producer
|
||||
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`.
|
||||
|
||||
3. 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(NacosProducerDemoApplication.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.
|
||||
|
||||
=== Service EndPoint
|
||||
|
||||
spring-cloud-starter-alibaba-nacos-discovery provides an EndPoint, and the address is `http://ip:port/actuator/nacos-discovery`.
|
||||
The EndPoint mainly provides two types of information:
|
||||
|
||||
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-producer",
|
||||
"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": ""
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
=== 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 RestTemolate 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 RestTemolate
|
||||
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:
|
||||
|
||||
Address:http://127.0.0.1:8082/echo/app-name
|
||||
Access result: Hello Nacos Discovery nacos-consumer
|
||||
|
||||
=== More Information about Nacos Starter Configurations
|
||||
|
||||
The following shows the other configurations of the starter of spring-cloud-starter-alibaba-nacos-discovery:
|
||||
|
||||
:frame: topbot
|
||||
[width="60%",options="header"]
|
||||
|====
|
||||
^|Configuration ^|Key ^|Default Value ^|Description
|
||||
|`Server address`|`spring.cloud.nacos.discovery.server-addr`|`No default value`|`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`|`No default value`|`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`|`No default value`|`Highest priority`
|
||||
|`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`|`No default value`|`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`|`No default value`|`Alibaba Cloud account`
|
||||
|`SecretKey`|`spring.cloud.nacos.discovery.secret-key`|`No default value`|`Alibaba Cloud account accesskey`
|
||||
|`Metadata`|`spring.cloud.nacos.discovery.metadata`|`No default value`|`You can define some of the metadata for your services in the Map format`
|
||||
|`Log file name`|`spring.cloud.nacos.discovery.log-name`|`No default value`|
|
||||
|`Endpoint`|`spring.cloud.nacos.discovery.enpoint`|`UTF-8`|`The domain name of a certain service in a specific region. You can retrieve the server address dynamically with this domain name`
|
||||
|`Integrate Ribbon or not`|`ribbon.nacos.enabled`|`true`|`Set to true in most cases`
|
||||
|====
|
||||
|
@@ -1,157 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud OSS
|
||||
|
||||
OSS(Object Storage Service)is 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
|
||||
|
||||
We’ve released Spring Cloud Alibaba version 0.2.1. You will need to add dependency management POM first.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.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>org.springframework.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 don’t 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 haven’t 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,277 +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 sulotions, financial settlements, telecommunication, e-commerce, logistics, marketing, social media, instant messaging, mobile applications, mobile games, vedios, 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 successfuly 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 let’s 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>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Alternatively, you can also use the Spring Cloud Stream RocketMQ Starter:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### How Spring Cloud Alibaba RocketMQ Binder Works
|
||||
|
||||
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("DELAY", "1");
|
||||
Message message = builder.build();
|
||||
output().send(message);
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
#### RocketMQ Binder Properties
|
||||
|
||||
spring.cloud.stream.rocketmq.binder.name-server::
|
||||
The name server of RocketMQ Server.
|
||||
+
|
||||
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`.
|
||||
|
||||
|
||||
#### 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,114 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud SchedulerX
|
||||
|
||||
SchedulerX(Distributed 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 `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alicloud-schedulerX`.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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 interface:org.springframework.cloud.alibaba.cloud.examples.SimpleTask
|
||||
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 speficied 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,284 +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 Alibaba’s Double 11 Shopping Festivals for over 10 years, such as second kill(i.e., controlling sudden bursts of traffic flow so that it’s 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 `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alibaba-sentinel`.
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.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].
|
||||
|
||||
##### 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
|
||||
----
|
||||
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].
|
||||
|
||||
### Feign Support
|
||||
|
||||
Sentinel is compatible with the https://github.com/OpenFeign/feign[Feign] 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 `feign 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 {
|
||||
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
|
||||
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 is:httpmethod: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:
|
||||
|
||||
* `schema://host:port/path`: Protocol, host, port and path
|
||||
|
||||
* `schema://host:port`: Protocol, host and port
|
||||
|
||||
NOTE: Take `https://www.taobao.com/test` as an example. The corresponding resource names have two levels of granularities, `https://www.taobao.com` and `https://www.taobao.com/test`.
|
||||
|
||||
### Dynamic Data Source Support
|
||||
|
||||
`SentinelProperties` provide `datasource` attribute to configure datasource.
|
||||
|
||||
For example, 4 data sources are configures:
|
||||
|
||||
```
|
||||
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=localhost:8848
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel
|
||||
spring.cloud.sentinel.datasource.ds2.nacos.groupId=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.ds5.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`).
|
||||
|
||||
If the data source takes effect and is loaded successfully, the dashboard will print information as shown below:
|
||||
|
||||
```
|
||||
[Sentinel Starter] DataSource ds1-sentinel-file-datasource load 3 DegradeRule
|
||||
[Sentinel Starter] DataSource ds2-sentinel-nacos-datasource load 2 FlowRule
|
||||
```
|
||||
|
||||
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].
|
||||
|
||||
### Endpoint Support
|
||||
|
||||
Before you use the Endpoint feature, please add the `spring-boot-starter-actuator` dependency in Maven, and enable access of Endpoints in your configuration.
|
||||
|
||||
* Add `management.security.enabled=false` in Spring Boot 1.x. The exposed endpoint path is `/sentinel`.
|
||||
* Add `management.endpoints.web.exposure.include=*` in Spring Boot 2.x. The exposed endpoint path is `/actuator/sentinel`.
|
||||
|
||||
The information exposed in Sentinel Endpoint is very useful. It includes all the rules of the current application, the log directory, the IP of the current instance, the Sentinel Dashboard address, the Block Page, the heartbeat frequency of the application and the Sentinel Dashboard, and so on.
|
||||
|
||||
### More
|
||||
|
||||
The following table shows that when there are corresponding bean types in `ApplicationContext`, some actions will be taken:
|
||||
|
||||
:frame: topbot
|
||||
[width="60%",options="header"]
|
||||
|====
|
||||
^|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:
|
||||
|
||||
:frame: topbot
|
||||
[width="60%",options="header"]
|
||||
|====
|
||||
^|Configuration ^|Description ^|Default Value
|
||||
|`spring.cloud.sentinel.enabled`|Whether Sentinel automatic configuration takes effect|true
|
||||
|`spring.cloud.sentinel.eager`|Cancel Sentinel dashboard lazy load|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`|Client IP|
|
||||
|`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
|
||||
|====
|
||||
|
||||
NOTE: These configurations will only take effect in servlet environment. RestTemplate and Feign will not take effect for these configurations.
|
@@ -1,209 +0,0 @@
|
||||
== Spring Cloud Alibaba Cloud SMS
|
||||
|
||||
SMS(Short Message Service)is 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 AliCloud SMS provide an easier-to-use API for quick access to Alibaba Cloud's SMS service based on Spring Cloud Alibaba SMS.
|
||||
|
||||
=== 如何引入 Spring Cloud AliCloud SMS
|
||||
|
||||
If you want to use SMS in your project, please use the starter with the group ID as `org.springframework.cloud` and the artifact ID as `spring-cloud-starter-alicloud-sms`.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.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 don’t 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 haven’t 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 org.springframework.cloud.alicloud.sms.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
|
||||
----
|
||||
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,32 +0,0 @@
|
||||
[[spring-cloud-alibaba-reference]]
|
||||
= Spring Cloud Alibaba Reference Documentation
|
||||
xiaojing; xiaolongzuo; jim fang; bingting peng; wangyuxin
|
||||
:doctype: book
|
||||
:toc:
|
||||
:toclevels: 4
|
||||
:source-highlighter: prettify
|
||||
:numbered:
|
||||
|
||||
== Introduction
|
||||
|
||||
Spring Cloud Alibaba aims to provide a one-stop solution for microservices development. This prjoect 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.
|
||||
|
||||
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[]
|
Reference in New Issue
Block a user