Spring Cloud Alibaba
- 简介
- 依赖管理
- Spring Cloud Alibaba Nacos Discovery
- 3.1 服务注册/发现:Nacos Discovery
- 3.2 如何引入Nacos Discovery进行服务注册/发现
- 3.3 使用Nacos Discovery进行服务注册/发现和调用的示例
- 3.3.1 Nacos 服务器启动
- 3.3.2. 启动供应商申请
- 3.3.3. 启动消费者应用程序
- 3.4. Nacos 发现端点
- 3.5. 重量路线
- 3.5.1. Spring Cloud 负载均衡器
- 3.6. 有关 Nacos Discovery Starter 配置的更多信息
- Spring Cloud Alibaba Nacos Config
- 4.1. 如何引入Nacos Config进行配置
- 4.2. 快速开始
- 4.2.1. 初始化 Nacos 服务器
- 4.3. 使用 YAML 格式的 DataId 添加配置
- 4.4. 支持动态配置更新
- 4.5. 支持配置文件级别的配置
- 4.6. 支持自定义命名空间
- 4.7. 支持自定义组
- 4.8. 支持自定义数据ID
- 4.9. Nacos 配置端点
- 4.10. 禁用 Nacos Config 自动配置
- 4.11. 有关 Nacos Config 入门配置的更多信息
- 5.Spring Cloud阿里巴巴哨兵
- 5.1. 哨兵介绍
- 5.2. 如何使用哨兵
- 5.2.2. 配置仪表板
- 5.3. OpenFeign 支持
- 5.4. RestTemplate支持
- 5.5. 动态数据源支持
- 5.6. 支持Spring Cloud Gateway
- 5.7. 断路器:带哨兵的 Spring Cloud 断路器和配置哨兵断路器
- 5.7.1. 默认配置
- 5.7.2. 特定断路器配置
- 5.8. 哨兵端点
- 5.9. 配置
- 6. Spring Cloud Alibaba RocketMQ 绑定器
- 6.1. RocketMQ简介
- 6.2. RocketMQ 用法
- 6.3. Spring Cloud Stream 介绍
- 6.4. Spring Cloud Alibaba RocketMQ Binder使用方法
- 6.5. Spring Cloud Alibaba RocketMQ Binder 的工作原理
- 6.6. 配置选项
- 6.6.1. RocketMQ 绑定器属性
- 6.6.2. RocketMQ 消费者属性
- 6.6.3. RocketMQ 提供者属性
- 7. Spring Cloud Alibaba Cloud ANS
- 7.1. 如何引入Spring Cloud阿里云ANS
- 7.2. 使用 ANS 注册服务
- 7.3. 启动注册中心
- 7.3.1. 启动轻量配置中心
- 7.3.2. 云端用户注册中心
- 8. Spring Cloud阿里云ACM
- 8.1. 如何引入Spring Cloud阿里云ACM
- 8.2. 使用 ACM 管理配置
- 8.2.1. 启动配置中心
- 8.2.2. 在配置中心添加配置
- 8.2.3. 开始申请验证
- 8.3. 修改配置文件扩展名
- 8.4. 动态配置刷新
- 8.5. 配置配置文件粒度
- 8.6. 支持自定义 ACM 超时
- 8.7. 支持自定义组配置
- 8.7.1. 支持共享配置
- 8.8. 执行器端点
- 9. Spring Cloud阿里云OSS
- 9.1. 如何引入Spring Cloud阿里云OSS
- 9.2. 如何使用 OSS API
- 9.2.1. 配置OSS
- 9.2.2. 介绍OSS API
- 9.3. 与 Spring 的资源规范集成
- 9.4. 使用 STS 认证
- 9.5. 客户端的更多配置
- 10.Spring Cloud阿里云SchedulerX
- 10.1. 如何引入Spring Cloud Alibaba Cloud SchedulerX
- 10.2. 启动调度器X
- 10.3. 编译一个简单的作业
- 10.4. 作业调度
- 10.5. 在生产环境中的使用
- 11. Spring Cloud 阿里云短信
- 11.1. 如何引入Spring Cloud阿里云短信
- 11.2. 如何使用短信API
- 11.2.1. 配置短信
- 11.2.2. 引入短信API
- 11.3. SMS Api 的高级功能
参考地址
简介
Spring Cloud Alibaba旨在为微服务开发提供一站式解决方案。本项目包含开发分布式应用和服务所需的组件,方便开发者使用Spring Cloud编程模型轻松开发分布式应用。
有了Spring Cloud Alibaba,你只需要添加一些注解和配置,你的应用就可以使用阿里巴巴的分布式解决方案,用阿里巴巴的中间件搭建一个属于你自己的分布式系统。
Spring Cloud Alibaba 的特点:
- 限流降级:支持WebServlet、WebFlux、OpenFeign、RestTemplate、Dubbo接入限流降级功能。可在运行时通过控制台实时修改限流降级规则,同时支持限流Metrics监控。
- 服务注册和发现:可以注册服务,客户端可以使用Spring管理的bean发现实例,自动集成Ribbon。
- 分布式配置:支持在分布式系统中外化配置,配置变化时自动刷新。
- Rpc Service:扩展Spring Cloud客户端RestTemplate和OpenFeign,支持调用Dubbo RPC服务。
- 事件驱动:支持构建与共享消息系统连接的高度可扩展的事件驱动微服务。
- Distributed Transaction:支持高性能易用的分布式事务解决方案。
- 阿里云对象存储:海量、安全、低成本、高可靠的云存储服务。支持随时随地在任何应用程序中存储和访问任何类型的数据。
- Alibaba Cloud SchedulerX:精准、高可靠、高可用、秒级响应的定时作业调度服务。
- 阿里云短信:覆盖全球的消息服务,阿里云短信提供便捷、高效、智能的沟通能力,帮助企业快速联系客户。
Spring Cloud Alibaba 也提供了丰富的例子。
依赖管理
如果您是 Maven Central 用户,请将我们的 BOM 添加到您的 pom.xml 部分。这将允许您忽略任何 Maven 依赖项的版本,而是将版本控制委托给 BOM。
<dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.4.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
在以下部分中,假设您使用的是 Spring Cloud Alibaba BOM,并且依赖项片段将不包含版本。
Spring Cloud Alibaba Nacos Discovery
Nacos 是一个易于使用的动态服务发现、配置和服务管理平台,用于构建云原生应用程序。
借助Spring Cloud Alibaba Nacos Discovery,您可以快速接入基于Spring Cloud编程模型的Nacos服务注册功能。
3.1 服务注册/发现:Nacos Discovery
服务发现是微服务架构中的关键组件之一。在这样的架构中,手动为每个客户端配置服务列表可能是一项艰巨的任务,并且使动态扩展变得极其困难。Nacos Discovery 帮助您自动将服务注册到 Nacos 服务器,Nacos 服务器会跟踪服务并动态刷新服务列表。另外,Nacos Discovery会将服务实例的一些元数据,如主机、端口、健康检查URL、首页等注册到Nacos中。Nacos的下载和启动方法请参考Nacos官网。
3.2 如何引入Nacos Discovery进行服务注册/发现
请使用组 ID 为com.alibaba.cloud,工件 ID 为的启动器spring-cloud-starter-alibaba-nacos-discovery。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
3.3 使用Nacos Discovery进行服务注册/发现和调用的示例
Nacos Discovery 与 Netflix Ribbon、RestTemplate 或 OpenFeign 集成,可用于服务到服务的调用。
3.3.1 Nacos 服务器启动
Nacos的下载和启动方法请参考Nacos官网。
Nacos Server启动后,进入http://ip:8848查看控制台(默认账号/密码为nacos/nacos):
图 1. Nacos 仪表板
更多Nacos Server版本,您可以在发布页面下载最新版本。
3.3.2. 启动供应商申请
以下示例说明了如何向 Nacos 注册服务。
- pom.xml的配置下面是一个完整的pom.xml示例:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>open.source.test</groupId> <artifactId>nacos-discovery-test</artifactId> <version>1.0-SNAPSHOT</version> <name>nacos-discovery-test</name> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring.boot.version}</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
- application.properties的配置 Nacos的一些基本配置必须包含在application.properties(或application.yaml)中,如下所示:
应用程序.properties
server.port=8081spring.application.name=nacos-providerspring.cloud.nacos.discovery.server-addr=127.0.0.1:8848management.endpoints.web.exposure.include=*
如果不想使用 Nacos 进行服务注册和发现,可以设置spring.cloud.nacos.discovery为false.
- 以下是启动 Provider 的示例:
@SpringBootApplication@EnableDiscoveryClientpublic class NacosProviderDemoApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderDemoApplication.class, args); } @RestController public class EchoController { @GetMapping(value = "/echo/{string}") public String echo(@PathVariable String string) { return "Hello Nacos Discovery " + string; } }}
现在就可以在Nacos控制台看到注册的服务了。
在启动提供者应用程序之前,请先启动 Nacos。有关详细信息,请参阅Naco 网站。
3.3.3. 启动消费者应用程序
它可能不像启动提供者应用程序那么容易,因为消费者需要调用提供者的 RESTful 服务。在这个例子中,我们将使用最原始的方式,即显式结合 LoadBalanceClient 和 RestTemplate 来访问 RESTful 服务。pom.xml和application.properties的配置可以参考1.2节。以下是启动消费者应用程序的示例代码。
您还可以使用具有负载平衡的 RestTemplate 和 FeignClient 来访问该服务。
@SpringBootApplication@EnableDiscoveryClientpublic class NacosConsumerApp { @RestController public class NacosController{ @Autowired private LoadBalancerClient loadBalancerClient; @Autowired private RestTemplate restTemplate; @Value("${spring.application.name}") private String appName; @GetMapping("/echo/app-name") public String echoAppName(){ //Access through the combination of LoadBalanceClient and RestTemplate ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider"); String path = String.format("http://%s:%s/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName); System.out.println("request path:" +path); return restTemplate.getForObject(path,String.class); } } //Instantiate RestTemplate Instance @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(NacosConsumerApp.class,args); }}
在这个例子中,我们注入了一个 LoadBalancerClient 实例,并手动实例化了一个 RestTemplate。同时我们将 的配置值spring.application.name注入到应用中,这样在调用提供者的服务时就可以显示当前的应用名称。
请在启动消费者应用程序之前启动 Nacos。详情请参考Nacos官网。
接下来访问http://ip:port/echo/app-name消费者提供的接口。这里我们开启了8082端口,访问结果如下图:
地址:http://127.0.0.1:8082/echo/app-name访问结果: Hello Nacos Discovery nacos-consumer
3.4. Nacos 发现端点
Nacos Discovery 内部提供了一个 Endpoint,对应的 endpoint id 为nacosdiscovery。
端点暴露的 json 包含两个属性:
- subscribe:显示当前的服务订阅者
- NacosDiscoveryProperties:显示当前服务当前的Nacos基本配置
下面展示了一个服务实例是如何访问 Endpoint 的:
{ "subscribe": [ { "jsonFromServer": "", "name": "nacos-provider", "clusters": "", "cacheMillis": 10000, "hosts": [ { "instanceId": "30.5.124.156#8081#DEFAULT#nacos-provider", "ip": "30.5.124.156", "port": 8081, "weight": 1.0, "healthy": true, "enabled": true, "cluster": { "serviceName": null, "name": null, "healthChecker": { "type": "TCP" }, "defaultPort": 80, "defaultCheckPort": 80, "useIPPort4Check": true, "metadata": { } }, "service": null, "metadata": { } } ], "lastRefTime": 1541755293119, "checksum": "e5a699c9201f5328241c178e804657e11541755293119", "allIPs": false, "key": "nacos-provider", "valid": true } ], "NacosDiscoveryProperties": { "serverAddr": "127.0.0.1:8848", "endpoint": "", "namespace": "", "logName": "", "service": "nacos-provider", "weight": 1.0, "clusterName": "DEFAULT", "metadata": { }, "registerEnabled": true, "ip": "30.5.124.201", "networkInterface": "", "port": 8082, "secure": false, "accessKey": "", "secretKey": "" }}
3.5. 重量路线
3.5.1. Spring Cloud 负载均衡器
pom.xml
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency></dependencies>
应用程序.properties
spring.cloud.loadbalancer.ribbon.enabled=falsespring.cloud.loadbalancer.nacos.enabled=true
3.6. 有关 Nacos Discovery Starter 配置的更多信息
Nacos Discovery启动器的其他配置如下:
Configuration | Key | Default Value | 描述 |
---|---|---|---|
Server address | spring.cloud.nacos.discovery.server-addr | Nacos Server监听的IP和端口 | |
Service name | spring.cloud.nacos.discovery.service | ${spring.application.name} | 命名当前服务 |
Weight | spring.cloud.nacos.discovery.weight | 1 | 取值范围:1~100,值越大,权重越大 |
Network card name | spring.cloud.nacos.discovery.network-interface | 如果不指定IP地址,则注册的IP地址为网卡的IP地址。如果也没有指定,默认使用第一个网卡的IP地址。 | |
Registered IP address | spring.cloud.nacos.discovery.ip | 最高优先级 | |
Registered IP address Type | spring.cloud.nacos.discovery.ip-type | IPv4 | 可以配置IPv4和IPv6,如果同类型网卡有多个IP地址,想指定具体网段地址,可以使用spring.cloud.inetutils.preferred-networks配置过滤地址 |
Registered port | spring.cloud.nacos.discovery.port | -1 | 默认情况下会自动检测。不需要配置。 |
Namespace | spring.cloud.nacos.discovery.namespace | 一个典型的场景是隔离不同环境的服务注册,比如测试环境和生产环境的资源(配置、服务等)隔离 | |
AccessKey | spring.cloud.nacos.discovery.access-key | Alibaba Cloud account accesskey | |
SecretKey | spring.cloud.nacos.discovery.secret-key | Alibaba Cloud account secretkey | |
Metadata | spring.cloud.nacos.discovery.metadata | 您可以以Map格式为您的服务定义一些元数据 | |
Log file name | spring.cloud.nacos.discovery.log-name | ||
Cluster Name | spring.cloud.nacos.discovery.cluster-name | DEFAULT | Nacos的集群名称 |
Endpoint | spring.cloud.nacos.discovery.endpoint | 特定地区某项服务的域名。您可以使用此域名动态检索服务器地址 | |
Integrate LoadBalancer or not | spring.cloud.loadbalancer.nacos.enabled | false | |
Enable Nacos Watch | spring.cloud.nacos.discovery.watch.enabled | true | 设置为 false 以关闭监听 |
Spring Cloud Alibaba Nacos Config
Nacos 是一个易于使用的动态服务发现、配置和服务管理平台,用于构建云原生应用程序。
使用Spring Cloud Alibaba Nacos Config,基于Spring Cloud的编程模型,快速接入Nacos的配置管理能力。
4.1. 如何引入Nacos Config进行配置
请使用组 ID 为com.alibaba.cloud,工件 ID 为的启动器spring-cloud-starter-alibaba-nacos-config。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>
4.2. 快速开始
Nacos Config 使用 DataId 和 GROUP 来确定一个配置。
下图是DataId使用myDataid,GROUP使用DEFAULT_GROUP,配置了一个Properties格式的配置项:
图 2. Nacos 配置项
4.2.1. 初始化 Nacos 服务器
具体的启动方法可以参考Spring Cloud Alibaba Nacos Discovery章节的“Nacos Server启动”部分。
Nacos Server启动后,添加配置方式:
Data ID: nacos-config.propertiesGroup : DEFAULT_GROUPConfiguration format: PropertiesConfiguration content: user.name=nacos-config-properties user.age=90
DataId 的默认文件扩展名是属性。
在客户端上的使用
如果您想使用 Nacos 来管理您的应用程序的外部化配置,请使用组 ID 为com.alibaba.cloud,工件 ID 为的 starter spring-cloud-starter-alibaba-nacos-config。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>
现在我们可以创建一个标准的 Spring Boot 应用程序。
@SpringBootApplicationpublic class NacosConfigApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args); String userName = applicationContext.getEnvironment().getProperty("user.name"); String userAge = applicationContext.getEnvironment().getProperty("user.age"); System.err.println("user name :" +userName+"; age: "+userAge); }}
请注意,当您获取文件中的配置时,将在文件之前加载。根据spring官方文档中提到的[bootstrap]( https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#config-first-bootstrap ) 来解决这个问题,我们推荐您将以下依赖项添加到项目根文件中 spring-cloud-alibaba’s version is ``2021.1nacosbootstrap.yml application.ymlpom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <version>3.1.1</version></dependency>
在运行这个例子之前,我们需要在bootstrap.properties中配置Nacos服务器的地址。例如:
bootstrap.properties
# DataId By default, the `spring.application.name` configuration is combined with the file extension (the configuration format uses properties by default), and the GROUP is not configured to use DEFAULT_GROUP by default. Therefore, the Nacos Config configuration corresponding to the configuration file has a DataId of nacos-config.properties and a GROUP of DEFAULT_GROUPspring.application.name=nacos-configspring.cloud.nacos.config.server-addr=127.0.0.1:8848
如果使用域名访问Nacos,格式spring.cloud.nacos.config.server-addr应该是Domain name:port. 例如Nacos域名为abc.com.nacos,监听器端口为80,则配置为spring.cloud.nacos.config.server-addr=abc.com.nacos:80. 80端口不能省略。
运行此示例,您可以看到以下输出:
2018-11-02 14:24:51.638 INFO 32700 --- [main] c.a.demo.provider.NacosConfigApplication : Started NacosConfigApplication in 14.645 seconds (JVM running for 15.139)user name :nacos-config-properties; age: 902018-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
4.3. 使用 YAML 格式的 DataId 添加配置
Nacos Config 也支持 yaml 格式。您只需完成以下2个步骤。
1、在bootstrap.properties文件中,添加如下一行声明DataId的格式为yaml。如下:
bootstrap.properties
spring.cloud.nacos.config.file-extension=yaml
2、在Nacos控制台添加配置,DataId为yaml格式,如下图:
Data ID: nacos-config.yamlGroup : DEFAULT_GROUPConfiguration format: YAMLConfiguration content: user.name: nacos-config-yaml user.age: 68
完成前两步后,重启测试程序,你会看到如下结果。
2018-11-02 14:59:00.484 INFO 32928 --- [main] c.a.demo.provider.NacosConfigApplication:Started NacosConfigApplication in 14.183 seconds (JVM running for 14.671)user name :nacos-config-yaml; age: 682018-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
4.4. 支持动态配置更新
Nacos Config 还支持动态配置更新。启动Spring Boot应用测试的代码如下:
@SpringBootApplicationpublic class NacosConfigApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args); while(true) { //When configurations are refreshed dynamically, they will be updated in the Enviroment, therefore here we retrieve configurations from Environment every other second. String userName = applicationContext.getEnvironment().getProperty("user.name"); String userAge = applicationContext.getEnvironment().getProperty("user.age"); System.err.println("user name :" + userName + "; age: " + userAge); TimeUnit.SECONDS.sleep(1); } }}
更改 user.name 时,可以从应用程序中检索最新值,如下所示:
user name :nacos-config-yaml; age: 68user name :nacos-config-yaml; age: 68user name :nacos-config-yaml; age: 682018-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@6520af72018-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 Enviromentuser name :nacos-config-yaml-update; age: 68user name :nacos-config-yaml-update; age: 68
您可以使用此设置 spring.cloud.nacos.config.refresh.enabled=false 禁用自动刷新。
4.5. 支持配置文件级别的配置
Nacos Config 加载配置时,DataId 为 的基础配置也会被加载${spring.application.name}. f i l e − e x t e n s i o n : p r o p e r t i e s , D a t a I d 为 {file-extension:properties},DataId 为 file−extension:properties,DataId为{spring.application.name}-${profile}. f i l e − e x t e n s i o n : p r o p e r t i e s 。如果需要在不同的环境使用不同的配置,可以使用 {file-extension:properties}。如果需要在不同的环境使用不同的配置,可以使用 file−extension:properties。如果需要在不同的环境使用不同的配置,可以使用{spring.profiles.active}Spring提供的配置。
spring.profiles.active=develop
在配置文件中指定时,${spring.profiles.active} 必须放在 bootstrap.properties 中。
在Nacos中添加一个基础配置,DataId为nacos-config-develop.yaml,如下图:
Data ID: nacos-config-develop.yamlGroup : DEFAULT_GROUPConfiguration format: YAMLConfiguration content: current.env: develop-env
运行以下 Spring Boot 应用程序测试代码:
@SpringBootApplicationpublic class NacosConfigApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args); while(true) { String userName = applicationContext.getEnvironment().getProperty("user.name"); String userAge = applicationContext.getEnvironment().getProperty("user.age"); //Get the current deployment environment String currentEnv = applicationContext.getEnvironment().getProperty("current.env"); System.err.println("in "+currentEnv+" enviroment; "+"user name :" + userName + "; age: " + userAge); TimeUnit.SECONDS.sleep(1); } }}
启动后,可以在控制台看到如下输出:
in develop-env enviroment; user name :nacos-config-yaml-update; age: 682018-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}。如下图:
spring.profiles.active=product
同时在生产环境的Nacos中添加DataId的基础配置。比如你可以在你的生产环境的Nacos中添加DataId为nacos-config-product.yaml的配置:
Data ID: nacos-config-product.yamlGroup : DEFAULT_GROUPConfiguration format: YAMLConfiguration content: current.env: product-env
启动测试程序,你会看到如下结果:
in product-env enviroment; user name :nacos-config-yaml-update; age: 682018-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
在这个例子中,我们使用 方法在配置文件中编码配置spring.profiles.active=。在实际场景中,这个变量需要在不同的环境中有所不同。您可以使用-Dspring.profiles.active=参数指定配置,以便您可以轻松地在不同环境之间切换。
4.6. 支持自定义命名空间
Nacos中命名空间的详细介绍,请参考Nacos概念
命名空间用于隔离不同租户的配置。不同命名空间中的组和数据 ID 可以相同。命名空间的典型场景是不同环境的配置隔离,例如开发/测试环境和生产环境(配置和服务等)的隔离。
如果没有指定命名空间,则使用 Nacos 的“公共”命名空间${spring.cloud.nacos.config.namespace}。您还可以通过以下方式指定自定义命名空间:
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
此配置必须位于 bootstrap.properties 文件中。的值spring.cloud.nacos.config.namespace是命名空间的id,id的值可以从Nacos控制台获取。添加配置时不要选择其他命名空间。否则无法正确检索配置。
4.7. 支持自定义组
{spring.cloud.nacos.config.group}没有定义配置时默认使用 DEFAULT_GROUP 。如果需要定义自己的组,可以在下面的属性中定义:
spring.cloud.nacos.config.group=DEVELOP_GROUP
这个配置必须在 bootstrap.properties 文件中,并且 Group 的值必须与 的值相同spring.cloud.nacos.config.group。
4.8. 支持自定义数据ID
从Spring Cloud Alibaba Nacos Config开始,数据id可以自定义。这部分的详细设计可以参考Github issue。以下是一个完整的示例:
spring.application.name=opensource-service-providerspring.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.propertiesspring.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.propertiesspring.cloud.nacos.config.ext-config[2].group=REFRESH_GROUPspring.cloud.nacos.config.ext-config[2].refresh=true
我们可以看到:
- 通过配置支持多个数据id spring.cloud.nacos.config.ext-config[n].data-id。
- 通过配置自定义数据组id spring.cloud.nacos.config.ext-config[n].group。如果未指定,则使用 DEFAULT_GROUP。
- 控制此数据id是否支持配置动态刷新,支持通过configuration更改配置时spring.cloud.nacos.config.ext-config[n].refresh。默认情况下不支持它。
当同时配置多个Data Id时,优先级由.n中的n值定义spring.cloud.nacos.config.ext-config[n].data-id。值越大,优先级越高。
的值spring.cloud.nacos.config.ext-config[n].data-id必须有一个文件扩展名,它可以是 properties 或 yaml/yml。中的设置spring.cloud.nacos.config.file-extension对自定义数据 ID 文件扩展名没有任何影响。
配置自定义Data Id可以实现多个应用之间的配置共享,也可以实现一个应用支持多种配置。
为了更清晰的在多个应用之间共享data id,还可以使用如下方法:
spring.cloud.nacos.config.shared-dataids=bootstrap-common.properties,all-common.propertiesspring.cloud.nacos.config.refreshable-dataids=bootstrap-common.properties
我们可以看到:
- 可以配置多个共享数据id spring.cloud.nacos.config.shared-dataids,数据id之间用逗号分隔。
- spring.cloud.nacos.config.refreshable-dataids用于控制更新配置时动态刷新哪些数据id,以及最新的配置值可以被应用程序检索。数据 ID 用逗号分隔。如果没有指定,所有的共享数据id都不会被动态刷新。
当spring.cloud.nacos.config.shared-dataids用于配置多个共享数据id时,我们约定共享配置之间的以下优先级:优先级是根据配置出现的顺序来决定的。后出现的优先级高于先出现的优先级。
使用spring.cloud.nacos.config.shared-dataids时,data Id 必须有文件扩展名,可以是 properties 或 yaml/yml。并且里面的配置spring.cloud.nacos.config.file-extension对自定义的Data Id文件扩展名没有任何影响。
指定支持动态刷新的data id时spring.cloud.nacos.config.refreshable-dataids,data id对应的值也要指定文件扩展名。
4.9. Nacos 配置端点
Nacos Config 内部提供了一个 Endpoint,对应的 endpoint id 为nacos-config.
端点暴露的 json 包含三个属性:
- 资料来源:当前应用程序配置数据信息
- RefreshHistory:配置刷新历史
- NacosConfigProperties:显示当前服务当前的Nacos基本配置
下面展示了一个服务实例是如何访问 Endpoint 的:
{"NacosConfigProperties": {"serverAddr": "127.0.0.1:8848","encode": null,"group": "DEFAULT_GROUP","prefix": null,"fileExtension": "properties","timeout": 3000,"endpoint": null,"namespace": null,"accessKey": null,"secretKey": null,"contextPath": null,"clusterName": null,"name": null,"sharedDataids": "base-common.properties,common.properties","refreshableDataids": "common.properties","extConfig": null},"RefreshHistory": [{"timestamp": "2019-07-29 11:20:04","dataId": "nacos-config-example.properties","md5": "7d5d7f1051ff6571e2ec9f90887d9d91"}],"Sources": [{"lastSynced": "2019-07-29 11:19:04","dataId": "common.properties"}, {"lastSynced": "2019-07-29 11:19:04","dataId": "base-common.properties"}, {"lastSynced": "2019-07-29 11:19:04","dataId": "nacos-config-example.properties"}]}
4.10. 禁用 Nacos Config 自动配置
设置 spring.cloud.nacos.config.enabled = false 以禁用 Spring Cloud Nacos Config AutoConfiguration。
4.11. 有关 Nacos Config 入门配置的更多信息
Nacos Config启动器的其他配置如下:
Configuration | Key | Default Value | Description |
---|---|---|---|
Server address | spring.cloud.nacos.config.server-addr | Nacos Server监听的IP和端口 | |
Dataid from nacos config | spring.cloud.nacos.config.name | 先取前缀,再取名字,最后取spring.application.name | |
Dataid from nacos config | spring.cloud.nacos.config.prefix | 先取前缀,再取名字,最后取spring.application.name | |
Encode for nacos config content | spring.cloud.nacos.config.encode | 对 nacos 配置内容进行编码 | |
GROUP for nacos config | spring.cloud.nacos.config.group | DEFAULT_GROUP | nacos 配置的 GROUP |
The suffix of nacos config dataId, also the file extension of config content. | spring.cloud.nacos.config.fileExtension | properties | nacos config dataId的后缀,也是config内容的文件扩展名(现在支持properties或者yaml(yml)) |
Timeout for get config from nacos | spring.cloud.nacos.config.timeout | 3000 | nacos获取配置超时 |
Endpoint | spring.cloud.nacos.config.endpoint | 端口 | |
Namespace | spring.cloud.nacos.config.namespace | 命名空间 | |
AccessKey | spring.cloud.nacos.config.accessKey | Alibaba Cloud account accesskey | |
SecretKey | spring.cloud.nacos.config.secretKey | Alibaba Cloud account secretkey | |
The context path of Nacos Server | spring.cloud.nacos.config.contextPath | Nacos Server 上下文路径 | |
Cluster name | spring.cloud.nacos.config.clusterName | 集群名称 | |
Dataid for Shared Configuration | spring.cloud.nacos.config.sharedDataids | 共享配置的Dataid,以“,”分割 | |
Dynamic refresh dataid for Shared Configuration | spring.cloud.nacos.config.refreshableDataids | Shared Configuration的动态刷新dataid,以“,”分割 | |
custom dataid | spring.cloud.nacos.config.extConfig | 这是一个列表,由ConfigPOJO 建立。Config有 3 个属性,dataId,group和refresh |
5.Spring Cloud阿里巴巴哨兵
5.1. 哨兵介绍
随着微服务的流行,服务调用的稳定性变得越来越重要。Sentinel以“流量”为切入点,在流量控制、断路、负载保护等多个领域发力,为服务可靠性保驾护航。
哨兵具有以下特点:
- 场景丰富:Sentinel支持阿里双11重点场景秒杀(控制突发流量在系统容量可接受范围内)、消息负载转移、断路不可靠的下游应用。
- 全面实时监控: Sentinel提供实时监控能力。您可以看到您服务器的监控数据,精确到秒级,甚至可以查看500节点以下集群的整体运行状态。
- 广泛的开源生态系统: Sentinel 提供开箱即用的模块,可以轻松与其他开源框架/库集成,例如 Spring Cloud、Dubbo 和 gRPC。使用Sentinel,只需要引入相关的依赖,进行一些简单的配置即可。
- Sound SPI Extensions: Sentinel提供简单易用且完善的SPI扩展接口。您可以使用 SPI 扩展快速自定义逻辑,例如,您可以定义自己的规则管理,或者适配特定的数据源。
5.2. 如何使用哨兵
如果你想在你的项目中使用 Sentinel,请使用组 ID 为com.alibaba.cloudartifact ID 为的 starter spring-cloud-starter-alibaba-sentinel。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
以下是如何使用 Sentinel 的简单示例:
@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(ServiceApplication.class, args); }}@RestControllerpublic class TestController { @GetMapping(value = "/hello") @SentinelResource("hello") public String hello() { return "Hello Sentinel"; }}
@SentinelResource 注释用于标识资源是速率受限还是降级。在上面的示例中,注释的“hello”属性指的是资源名称。
@SentinelResource 还提供 、 和 等属性blockHandler来blockHandlerClass标识fallback速率限制或降级操作。有关详细信息,请参阅 Sentinel 注释支持。
Sentinel 注释支持
Sentinel注解支持
Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。使用 Sentinel Annotation AspectJ Extension 的时候需要引入以下依赖:
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>x.y.z</version></dependency>
@SentinelResource 注解
注意:注解方式埋点不支持 private 方法。
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:
- value:资源名称,必需项(不能为空)
- entryType:entry 类型,可选项(默认为 EntryType.OUT)
- blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
- fallback / fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
1.返回值类型必须与原函数返回值类型一致;
2.方法参数列表需要和原函数一致,或者可以额外多一个Throwable 类型的参数用于接收对应的异常。
3.fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。 - exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
1.8.0 版本开始,defaultFallback 支持在类级别进行配置。
注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。
特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出(若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException)。
示例:
public class TestService { // 原函数 @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback") public String hello(long s) { return String.format("Hello at %d", s); } // Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数. public String helloFallback(long s) { return String.format("Halooooo %d", s); } // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致. public String exceptionHandler(long s, BlockException ex) { // Do some log here. ex.printStackTrace(); return "Oops, error occurred at " + s; } // 这里单独演示 blockHandlerClass 的配置. // 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 public static 函数. @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class}) public void test() { System.out.println("Test"); }}
从 1.4.0 版本开始,注解方式定义资源支持自动统计业务异常,无需手动调用 Tracer.trace(ex) 来记录业务异常。Sentinel 1.4.0 以前的版本需要自行调用 Tracer.trace(ex) 来记录业务异常。
配置
Spring Cloud Alibaba
若您是通过 Spring Cloud Alibaba 接入的 Sentinel,则无需额外进行配置即可使用 @SentinelResource 注解。
Spring AOP
若您的应用使用了 Spring AOP(无论是 Spring Boot 还是传统 Spring 应用),您需要通过配置的方式将 SentinelResourceAspect 注册为一个 Spring Bean:
@Configurationpublic class SentinelAspectConfiguration { @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }}
我们提供了 Spring AOP 的示例,可以参见 sentinel-demo-annotation-spring-aop。
AspectJ
若您的应用直接使用了 AspectJ,那么您需要在 aop.xml 文件中引入对应的 Aspect:
<aspects> <aspect name="com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect"/></aspects>
以上例子都是在WebServlet环境下使用的。Sentinel目前支持WebFlux,需要配合spring-boot-starter-webflux依赖触发sentinel starter中WebFlux相关的自动化配置。
@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(ServiceApplication.class, args); }}@RestControllerpublic class TestController { @GetMapping("/mono") @SentinelResource("hello") public Mono<String> mono() {return Mono.just("simple string").transform(new SentinelReactorTransformer<>("otherResourceName")); }}
哨兵仪表板
Sentinel dashboard是一个轻量级的控制台,提供机器发现、单机资源监控、集群资源数据概览、规则管理等功能。要使用这些功能,您只需完成几个步骤。
注意:集群统计概览只支持500个以下的集群,有1-2秒左右的延迟。
要使用 Sentinel 仪表板,只需完成以下 3 个步骤。
获取仪表板
您可以从发布页面下载最新的仪表板 JAR 文件。
您还可以获得最新的源代码来构建您自己的 Sentinel 仪表盘:
- 下载 仪表板项目。
- 运行以下命令将代码打包到 FatJar 中:mvn clean package
启动仪表板
Sentinel dashboard 是一个标准的SpringBoot 应用程序,您可以在Spring Boot 模式下运行JAR 文件。
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
如果与 8080 端口有冲突,可以使用-Dserver.port=new port定义新的端口。
5.2.2. 配置仪表板
application.yml
spring: cloud: sentinel: transport: port: 8719 dashboard: localhost:8080
指定的端口号spring.cloud.sentinel.transport.port会在应用对应的服务器上启动一个HTTP Server,这个服务器会和Sentinel dashboard进行交互。例如,如果在 Sentinel 仪表板中添加了速率限制规则,则规则数据将被推送到 HTTP 服务器并由其接收,而 HTTP 服务器又将规则注册到 Sentinel。
有关 Sentinel 仪表板的更多信息,请参阅Sentinel 仪表板。
5.3. OpenFeign 支持
Sentinel 与OpenFeign组件兼容。要使用它,除了引入sentinel-starter依赖外,还要完成以下2个步骤:
- 在属性文件中启用 Sentinel 对 feign 的支持。feign.sentinel.enabled=true
- 将openfeign starter依赖项添加到 trigger 和 enable sentinel starter:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
这是一个简单的用法FeignClient:
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)public interface EchoService { @GetMapping(value = "/echo/{str}") String echo(@PathVariable("str") String str);}class FeignConfiguration { @Bean public EchoServiceFallback echoServiceFallback() { return new EchoServiceFallback(); }}class EchoServiceFallback implements EchoService { @Override public String echo(@PathVariable("str") String str) { return "echo fallback"; }}
Feign对应接口中的资源名称策略为:httpmethod:protocol://requesturl。@FeignClientSentinel 支持注解 中的所有属性。
接口中echo方法对应的资源名称为.EchoServiceGET:http://service-provider/echo/{str}
5.4. RestTemplate支持
Spring Cloud Alibaba Sentinel 支持RestTemplate使用 Sentinel 对服务调用进行保护。为此,您需要在构造bean@SentinelRestTemplate时添加注解。RestTemplate
@Bean@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)public RestTemplate restTemplate() { return new RestTemplate();}
@SentinelRestTemplate注解的属性支持流控( blockHandler, blockHandlerClass)和熔断(fallback, fallbackClass)。
==
blockHandlerorfallback是 or 的blockHandlerClass静态方法fallbackClass。
method in 的参数和返回值与@SentinelRestTemplate相同
org.springframework.http.client.ClientHttpRequestInterceptor#interceptor,但多了一个参数BlockException,可以让 Sentinel 捕获异常。
上面的方法签名应该handleException是ExceptionUtil这样的:
public class ExceptionUtil { public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) { ... }}
应用启动时会检查@SentinelRestTemplate流控或熔断方法对应的注解是否存在,如果不存在则抛出异常。
@SentinelRestTemplate注释的属性是可选的。
RestTemplate request block by sentinel当您使用RestTemplate被 Sentinel 阻止时,它将返回。您可以根据自己的逻辑覆盖它。我们提供SentinelClientHttpResponse处理响应。
Sentinel RestTemplate 提供了两种粒度的资源限速:
- httpmethod:schema://host:port/path: 协议、主机、端口和路径
- httpmethod:schema://host:port: 协议、主机和端口
以 Http GEThttps://www.taobao.com/test为例。相应的资源名称有两个级别的粒度,GET:https://www.taobao.com和GET:https://www.taobao.com/test.
5.5. 动态数据源支持
SentinelProperties提供datasource配置数据源的属性。
例如配置4个数据源:
spring.cloud.sentinel.datasource.ds1.file.file=classpath: degraderule.jsonspring.cloud.sentinel.datasource.ds1.file.rule-type=flow#spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json#spring.cloud.sentinel.datasource.ds1.file.data-type=custom#spring.cloud.sentinel.datasource.ds1.file.converter-class=JsonFlowRuleListConverter#spring.cloud.sentinel.datasource.ds1.file.rule-type=flowspring.cloud.sentinel.datasource.ds2.nacos.server-addr=127.0.0.1:8848spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinelspring.cloud.sentinel.datasource.ds2.nacos.group-id=DEFAULT_GROUPspring.cloud.sentinel.datasource.ds2.nacos.data-type=jsonspring.cloud.sentinel.datasource.ds2.nacos.rule-type=degradespring.cloud.sentinel.datasource.ds3.zk.path = /Sentinel-Demo/SYSTEM-CODE-DEMO-FLOWspring.cloud.sentinel.datasource.ds3.zk.server-addr = localhost:2181spring.cloud.sentinel.datasource.ds3.zk.rule-type=authorityspring.cloud.sentinel.datasource.ds4.apollo.namespace-name = applicationspring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = sentinelspring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = testspring.cloud.sentinel.datasource.ds4.apollo.rule-type=param-flow
此方法遵循 Spring Cloud Stream Binder 的配置。TreeMap内部用于存储,比较器为String.CASE_INSENSITIVE_ORDER.
d1, ds2, ds3, ds4 是 的名称ReadableDataSource,可以任意编码。, file, zk,指的是具体的数据来源nacos。apollo它们后面的配置分别是这些数据源的具体配置。
每个数据源都有 3 个公共配置项:data-type,converter-class和rule-type。
data-type指的是Converter。Spring Cloud Alibaba Sentinel默认提供了两个内嵌值:jsonand xml(不指定默认为json)。如果你不想使用嵌入式json或者xml Converter,你也可以填写custom表示你将自己定义Converter,然后配置converter-class。您需要为此配置指定类的完整路径。
rule-type指数据源中的规则类型( flow,degrade,authority,system, param-flow, gw-flow, gw-api-group)。
默认不支持 XML 格式。为了使其生效,您需要添加 jackson-dataformat-xml依赖项。
要了解有关动态数据源如何在 Sentinel 中工作的更多信息,请参阅动态规则扩展。
5.6. 支持Spring Cloud Gateway
参考API网关流量控制
如果要在Spring Cloud Gateway中使用Sentinel Starter,需要添加spring-cloud-alibaba-sentinel-gateway依赖,添加spring-cloud-starter-gateway依赖让模块中的Spring Cloud Gateway AutoConfiguration类生效:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId></dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId></dependency>
5.7. 断路器:带哨兵的 Spring Cloud 断路器和配置哨兵断路器
5.7.1. 默认配置
要为所有断路器提供默认配置,请创建一个Customizer传递 SentinelCircuitBreakerFactoryor的 bean ReactiveSentinelCircuitBreakerFactory。该configureDefault方法可用于提供默认配置。
@Beanpublic Customizer<SentinelCircuitBreakerFactory> defaultCustomizer() {return factory -> factory.configureDefault(id -> new SentinelConfigBuilder(id).build());}
您可以选择通过 提供默认的熔断规则SentinelConfigBuilder#rules(rules)。DegradeRuleManager.loadRules(rules)您还可以选择稍后使用Sentinel 的 API 或通过 Sentinel 仪表板在其他地方加载熔断规则 。
反应性例子
@Beanpublic Customizer<ReactiveSentinelCircuitBreakerFactory> defaultCustomizer() {return factory -> factory.configureDefault(id -> new SentinelConfigBuilder(id).build());}
5.7.2. 特定断路器配置
与提供默认配置类似,您可以创建一个Customizer通过 SentinelCircuitBreakerFactory.
@Beanpublic Customizer<SentinelCircuitBreakerFactory> slowCustomizer() {String slowId = "slow";List<DegradeRule> rules = Collections.singletonList(new DegradeRule(slowId).setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(100).setTimeWindow(10));return factory -> factory.configure(builder -> builder.rules(rules), slowId);}
反应性例子
@Beanpublic Customizer<ReactiveSentinelCircuitBreakerFactory> customizer() {List<DegradeRule> rules = Collections.singletonList(new DegradeRule().setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(100).setTimeWindow(10));return factory -> factory.configure(builder -> builder.rules(rules), "foo", "bar");}
5.8. 哨兵端点
Sentinel 在内部提供了一个 Endpoint,对应的端点 ID 为sentinel。
端点暴露的 json 包含多个属性:
- appName:应用名称
- logDir:日志目录
- logUsePid: 带 pid 的日志名称
- blockPage:哨兵块后重定向页面
- metricsFileSize:指标文件的大小
- metricsFileCharset:指标文件字符集
- totalMetricsFileCount:指标文件的总文件数
- consoleServer: sentinel dashboard 地址
- clientIp:客户端ip
- heartbeatIntervalMs:带有仪表板的客户端心跳间隔
- clientPort:客户端需要暴露端口才能与dashboard交互
- coldFactor: 冷因子
- filter:CommonFilter相关的属性,比如order、urlPatterns和enable
- 数据源:客户端的数据源配置信息
- rules:客户端生效的规则,内部包含flowRules, degradeRules, systemRules, authorityRule, paramFlowRule
下面展示了一个服务实例是如何访问 Endpoint 的:
{"blockPage": null,"appName": "sentinel-example","consoleServer": "localhost:8080","coldFactor": "3","rules": {"flowRules": [{"resource": "GET:http://www.taobao.com","limitApp": "default","grade": 1,"count": 0.0,"strategy": 0,"refResource": null,"controlBehavior": 0,"warmUpPeriodSec": 10,"maxQueueingTimeMs": 500,"clusterMode": false,"clusterConfig": null}, {"resource": "/test","limitApp": "default","grade": 1,"count": 0.0,"strategy": 0,"refResource": null,"controlBehavior": 0,"warmUpPeriodSec": 10,"maxQueueingTimeMs": 500,"clusterMode": false,"clusterConfig": null}, {"resource": "/hello","limitApp": "default","grade": 1,"count": 1.0,"strategy": 0,"refResource": null,"controlBehavior": 0,"warmUpPeriodSec": 10,"maxQueueingTimeMs": 500,"clusterMode": false,"clusterConfig": null}]},"metricsFileCharset": "UTF-8","filter": {"order": -2147483648,"urlPatterns": ["/*"],"enabled": true},"totalMetricsFileCount": 6,"datasource": {"ds1": {"file": {"dataType": "json","ruleType": "FLOW","converterClass": null,"file": "...","charset": "utf-8","recommendRefreshMs": 3000,"bufSize": 1048576},"nacos": null,"zk": null,"apollo": null,"redis": null}},"clientIp": "30.5.121.91","clientPort": "8719","logUsePid": false,"metricsFileSize": 52428800,"logDir": "...","heartbeatIntervalMs": 10000}
5.9. 配置
下表显示当 中有对应的bean类型时ApplicationContext,会进行一些动作:
Existing Bean Type | Action | Function |
---|---|---|
UrlCleaner | WebCallbackManager.setUrlCleaner(urlCleaner) | 资源清理(resource(例如将/foo/:id的所有url分类到/foo/*资源)) |
UrlBlockHandler | WebCallbackManager.setUrlBlockHandler(urlBlockHandler) | 自定义限速逻辑 |
RequestOriginParser | WebCallbackManager.setRequestOriginParser(requestOriginParser) | 设置原点 |
下表是Spring Cloud Alibaba Sentinel的所有配置:
Configuration | Description | Default Value |
---|---|---|
spring.application.name or project.name | 哨兵的项目名称 | |
spring.cloud.sentinel.enabled | Sentinel自动配置是否生效 | true |
spring.cloud.sentinel.eager | 是否提前触发Sentinel初始化 | false |
spring.cloud.sentinel.transport.port | 应用程序与 Sentinel 仪表板交互的端口。使用此端口的 HTTP 服务器将在应用程序中启动 | 8719 |
spring.cloud.sentinel.transport.dashboard | Sentinel仪表盘地址 | |
spring.cloud.sentinel.transport.heartbeatIntervalMs | 应用程序和 Sentinel 仪表板之间的心跳间隔 | |
spring.cloud.sentinel.transport.client-ip | 这个配置的客户端IP会注册到Sentinel Server端。 | |
spring.cloud.sentinel.filter.order | Servlet 过滤器的加载顺序。过滤器将在 Starter 中构建 | Integer.MIN_VALUE |
spring.cloud.sentinel.filter.url-patterns | 数据类型为数组。指Servlet Filter ULR模式的集合 | /* |
spring.cloud.sentinel.filter.enabled | 启用实例 CommonFilter | true |
spring.cloud.sentinel.metric.charset | 公制文件字符集 | UTF-8 |
spring.cloud.sentinel.metric.fileSingleSize | Sentinel 指标单个文件大小 | |
spring.cloud.sentinel.metric.fileTotalCount | Sentinel 指标总文件数 | |
spring.cloud.sentinel.log.dir | Sentinel 日志文件的目录 | |
spring.cloud.sentinel.log.switch-pid | 如果 Sentinel 日志文件名需要 PID | false |
spring.cloud.sentinel.servlet.blockPage | 自定义重定向 URL。当速率受限时,请求将被重定向到预定义的 URL | |
spring.cloud.sentinel.flow.coldFactor | 限流—冷启动 | 3个 |
spring.cloud.sentinel.scg.fallback.mode | Spring Cloud Gateway 断路后的响应方式(选择redirect或response) | |
spring.cloud.sentinel.scg.fallback.redirect | Spring Cloud Gateway响应方式为’redirect’方式对应的重定向URL | |
spring.cloud.sentinel.scg.fallback.response-body | Spring Cloud Gateway响应方式为’response’模式对应的响应内容 | |
spring.cloud.sentinel.scg.fallback.response-status | Spring Cloud Gateway响应模式为’response’模式对应的响应码 | 429 |
spring.cloud.sentinel.scg.fallback.content-type | Spring Cloud Gateway 响应模式是’response’模式对应的content-type。 | application/json |
这些配置只会在 servlet 环境中生效。RestTemplate 和 Feign 不会对这些配置生效。
6. Spring Cloud Alibaba RocketMQ 绑定器
6.1. RocketMQ简介
RocketMQ是一个开源的分布式消息系统。它基于高可用的分布式集群技术,提供低延迟、高稳定性的消息发布和订阅服务。RocketMQ广泛应用于各种行业,如异步通信解耦、企业解决方案、金融结算、电信、电子商务、物流、营销、社交媒体、即时通讯、移动应用、手游、视频、物联网、以及车联网。
它具有以下特点:
- 严格的消息发送和消费顺序
- 丰富的消息拉取方式
- 消费者的水平可扩展性
- 实时消息订阅
- 亿级消息积累能力
6.2. RocketMQ 用法
- 下载RocketMQ
下载+ message.getPayload()); }});// Message sendingmessageChannel.send(MessageBuilder.withPayload(“simple msg”).build());此代码中的所有消息类型均由 spring-messaging 模块提供。它屏蔽了消息中间件的底层实现。如果要更改消息中间件,只需要在配置文件中配置相关的消息中间件信息,修改binder依赖即可。
Spring Cloud Stream的下层也是在前面代码的基础上实现了各种代码抽象。
6.4. Spring Cloud Alibaba RocketMQ Binder使用方法
要使用 Spring Cloud Alibaba RocketMQ Binder,您只需将其添加到您的 Spring Cloud Stream 应用程序中,使用以下 Maven 坐标:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-stream-binder-rocketmq</artifactId></dependency>
或者,您也可以使用 Spring Cloud Stream RocketMQ Starter:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-stream-rocketmq</artifactId></dependency>
6.5. Spring Cloud Alibaba RocketMQ Binder 的工作原理
这是Spring Cloud Stream RocketMQ Binder的实现架构:
图 5. SCS RocketMQ 绑定器RocketMQ Binder的实现依赖于RocketMQ-Spring框架。
RocketMQ Spring 框架是 RocketMQ 和 Spring Boot 的集成。它提供了三个主要功能:
- RocketMQTemplate:发送消息,包括同步消息、异步消息和事务消息。
- @RocketMQTransactionListener:收听并检查交易消息。
- @RocketMQMessageListener:消费消息。
RocketMQMessageChannelBinderRocketMQInboundChannelAdapter是 Binder 的标准实现,它将在RocketMQMessageHandler内部构建。
RocketMQMessageHandler将RocketMQTemplate基于 Binding 配置进行构建。RocketMQTemplate内部会将模块的org.springframework.messaging.Message消息类转换spring-messaging为RocketMQ的消息类org.apache.rocketmq.common .message.Message,然后发送出去。
RocketMQInboundChannelAdapter也会RocketMQListenerBindingContainer根据Binding配置进行构建,RocketMQListenerBindingContainer启动RocketMQConsumer接收消息。
RocketMQ Binder Application也可以用来配置rocketmq.**来触发RocketMQ Spring相关的AutoConfiguration
目前Binder支持设置相关的keyHeader来设置RocketMQ消息的属性。
例如 , , , , ,TAGS代表DELAYRocketMQTRANSACTIONAL_ARG消息KEYS对应的标签。WAIT_STORE_MSG_OKFLAG
MessageBuilder builder = MessageBuilder.withPayload(msg) .setHeader(RocketMQHeaders.TAGS, "binder") .setHeader(RocketMQHeaders.KEYS, "my-key") .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");Message message = builder.build();output().send(message);
或者使用 StreamBridge
MessageBuilder builder = MessageBuilder.withPayload(msg) .setHeader(RocketMQHeaders.TAGS, "binder") .setHeader(RocketMQHeaders.KEYS, "my-key") .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");Message message = builder.build();streamBridge.send("producer-out-0", message);
更多示例:[RocketMQ 示例](https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/rocketmq-example)
6.6. 配置选项
6.6.1. RocketMQ 绑定器属性
spring.cloud.stream.rocketmq.binder.name-server
RocketMQ Server的名称服务器(旧版本使用namesrv-addr配置项)。默认值:127.0.0.1:9876.
spring.cloud.stream.rocketmq.binder.access-key
阿里云账号的AccessKey。默认值:空。
spring.cloud.stream.rocketmq.binder.secret-key
阿里云账号的SecretKey。默认值:空。
spring.cloud.stream.rocketmq.binder.enable-msg-trace
为所有生产者和消费者启用消息跟踪功能。默认值:true.
spring.cloud.stream.rocketmq.binder.customized-trace-topic
消息跟踪的跟踪主题。默认值:RMQ_SYS_TRACE_TOPIC.
spring.cloud.stream.rocketmq.binder.access-channel
商业版rocketmq消息轨迹主题自适应,值为CLOUD默认值:空。
6.6.2. RocketMQ 消费者属性
以下属性仅适用于 RocketMQ 生产者,并且必须以spring.cloud.stream.rocketmq.bindings..consumer…
使能够
启用消费者绑定。默认值:true.
标签
消费者订阅标签表达式,标签由||.默认值:空。
数据库
消费者订阅sql表达式。默认值:空。
广播
控制消息方式,如果你想让所有的订阅者都收到消息所有的消息,广播是个不错的选择。默认值:false.
整齐的
同时或按顺序接收消息。默认值:false.
delayLevelWhenNextConsume
并发消费的消息消费重试策略:-1,不重试,直接放入DLQ
0,broker控制重试频率
>0,客户端控制重试频率
默认值:0.
暂停当前队列时间毫秒
消息消费重试有序消费的时间间隔。默认值:1000.
6.6.3. RocketMQ 提供者属性
以下属性仅适用于 RocketMQ 生产者,并且必须以spring.cloud.stream.rocketmq.bindings..producer…
使能够
启用生产者绑定。默认值:true.
团体
生产者团体名称。默认值:空。
最大消息大小
允许的最大消息大小(以字节为单位)。默认值:8249344.
事务性的
发送交易消息。默认值:false.
同步
以同步方式发送消息。默认值: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.
7. Spring Cloud Alibaba Cloud ANS
ANS(Application Naming Service)是 EDAS 的一个组件。Spring Cloud 阿里云ANS提供了符合Spring Cloud规范的商业版服务注册和发现,让您可以在本地开发应用,在云端运行。
EDAS 目前支持直接部署 Nacos Discovery 应用
7.1. 如何引入Spring Cloud阿里云ANS
如果你想在你的项目中使用 ANS,请使用 starter,group ID 为com.alibaba.cloud,artifact ID 为spring-cloud-starter-alicloud-ans。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-ans</artifactId></dependency>
7.2. 使用 ANS 注册服务
当客户端引入Spring Cloud AliCloud ANS Starter时,服务的IP、端口号、权限等元数据会自动注册到注册中心。客户端会与服务器保持心跳,以证明自己有能力正常提供服务。
下面是一个简单的例子。
@SpringBootApplication@EnableDiscoveryClient@RestControllerpublic class ProviderApplication { @RequestMapping("/") public String home() { return "Hello world"; } public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); }}
由于服务会注册到注册中心,所以我们需要配置注册中心的地址。我们还需要在application.properties中添加如下地址。
# The application name will be used as the service name, therefore it is mandatory.spring.application.name=ans-providerserver.port=18081# The following is the IP and port number of the registration center.spring.cloud.alicloud.ans.server-list=127.0.0.1spring.cloud.alicloud.ans.server-port=8080
现在注册中心还没有启动,所以如果你的应用程序启动了,你会得到一个错误信息。因此,请在开始申请之前启动注册中心。
7.3. 启动注册中心
ANS 使用两种类型的注册中心。一个是免费的轻量级配置中心,一个是云端注册中心,通过EDAS提供。通常,您可以使用轻量级版本进行应用开发和本地测试,使用 EDAS 进行canary部署或生产。
7.3.1. 启动轻量配置中心
轻量级配置中心的下载安装方法参见Configure轻量级配置中心。
您只需要执行步骤1(下载轻量级配置中心)和步骤2(启动轻量级配置中心)。如果您同时使用 ANS,则不需要步骤 3(配置主机)。
启动轻量级配置中心后,直接启动ProviderApplication,即可将服务注册到配置中心。轻量级配置中心默认端口为8080,因此打开http://127.0.0.1:8080,点击左侧的“服务”,即可看到注册的服务。
7.3.2. 云端用户注册中心
使用云端注册中心,让您免去繁琐的服务器维护工作,同时提供更好的稳定性。使用云端注册中心和轻量级配置中心在代码层面没有区别,只是在配置上有一些区别。
下面是使用云端注册中心的简单示例。
# The application name will be used the service name, and is therefore mandatory.spring.application.name=ans-provider# Configure your own port numberserver.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=EDASspring.cloud.alicloud.access-key=Your Alibaba Cloud AKspring.cloud.alicloud.secret-key=Your Alibaba Cloud SKspring.cloud.alicloud.edas.namespace=cn-xxxxx
server-mode 的默认值为 LOCAL。如果要使用云端的注册中心,需要改成EDAS。
access-key和secret-key就是你阿里云账号的AK/SK。先注册一个阿里云账号,登录云控制台阿里云AK/SK 复制你的AccessKey ID和Access Key Secret。如果您还没有创建,请单击“创建 AccessKey”按钮。
命名空间是 EDAS 中的一个概念,用来隔离环境,比如测试环境和生产环境。要找到您的命名空间,请先单击以注册 EDAS。按量付费模式不会向您收费。然后登录EDAS 控制台,就可以看到你的命名空间,比如 cn-hangzhou。
EDAS 提供应用托管服务,会自动为托管的应用填写所有配置。
8. Spring Cloud阿里云ACM
Spring Cloud AliCloud ACM是商业产品应用配置管理(ACM)在Spring Cloud客户端的一个实现,是免费的。
使用Spring Cloud AliCloud ACM基于Spring Cloud的编程模型快速接入ACM配置管理能力。
目前 EDAS 已经支持直接部署 Nacos Config 应用。
8.1. 如何引入Spring Cloud阿里云ACM
如果你想在你的项目中使用 ACM,请使用 starter,group ID 为com.alibaba.cloud,artifact ID 为spring-cloud-starter-alicloud-acm。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-acm</artifactId></dependency>
8.2. 使用 ACM 管理配置
客户端引入Spring Cloud Alibaba Cloud ACM Starter后,应用启动时会自动从配置管理服务器获取配置信息,并将配置注入到Spring Environment中。
下面是一个简单的例子。
@SpringBootApplicationpublic 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 中添加以下信息。
# Required. The application name will be used as part of the keyword to get the configuration key from the server.spring.application.name=acm-configserver.port=18081# The following is the IP and port number of the configuration server.spring.cloud.alicloud.acm.server-list=127.0.0.1spring.cloud.alicloud.acm.server-port=8080
现在配置中心还没有启动,所以如果你的应用程序启动你会得到一个错误信息。因此,请在启动应用程序之前启动配置中心。
8.2.1. 启动配置中心
ACM 使用两种类型的配置中心。一个是轻量级配置中心,一个是阿里云上用的ACM。通常,您可以使用轻量级版本进行应用程序开发和本地测试,使用 ACM 进行金丝雀部署或生产。
使用轻量配置中心
轻量级配置中心的下载安装方法参见Configure轻量级配置中心。您只需要执行步骤1(下载轻量级配置中心)和步骤2(启动轻量级配置中心)。
在阿里云上使用 ACM
在云端使用ACM,让您免去繁琐的服务器维护工作,同时提供更好的稳定性。在云端使用ACM和轻量级配置中心在代码层面没有区别,只是在配置上有一些区别。以下是使用 ACM 的简单示例。您可以在ACM 控制台上查看配置详细信息
# 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 numberserver.port=18081# The following is the IP and port number of the configuration center.spring.cloud.alicloud.acm.server-mode=EDASspring.cloud.alicloud.access-key=Your Alibaba Cloud AKspring.cloud.alicloud.secret-key=Your Alibaba Cloud SKspring.cloud.alicloud.acm.endpoint=acm.aliyun.comspring.cloud.alicloud.acm.namespace=Your ACM namespace(You can find the namespace on the ACM console)
EDAS 提供应用托管服务,会自动为托管的应用填写关于 ACM 的所有配置。
8.2.2. 在配置中心添加配置
- 启动轻量级配置中心后,在控制台添加如下配置。
Group: DEFAULT_GROOUPDataId: acm-config.propertiesContent: user.name=james user.age=18
dataId 的格式为{prefix}. {file-extension}. “prefix”默认从spring.application.name中获取,“file-extension”的值默认为“properties”。
8.2.3. 开始申请验证
启动下面的例子,可以看到控制台打印的值就是我们在轻量级配置中心配置的值。
user name :james; age: 18
8.3. 修改配置文件扩展名
spring-cloud-starter-alicloud-acm中dataId默认的文件扩展名为properties。除了属性之外,还支持 yaml。您可以使用 spring.cloud.alicloud.acm.file-extension 设置文件扩展名。只需将其设置为yaml或
yml
即可使用 yaml 格式。
修改文件扩展名后,需要在配置中心的DataID和内容中做相应的格式修改。
8.4. 动态配置刷新
spring-cloud-starter-alicloud-acm 支持动态配置更新。Spring的RefreshEvent是在配置中心更新配置时发布的。所有带有@RefreshScope 和@ConfigurationProperties 注解的类都会自动刷新。
您可以通过此设置禁用自动刷新:spring.cloud.alicloud.acm.refresh.enabled=false
8.5. 配置配置文件粒度
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 中添加以下内容。
spring.profiles.active={配置文件名称}
注意:也可以通过JVM参数配置粒度,比如-Dspring.profiles.active=develop或者–spring.profiles.active=develop,优先级更高。只需遵循 Spring Boot 的规范即可。
8.6. 支持自定义 ACM 超时
ACM 客户端从服务器获取配置的默认超时为 3000 毫秒。如果需要定义超时,设置配置spring.cloud.alicloud.acm.timeout,单位是毫秒。
8.7. 支持自定义组配置
{spring.cloud.alicloud.acm.group}没有定义配置时默认使用 DEFAULT_GROUP 。如果需要定义自己的组,可以使用下面的方法:
spring.cloud.alicloud.acm.group=DEVELOP_GROUP
这个配置必须放在bootstrap.properties文件中,并且Group的值必须和.的值一样spring.cloud.alicloud.acm.group。
8.7.1. 支持共享配置
ACM 提供了一种跨多个应用程序共享相同配置的解决方案。您可以通过spring.application.group在 Bootstrap 中添加配置来完成此操作。
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} 越靠后的优先级越高,应用本身的独特配置具有最高的优先级。
DataId默认后缀为properties,可以使用spring.cloud.alicloud.acm.file-extension更改。{spring.application.group}: {spring.application.name}. {file-extension}.
如果你配置spring.profiles.active了,那么{spring.application.group}: {spring.application.name}-{spring.profiles.active}. {file-extension}也支持的DataId格式,优先级高于{spring.application.group}: {spring.application.name}. {file-extension}
8.8. 执行器端点
ACM的Actuator端点为/acm,config表示ACM元数据配置信息,runtime.sources对应从ACM服务器获取的配置信息和上次刷新时间,runtime.refreshHistory对应动态刷新历史。
9. Spring Cloud阿里云OSS
OSS(Object Storage Service)是阿里云上的一款存储产品。Spring Cloud阿里云OSS提供符合Spring Cloud规范的商业化存储服务。我们提供简单易用的API,支持在Spring框架中集成Resource。
9.1. 如何引入Spring Cloud阿里云OSS
我们发布了 Spring Cloud Alibaba 版本 0.2.1。您需要先添加依赖管理 POM。
<dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.2.2.BUILD-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
接下来需要介绍一下Spring Cloud阿里云OSS Starter。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-oss</artifactId></dependency>
9.2. 如何使用 OSS API
9.2.1. 配置OSS
在开始使用Spring Cloud阿里云OSS之前,请在application.properties中添加如下配置。
spring.cloud.alicloud.access-key=Your Alibaba Cloud AKspring.cloud.alicloud.secret-key=Your Alibaba Cloud SKspring.cloud.alicloud.oss.endpoint=***.aliyuncs.com
access-key和secret-key就是你阿里云账号的AK/SK。如果没有,请先注册一个账号,登录阿里云AK/SK管理获取您的 AccessKey ID 和 Access Key Secret 。如果您还没有创建 AccessKey,请单击“创建 AccessKey”来创建一个。
有关端点信息,请参阅 OSS文档并获取您所在地区的端点。
9.2.2. 介绍OSS API
Spring Cloud阿里云OSS的OSS API基于官方OSS SDK,包含上传、下载、查看文件的API。
这是一个使用 OSS API 的简单应用程序。
@SpringBootApplicationpublic 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); }}
在上传文件之前,请先 注册一个阿里云账号。如果您已经有一个,请 注册 OSS。
登录OSS控制台,点击“新建Bucket”,按照提示创建一个Bucket。将先前代码的“bucketname”中的存储桶名称替换为您的新存储桶名称。“fileName”可以是任意名称,“/your/local/file/path”可以是任意本地文件路径。接下来你可以运行 curl http://127.0.0.1:port number/ 来上传你的文件,你会在OSS 控制台看到你的文件。
更多OSS API说明请参考OSS SDK文档。
9.3. 与 Spring 的资源规范集成
Spring Cloud阿里云OSS集成了Spring框架的Resource,让您轻松使用OSS资源。
以下是如何使用资源的简单示例。
@SpringBootApplicationpublic 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); }}
上述示例的前提条件是您需要在OSS上有一个名为“bucketName”的bucket,并且在这个bucket中有一个名为“fileName”的文件。
9.4. 使用 STS 认证
除了AccessKeys,Spring Cloud阿里云OSS还支持STS认证。STS是一种带有临时安全令牌的认证方式,通常用于第三方临时访问其资源。
第三方临时访问资源,只需要完成以下配置即可。
spring.cloud.alicloud.oss.authorization-mode=STSspring.cloud.alicloud.oss.endpoint=***.aliyuncs.comspring.cloud.alicloud.oss.sts.access-key=Your authenticated AKspring.cloud.alicloud.oss.sts.secret-key=Your authenticated SKspring.cloud.alicloud.oss.sts.security-token=Your authenticated ST
其中spring.cloud.alicloud.oss.authorization-mode为枚举类型。这里填写STS表示使用STS认证。有关端点信息,请参阅OSS 文档并填写您所在地区的端点。
access-key、secret-key和security-token需要认证方下发。有关 STS 的更多信息,请参阅STS 文档。
9.5. 客户端的更多配置
Spring Cloud Alibaba Cloud OSS 除了基础配置外,还支持很多其他的配置,这些配置也包含在application.properties 文件中。
这里有些例子。
spring.cloud.alicloud.oss.authorization-mode=STSspring.cloud.alicloud.oss.endpoint=***.aliyuncs.comspring.cloud.alicloud.oss.sts.access-key=Your authenticated AKspring.cloud.alicloud.oss.sts.secret-key=Your authenticated SKspring.cloud.alicloud.oss.sts.security-token=Your authenticated STspring.cloud.alicloud.oss.config.connection-timeout=3000spring.cloud.alicloud.oss.config.max-connections=1000
更多配置请参考OSSClient Configurations底部的表格。
大多数情况下, OSSClient Configurations 表中的参数需要用“-”连接参数名,且字母全部小写。例如,ConnectionTimeout 应该更改为 connection-timeout。
10.Spring Cloud阿里云SchedulerX
SchedulerX(分布式作业调度)是阿里云产品EDAS的一个组件。Spring Cloud Alibaba Cloud SchedulerX 提供了符合Spring Cloud规范的分布式作业调度。SchedulerX提供高精度秒级、高稳定性、高可用的定时作业调度服务,支持简单单机作业、简单多机作业、脚本作业、网格作业等多种作业类型。
10.1. 如何引入Spring Cloud Alibaba Cloud SchedulerX
如果你想在你的项目中使用 SchedulerX,请使用组 ID 为com.alibaba.cloudartifact ID 为的 starter spring-cloud-starter-alicloud-schedulerX。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-schedulerX</artifactId></dependency>
10.2. 启动调度器X
客户端引入Spring Cloud Alibaba Cloud SchedulerX Starter后,只需要完成一些简单的配置,就可以自动初始化SchedulerX服务。
下面是一个简单的例子。
@SpringBootApplicationpublic class ScxApplication { public static void main(String[] args) { SpringApplication.run(ScxApplication.class, args); }}
在application.properties文件中添加如下配置。
server.port=18033# cn-test is the test region of SchedulerXspring.cloud.alicloud.scx.group-id=***spring.cloud.alicloud.edas.namespace=cn-test
在获取group-id之前,请先注册一个阿里云账号,然后注册EDAS和注册SchedulerX。
要获取组 ID,请参阅SchedulerX 文档。
创建群组时,请选择“测试”区域。
10.3. 编译一个简单的作业
简单作业是最常用的作业类型。您只需要实现 ScxSimpleJobProcessor 接口。
以下是一个简单的单服务器作业示例。
public class SimpleTask implements ScxSimpleJobProcessor {@Overridepublic ProcessResult process(ScxSimpleJobContext context) {System.out.println("-----------Hello world---------------");ProcessResult processResult = new ProcessResult(true);return processResult;}}
10.4. 作业调度
进入SchedulerX Jobs页面,选择“Test”区域,点击右上角的“Create Job”创建一个Job,如下图。
Job Group: Test——***-*-*-****Job process interface:SimpleTaskType: Simple Single-Server JobQuartz Cron Expression: Default Option——0 * * * * ?Job Description: EmptyCustom Parameters: Empty
上面的作业是一个“简单的单服务器作业”,并指定了一个 Cron 表达式“0 * * * * ?” . 这意味着该作业将每分钟执行一次且仅执行一次。
有关更多作业类型,请参阅SchedulerX 文档。
10.5. 在生产环境中的使用
前面的例子展示了如何在“Test”区域使用SchedulerX,主要用于本地测试。
在生产层面,除了上面提到的group-id和namespace,还需要完成一些其他的配置。请参阅以下示例:
server.port=18033# cn-test is the test region of SchedulerXspring.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=***
group-id 的获取方式与前面的示例相同,您可以通过点击 EDAS 控制台左侧导航栏中的“命名空间”获取命名空间。
Group-id 必须在命名空间内创建。
access-key和secret-key就是你阿里云账号的AK/SK。如果您在 EDAS 上部署您的应用程序,则无需填写此信息。否则,请转到 安全信息以获取您的访问密钥。域名不是强制性的。详情可参考 SchedulerX 文档。
11. Spring Cloud 阿里云短信
SMS(Short Message Service)是覆盖全球的消息服务,阿里巴巴短信提供便捷、高效、智能的通讯能力,帮助商家快速联系客户。
Spring Cloud Alibaba Cloud SMS基于Spring Cloud Alibaba SMS,提供更易用的API,用于快速接入阿里云的短信服务。
11.1. 如何引入Spring Cloud阿里云短信
如果你想在你的项目中使用 SMS,请使用组 ID 为com.alibaba.cloudartifact ID 为的 starter spring-cloud-starter-alicloud-sms。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-sms</artifactId></dependency>
11.2. 如何使用短信API
11.2.1. 配置短信
在开始使用Spring Cloud阿里云短信之前,请在application.properties中添加如下配置。
spring.cloud.alicloud.access-key=AKspring.cloud.alicloud.secret-key=SK
access-key和secret-key就是你阿里云账号的AK/SK。如果没有,请先注册一个账号,登录阿里云AK/SK管理获取您的 AccessKey ID 和 Access Key Secret 。如果您还没有创建 AccessKey,请单击“创建 AccessKey”来创建一个。
11.2.2. 引入短信API
Spring Cloud阿里云短信中的短信API基于阿里云短信SDK。具有单条短信发送、多条短信批量发送、短信查询、短信(短信回执消息和上行短信)类操作API。
下面是一个简单的例子,说明如何使用SMS api发送短信:
@SpringBootApplicationpublic 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); }}
在发送消息之前,请先注册一个阿里云账号。如果您已经有一个,请 打开短信服务。
关于SMS的更多信息,请参考SMS官方短信(SendSms)—JAVA]文档。
由于较早的SMS sdk版本问题,如果发送短信失败,请删除显式MethodType为POST的代码行。如果仍有问题,请尽快与我们联系。
11.3. SMS Api 的高级功能
为了降低学习成本,Spring Cloud阿里云短信包的API接口与官网提供的API和Example保持一致。
- 批量发送短信
参考以下示例快速开发批量发送短信的功能。在Controller中添加如下代码或者新建一个Controller:
@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 ;}
请求的MethodType设置为GET,和官网给出的例子有些区别。这是因为依赖的阿里云POP API版本不一致导致不兼容问题,设置为GET。
更多参数说明可以参考这里- 短信查询
参考下面的例子,快速开发一个根据指定号码发送短信的历史记录。在Controller中添加如下代码或者新建一个Controller:
@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();}
更多参数说明可以参考这里
- 短信回执信息
通过订阅SmsReport短信状态报告,您可以了解每条短信的状态,以及是否知晓终端用户的状态及相关信息。这些努力都被Spring Cloud阿里云短信内部封装了。您只需要完成以下两个步骤。
- 在配置文件中配置SmsReport的队列名称application.properties(也可以是application.yaml)。
application.properties
spring.cloud.alicloud.sms.report-queue-name=Alicom-Queue-********-SmsReport
- 实现SmsReportMessageListener接口并初始化一个Spring Bean。
@Componentpublic class SmsReportMessageListenerimplements SmsReportMessageListener {@Overridepublic boolean dealMessage(Message message) { //do somethingSystem.err.println(this.getClass().getName() + "; " + message.toString());return true;}}
更多Message的消息体格式可以参考这里。
- 上行短信
通过订阅SmsUp上行短信,可以知道终端用户回复短信的内容。这些努力也被Spring Cloud阿里云短信打包了。您只需要完成以下两个步骤。
- 在配置文件中配置SmsReport的队列名称application.properties(也可以是application.yaml)。
spring.cloud.alicloud.sms.up-queue-name=Alicom-Queue-********-SmsUp
- 实现SmsUpMessageListener接口,初始化一个Spring Bean。
@Componentpublic class SmsUpMessageListenerimplements org.springframework.cloud.alicloud.sms.SmsUpMessageListener {@Overridepublic boolean dealMessage(Message message) { //do somethingSystem.err.println(this.getClass().getName() + "; " + message.toString());return true;}}
更多Message的消息体格式可以参考这里。