Spring Cloud alibaba
1.引言
目前Spring Cloud进入了维护模式,而Spring Cloud alibaba对Spring Cloud做了封装,使用起来更简单。包含的功能有服务限流降级、服务注册于发现、分布式配置管理、消息驱动能力、阿里云对象存储、分布式任务调度等。
参考文档:
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
源代码:https://github.com/zhongyushi-git/spring-cloud-alibaba-demo.git
2.Nacos
一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。是注册中心与配置中心的组合。官网:https://nacos.io/zh-cn/index.html
2.1下载
打开https://github.com/alibaba/nacos/releases下载需要的版本,这里以1.1.4版本为例说明。
2.2安装
2.2.1在windows系统安装
下载压缩包后解压即可使用。进入bin目录,双击startup.cmd看到下图说明运行成功。
默认是以集群方式启动,若启动报错,那么需要修改为单机版启动,在bin目录打开cmd,输入下面的命令进行启动。
startup.cmd -m standalone
访问http://localhost:8848/nacos,登录用户名和密码都是nacos。登录之后的页面如下,可以看到相关想信息。
2.2.2在Linux系统安装
把下载好的压缩上传制到Linux后解压
tar -zxvf nacos-server-1.1.4.tar.gz -C /usr/local
解压之后单机版启动,启动之后在浏览器访问nacos首页,同上。
bash startup.sh -m standalone
2.3基础环境搭建
创建maven的父工程spring-cloud-alibaba-demo,删除src目录。导入依赖,进行版本锁定
<!--统一管理jar包版本--> <properties> <spring.boot.version>2.2.2.RELEASE</spring.boot.version> <spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version> <spring.cloud.version>Hoxton.SR1</spring.cloud.version> </properties> <!-- 依赖管理,父工程锁定版本--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2.4服务注册
1)创建服务提供者子模块cloud-alibaba-provider8001,导入依赖
<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> <!--springcloud alibaba nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
2)application.yml配置
server: port: 8001 spring: application: name: cloud-alibaba-nacos-provider cloud: #配置nacos地址 nacos: #服务器地址 server-addr: 127.0.0.1:8848 #服务注册与发现地址 discovery: server-addr: ${spring.cloud.nacos.server-addr} #开启端口暴露 management: endpoints: web: exposure: include: "*"
3)创建启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class NacosProviderMain8001 { public static void main(String[] args) { SpringApplication.run(NacosProviderMain8001.class,args); } }
4)创建controller接口
package com.zys.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Value("${server.port}") private String port; @GetMapping("/user/get") public String get() { return "provider port is :" + port; } }
5)启动服务提供者,在nacos页面的服务列表中可以看到服务已注册进来。那么此时服务的注册就已完成,非常简单。
6)同理,按照cloud-alibaba-provider8001方式创建服务提供者子模块cloud-alibaba-provider8002,端口为8002。启动后发现nacos中服务的集群数目变成了2。
2.5服务调用
nacos并不提供服务调用的方法,因此还需要使用SpringCloud的方式进行调用,这里使用OpenFeign进行说明(关于OpenFeign的用法其他文章已介绍)。
1)创建服务消费者子模块cloud-alibaba-consumer80,导入依赖
<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> <!--springcloud alibaba nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
2)application.yml配置
server: port: 80 spring: application: name: cloud-alibaba-nacos-consumer cloud: #配置nacos地址 nacos: #服务器地址 server-addr: 127.0.0.1:8848 #服务注册与发现地址 discovery: server-addr: ${spring.cloud.nacos.server-addr} feign: client: config: #指定全局 default: #连接超时时间 connectTimeout: 5000 #服务等待时间 readTimeout: 5000 loggerLevel: full logging: level: com.zys.cloud.client.UserClient: debug
虽然是调用别的服务,但也需要把自身服务注册到nacos.
3)创建启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ConsumerMain80 { public static void main(String[] args) { SpringApplication.run(ConsumerMain80.class, args); } }
4)创建Client接口,用于接口映射
package com.zys.cloud.client; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(value = "cloud-alibaba-nacos-provider") public interface UserClient { @GetMapping("/user/get") String get(); }
5)创建controller接口
package com.zys.cloud.controller; import com.zys.cloud.client.UserClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/consumer") public class UserController { @Autowired private UserClient userClient; @GetMapping("/get") public String get() { return userClient.get(); } }
6)启动服务,可以在nacos页面的服务列表中看到两个注册的服务。
访问http://localhost/consumer/get,看到是8001和8002进行轮询负载的。是因为nacos默认支持负载均衡,原因是它默认引入了ribbon。
2.6服务配置
2.6.1基本配置
为了不改动上述的代码,这里新建一个模块说明服务的配置,原理是一样的。
1)创建配置的客户端子模块cloud-alibaba-config-client,导入依赖
<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> <!--springcloud alibaba nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> </dependencies>
这里同时引入了服务注册和服务配置的依赖。作为客户端,当然需要注册到nacos,而配置又是此服务必不可少的。
2)yml配置
bootstrap.yml:系统级别的配置,主要配置配置中心的相关信息。
spring: cloud: nacos: #服务器地址 server-addr: 127.0.0.1:8848 discovery: server-addr: ${spring.cloud.nacos.server-addr} config: #配置中心地址 server-addr: ${spring.cloud.nacos.server-addr} #指定配置的格式,有yaml和properties两种 file-extension: yaml
application.yml:主要配置服务的名称及激活的配置文件
spring: application: name: nacos-config-client profiles: active: dev
3)创建启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class NacosConfigClientMain { public static void main(String[] args) { SpringApplication.run(NacosConfigClientMain.class,args); } }
4)创建controller接口
package com.zys.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController //动态刷新 @RefreshScope public class UserController { @Value("${config.info}") private String info; @GetMapping("/config/get") public String get() { return "The config info is :" + info; } }
需要注意的是,这里在类上加了@RefreshScope
注解,用于自动刷新。若不添加,则无法进行自动的配置刷新。
5)创建统一的配置文件
在创建之前,先了解一些dataID的命名规则,它的完整格式为${prefix}-${spring.profile.active}.${file-extension}。
prefix :默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
spring.profile.active :即为当前环境对应的 profile。
file-exetension: 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
假如spring.application.name=nacos-config-client
,环境为dev,后缀名是yaml,那么dataID就是nacos-config-client-dev.yaml
。这里不存在主/从配置文件的说法,只指定不同环境的配置,公共的配置都放在自己的环境中。另外,dataId后缀必须是yaml或properties。
了解之后,就在nacos的配置管理页面新建一个配置文件,然后发布。
配置代码:
server: port: 3344 config: info: '我的名字叫张三'
6)测试
启动3344,访问http://localhost:3344/config/get,可以看到配置的信息。然后修改配置中的config.info
内容,再刷新页面,发现配置信息也更新了。此时就做到了配置实时刷新。
2.6.2分类配置
级别大小:namespace > Group > dataId。
1)dataId方案
一个dateId就是一个配置文件。在nacos页面再创建一个配置文件,作为测试环境配置
修改application.yml的环境为test。
重启后访问http://localhost:3355/config/get,可以看到test环境的配置信息。
2)Group方案
在上述的章节中,并没有去指定Group,而是采用的默认的名称DEFAULT_GROUP,如果需要自定义分组名称,则在创建配置时指定分组名即可,不过需要在bootstrap.yml在指定组名。
新建一个配置文件,分组名为GROUP_TEST
修改application.yml的环境为info,然后在bootstrap.yml指定组名
重启后访问http://localhost:3344/config/get,可以看到info环境的配置信息。
3)namespace方案
用于区分不同的部署环境,实现隔离。命名空间是最大的,需要设置的话就创建命名空间(id一般不指定,自动生成即可),在配置文件中指定创建的命名空间的id即可。
2.7持久化配置
nacos默认自带的是嵌入式数据库derby,持久化就需要切换到MySQL,MySQL版本5.7以上。
1)执行sql脚本
在下载的nacos文件夹中,nacos-server-1.1.4\nacos\conf\nacos-mysql.sql即是sql脚本,先创建一个名为nacos的数据库,然后执行这个脚本即可。
2)修改配置文件
打开nacos-server-1.1.4\nacos\conf\application.properties,在最后添加
#增加支持mysql数据源配置 spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=root db.password=123456
3)启动测试
重启nacos,发现之前配置的信息没有了,原因是MySQL中并没有进行配置。这时在nacos页面创建一个名为nacos-config-client-info.yaml的配置文件如下:
启动服务配置客户端,访问http://localhost:3344/config/get,可以看到info环境的配置信息。其配置信息在表config_info中可看到。
2.8集群配置
在搭建集群之前,默认在Linux已安装完成nocas。另外,nginx单机版也在Linux搭建完成,用于负载均衡nacos服务,MySQL在Linux已安装完成(MySQL版本5.7+)。
1)执行sql脚本(同上一小节)
2)配置nacos数据源,修改application.properties文件,在最后添加
#增加支持mysql数据源配置 spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=root db.password=123456
3)获取本机的ip
hostname -i
4)配置cluster.conf
打开文件
cp cluster.conf.example cluster.conf vim cluster.conf
把内容修改如下:
172.16.68.248:8849 172.16.68.248:8850 172.16.68.248:8851
需要注意的是,这里的ip必须是上一步获取的本机ip。
5)修改startup.sh启动文件
vim startup.sh
修改的文件前后对比,主要添加了启动的端口号
6)启动集群
./startup.sh -p 8849 ./startup.sh -p 8850 ./startup.sh -p 8851
在启动的时候,遇到了一个大坑,就是安装的jdk必须手动配置java_home,否则会报错。
3.Sentinel
学习地址:https://github.com/alibaba/Sentinel/wiki/介绍。
Sentinel主要从流量控制、熔断降级、系统负载保护维度保护服务的稳定性。
3.1下载与安装
1)下载地址https://github.com/alibaba/Sentinel/releases,选择对应的版本下载即可。这里以1.8.2版本为例
可以下载压缩包,也可以直接下载jar。本章节在Windows中说明,就直接下载jar进行说明。
2)下载到本地后,在其目录下打开cmd,输入命令
java -jar sentinel-dashboard-1.7.2.jar
3)在浏览器访问http://localhost:8080,看到下面的页面说明安装成功。
用户名和密码都是sentinel。
4)登录后看到仪表盘是空的,因为现在没有监控任何的服务。
3.2初始化监控
为了不改动上述的代码,这里新建一个模块进行说明,原理是一样的。
1)创建一个模块cloud-alibaba-sentinel,导入依赖
<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> <!--springcloud alibaba nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--springcloud alibaba sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
2)配置application.yml,简单起见,配置文件在本地进行配置
server: port: 8401 spring: application: name: cloud-alibaba-sentinel-service cloud: nacos: server-addr: 127.0.0.1:8848 discovery: server-addr: ${spring.cloud.nacos.server-addr} sentinel: transport: # sentinel dashboard的地址 dashboard: 127.0.0.1:8080 # sentinel dashboard内部通信端口,默认为8719,如果被占用会自动+1,直到找到为止 port: 8719 management: endpoints: web: exposure: include: "*"
3)创建启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class SentinelMain { public static void main(String[] args) { SpringApplication.run(SentinelMain.class, args); } }
4)创建controller
package com.zys.cloud.controller; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class FlowLimitController { @GetMapping("/testA") public String testA(){ return "--------testA"; } @GetMapping("/testB") public String testB(){ return "--------testB"; } }
5)测试。先启动nacos服务,再启动sentinel服务,再启动8401。访问http://localhost:8401/testA后会在仪表盘看到生成了一个服务:
将接口testA多调用几次,再看仪表盘
其中QBS表示1秒的请求数,QPS表示1秒的拒绝请求数。
原理:只要服务加入了Sentienl并进行了配置,那么在调用服务时,就会通过内部通信服务把日志信息发送给dashboard服务,其在页面上展示。因此只有的服务调用时dashboard才会进行初始化。
6)簇点链路
打开簇点链路的菜单,可以看到链路的信息,可操作的按钮包含流控、熔断、热点和授权,后续一一介绍。
3.2流控
流控:流量控制(flow control),其原理是监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
3.2.1阈值类型-QPS
QPS表示每秒的请求数。可在簇点链路中选择链路的点击流控按钮添加,也可在流控规则中添加。其他的功能类似。这里以/testA的流控为例:
上图的配置,也就是说对于请求/testA,当每秒请求的次数超过阈值,那么会直接返回失败的信息。保存后显示列表如下:
访问localhost:8401/testA结果是正常的,若快速的刷新几次,会发现返回了流控的信息:
对于针对来源,默认使用default,那么也可以指定来源,那么当指定的这个来源调用/testA请求时会进行流控,其他服务调用/testA时不进行流控,也就是对来源进行针对性的流控。
3.3.2阈值类型-并发线程数
当然也可设置并发线程的阈值,当某一时刻并发线程数量超过时会进行流控。
1)点击编辑,将/testA的阈值类型修改并发线程数
2)使用Jmeter对/testA发送超过阈值的并发请求,那么在发送的同时再访问/testA就会出现流控。
3.3.3 流控模式-关联
1)说明:前面的两种的流程模式都设置为直接,这种模式是默认的,也就是说流量控制规则到达阈值时直接触发流量控制。本小节说明关联模式,均以QPS类型说明,后同。
2)关联:当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。关联的关系是反向关联。
3)上述代码中的/testA和/testB就是关联关系,它们在同一个controller中,占用相同的资源,编辑配置如下:
使用Jmeter对/testB发送超过阈值的并发请求,那么在发送的同时再访问/testA就会出现流控。原因是两个请求相互争抢资源,进行了流控。
3.3.3 流控模式-链路
链路模式也就是对某一条链路进行流控。如用户服务会调用订单服务,商品服务也会调用订单服务,就存在两条链路。在某个时刻,对商品服务->订单服务这条链路进行流控,从而保证订单服务的正常使用,最终让用户服务可以正常调用订单服务,虽然限流了商品服务这条链路,但不影响用户服务这条链路。
3.3.4流控效果-快速失败
默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException
。前面已经使用过多次。
3.3.5流控效果-Warm Up
预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。它有一个冷加载因子,值是3。曲线图如下:
新加/testA的流控规则如下:
当1秒同时有20个请求,预热时间是10秒。那么服务会先处理7个请求(20/3),后面依次处理,当达到20秒时处理完所有的请求。
3.3.6流控效果-排队等待
让请求以均匀的速度通过。修改/testA的规则:
也就是说,当有大量的请求来时,每秒只处理20个请求,其他的请求进行排队等待,依次类推。当后面排队的时间超过5秒时就报错,显示流控信息。
3.3熔断降级
一个服务常常会调用别的模块,如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。而Sentinel在服务出现不稳定情况时,会对其进行限制,请求快速失败,避免影响到其他资源而导致级联错误。当资源被降级后,在接下来的时间窗口内,对该资源的调用都自动熔断。
3.3.1降级策略
(1)慢调用比例:当单位统计时长内请求数目大于设置的最小请求数目,并且平均响应时间超过最大RT的请求的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。
经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。
说明:在1000ms内请求数超过5个,且平均响应时间超过300ms的请求的比例(超过300ms的请求占总请求的比例)大于0.4,则该资源自动熔断10s。10s后根据下一个请求判断是否再次被熔断。
(2)异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。
经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。
说明:在1000ms内请求数超过5个,且异常的比例(异常的请求占总请求的比例)大于0.8,则该资源自动熔断15s。15s后根据下一个请求判断是否再次被熔断。
(3)异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。
经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求成功完成则结束熔断,否则会再次被熔断。
说明:在1000ms内请求数超过5个,且异常的请求超过6个,那么该资源将自动熔断20s。20s后根据下一个请求判断是否再次被熔断。
3.3.2注解@SentinelResource的使用
前面的所讲的流控或降级,其返回的数据都是 Blocked by Sentinel (flow limiting) ,当然可以自定义。@SentinelResource和@HystrixCommand的作用是类似的,都是来指定流控或降级时返回的信息。
在方法上加@SentinelResource注解,且使用blockHandler(或者blockHandlerClass)指定流控或降级时的自定义提示,而blockHandler函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数(类型是BlockException),且和原方法在同一个类中。使用fallback 指定未流控或降级发生异常时的自定义提示,其方法必须是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配。
下面通过对/testC进行流控和降级来说明:
1)流控配置:
2)降级配置:
3)后台代码:
@GetMapping("/testC") @SentinelResource(value = "aaa", blockHandler = "testCBlockHandler",fallback = "testCFallback") public String testC(Integer id) { if (id < 0) { throw new RuntimeException("参数值格式错误"); } return "--------testC"; } //自定义降级或熔断时的提示信息 public String testCBlockHandler(Integer id, BlockException exception) { //判断异常的类型 if (exception instanceof FlowException) { return "你被限流了,请稍后再试"; } else if (exception instanceof DegradeException) { return "你被降级了,请稍后再试"; } return "当前服务不可用"; } //自定义未限流时发生异常的提示信息 public String testCFallback(Integer id){ return "参数不合法"; }
在@SentinelResource指定了value,其值就是要流控或降级的资源名,必须配置。
当访问/testC?id=8时,快速刷新,会出现流控提示信息。
当问/testC?id=-5时,刷新1此,会出现错误提示信息。
当问/testC?id=-5时,刷新5次以上,会出现降级提示信息。
3.4规则持久化
你有没有发现,每次无论重启sentinel服务还是要监控的服务,sentinel页面的配置规则都会消失,这是因为这些规则没有持久化,对应大量的配置规则,持久化也非常重要,可将其配置到nacos中。
这里直接在cloud-alibaba-sentinel模块进行说明:
1)导入依赖
<!--springcloud alibaba sentinel-datasource-nacos--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
2)在yml配置,已存在配置省略:
spring: cloud: # 流控规则持久化到nacos datasource: dsl: nacos: server-addr: ${spring.cloud.nacos.server-addr} data-id: ${spring.application.name} group-id: DEFAULT_GROUP data-type: json rule-type: flow
3)在nacos中添加配置文件,如下图:
json内容:
[ { "resource": "/testA", "limitApp": "default", "grade": 1, "count": 5, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
可看到json中是一个数组,数组中只有一个元素,那么针对/test的请求的配置规则会存下来,不会因为重启而丢失,而其他的请求的配置规则还是丢失。针对这些请求,都按照这种规则配置在数组中即可。
4.Seata
官网:https://seata.io/zh-cn/index.html
一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。Seata是一种分布式事务的解决方案,在服务搭建正确的情况下,在业务上添加@GlobalTransactional
4.1术语(一ID+三组件模式)
1)XID:(Transaction ID)全局唯一的事务ID
1)TC:(Transaction Coordinator)事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚
2)TM:(Transaction Manager)控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议
3)RM:(Resource Manager)控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚
4.2处理过程
1)TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID
2)XID在微服务调用链路的上下文中传播
3)RM向TC注册分支事务,将其纳入XID对应全局事务的管辖
4)TM向TC发起针XID的全局提交或回滚决议
5)TC调度XID下管辖的全部分支事务完成提交或回滚请求。
4.3下载安装
1)下载地址:https://github.com/seata/seata/releases,下载对应版本即可。
5.微服务架构整合
相比之下,使用SpringCloud+SpringCloud alibaba效果会更好。整合的组件说明如下表:
微服务组件 | 框架 | 具体组件 |
服务注册 | SpringCloud alibaba | nacos |
服务调用 | SpringCloud | openfeign |
服务配置 | SpringCloud alibaba | nacos |
服务网关 | SpringCloud | gateway |
服务熔断和降级 | SpringCloud alibaba | sentinel |
服务负载均衡 | SpringCloud | Ribbon。默认已有 |
涉及到整合,那么两者的版本需要进行匹配并进行统一管理。