目录
2.SpringCloud和SpringCloudAlibaba
一.SpringCloudAlibaba介绍
1.SpringCloudAlibaba认识
1.1.为什么会出现SpringCloudAlibaba
早期在国内做分布式(微服务)应用Dubbo是比较热门的框架,被许多互联网公司所采用,并产生了许多衍生版本,如网易,京东,新浪,当当等等,奈何在2014年10月Dubbo停止维护,在Dubbo停更的时间里Spring Cloud快速追赶上。在2017年9月,阿里宣布重启Dubbo项目,计划对Dubbo进行持续更新维护。2018.2月,阿里将Dubbo捐献给Apache基金会,Dubbo成为Apache孵化器项目。
所以当前微服务架构,Dubbo和SpringCloud比较火,另外还有Thrift、gRPC等等 。很多人把SpringCloud 和Dubbo进行对比,其实两个框架并没有太大的可比性,因为他们的定位不同。Spring Cloud是一个完整的微服务解决方案,它提供了微服务各问题的解决方案集合,而Dubbo是一个高性能的RPC框架,它有着很多功能的缺失。
但是很多企业一边想要Dubbo的高性能RPC ,一边又想要Spring Cloud 完整的生态,然后在项目中出现了两个微服务框架的身影 。甚至市面上出现了一些Dubbo和Sprng Cloud的融合方案,但是最终都不是特别成熟。直到Spring Cloud官方出现了Spring Cloud Alibaba 才算是吧Dubbo和Spring Cloud真正的融合在一起。
1.2.什么是 Spring Cloud Alibaba
下面是Spring Cloud 官方对Spring Cloud Alibaba的介绍
Spring Cloud Alibaba旨在为微服务开发提供
一站式
解决方案。该项目包括开发分布式应用程序和服务所需的组件,以便开发人员可以使用Spring Cloud编程模型轻松开发分布式应用程序。使用Spring Cloud Alibaba,您只需要添加一些注释和配置,就可以为您的应用程序使用Alibaba的分布式解决方案,并使用Alibaba中间件构建自己的分布式系统。
Spring Cloud Alibaba其实是阿里的微服务解决方案
,是阿里巴巴结合自身微服务实践,开源的微服务全家桶
,在Spring Cloud项目中孵化成为Spring Cloud的子项目。第一代的Spring Cloud标准中很多组件已经停更,如:Eureak,zuul等。所以Spring Cloud Alibaba很有可能成为Spring Cloud第二代的标准实现,所以许多组件在业界逐渐开始使用,已有很多成功案例。
值得一提的是Spring Cloud Alibaba对Dubbo
做了很好的兼容,同时也提供了一些强大的功能,如 Sentinel 流控 ,Seata 分布式事务,Nacos 服务发现与注册
等等。
Spring Cloud Alibaba的功能
Spring Cloud Alibaba是阿里巴巴结合自身的微服务实践开源的微服务全家桶,我个人觉得其组件比Spring Cloud 中的组件更加好用和强大。并且对的Spring Cloud组件做了很好的兼容。比如在Spirng Cloud Alibaba中依然可以使用Feign作为服务调用方式,使用Eureak做服务注册发现等等。Spring Cloud Alibaba主要的功能如下:
-
流控制和服务降级:支持WebServlet,WebFlux,OpenFeign,RestTemplate,Dubbo访问限制和降级流的功能。它可以在运行时通过控制台实时修改限制和降级流的规则,并且还支持监视限制和降级度量标准。
-
服务注册和发现:可以注册服务,并且客户可以使用Spring托管的bean(自动集成功能区)发现实例。
-
分布式配置:支持分布式系统中的外部配置,配置更改时自动刷新。
-
Rpc服务:扩展Spring Cloud客户端RestTemplate和OpenFeign以支持调用Dubbo RPC服务。
-
事件驱动:支持构建与共享消息系统连接的高度可扩展的事件驱动微服务。
-
分布式事务:支持高性能且易于使用的分布式事务解决方案。
-
阿里云对象存储:大规模,安全,低成本,高度可靠的云存储服务。支持随时随地在任何应用程序中存储和访问任何类型的数据。
-
阿里云SchedulerX:准确,高度可靠,高可用性的计划作业调度服务,响应时间在几秒钟内。
-
阿里云短信:阿里云短信服务覆盖全球,提供便捷,高效,智能的通信功能,帮助企业快速联系客户。
2.SpringCloud和SpringCloudAlibaba
2.1.两代技术对比
下面是SpringCloud 和 Spring Cloud Alibaba(命名 Dubbo Spring Cloud )的功能对比
功能组件 | Spring Cloud | Dubbo Spring Cloud |
---|---|---|
分布式配置(Distributed configuration) | Git、Zookeeper、Consul、JDBC | Spring Cloud 分布式配置 + Dubbo 配置中心(Nacos) |
服务注册与发现(Service registration and discovery) | Eureka、Zookeeper、Consul | Spring Cloud 原生注册中心 + Dubbo 原生注册中心(Nacos) |
负载均衡(Load balancing) | Ribbon(随机、轮询等算法) | Dubbo 内建实现(随机、轮询等算法 + 权重等特性) |
服务熔断(Circuit Breakers) | Spring Cloud Hystrix | Spring Cloud Hystrix + Alibaba Sentinel 等 |
服务调用(Service-to-service calls) | Open Feign、RestTemplate | Spring Cloud 服务调用 + Dubbo @Reference |
链路跟踪(Tracing) | Spring Cloud Sleuth + Zipkin | Zipkin、opentracing 等 |
2.2.Spring Cloud Alibaba的版本
Spring Cloud Alibaba是Spring Cloud的子项目 ,Spring Cloud 基于Spring Boot,所以我们在选择版本的时候需要考虑三个框架的版本,目前官方给出的版本如下:
Spring Cloud Version | Spring Cloud Alibaba Version | Spring Boot Version |
---|---|---|
Spring Cloud Greenwich | 2.1.x.RELEASE | 2.1.x.RELEASE |
Spring Cloud Finchley | 2.0.x.RELEASE | 2.0.x.RELEASE |
Spring Cloud Edgware | 1.5.x.RELEASE | 1.5.x.RELEASE |
二.Nacos服务注册与发现
1.Nacos认识与安装
1.1.什么是Nacos
在《Spring Cloud 极简入门》中我们学习了netflix 的 Eureka 组件作为微服务的服务发现。Nacos和Eureka有着相同的能力,甚至更为强大,作为Dubbo 生态系统中重要的注册中心实现。官方对它有如下定义:
Nacos致力于帮助您发现,配置和管理微服务。它提供了一组简单有用的功能,使您能够实现动态服务发现,服务配置,服务元数据和流量管理。 Nacos使构建,交付和管理微服务平台变得更容易,更快捷。它是通过微服务或云原生方法支持以服务为中心的现代应用程序体系结构的基础架构。
这里我们看到Nacos不仅是服务发现组件,同时也是一个配置管理组件,也就是说它不仅可以用来取代Eureak作为注册中心, 也可以用来取代Spring Cloud Config 做配置统一管理。本篇文章意在探讨Nacos的服务注册与发现功能。
1.2.Nacos服务安装
官方提供了Nacos的服务端供我们下载使用,我们启动Nacos后将我们的微服务注册进入Nacos即可。
下载地址:Releases · alibaba/nacos · GitHub
启动Nacos:解压后,
-
windows执行bin目录下的startup命令 :startup.cmd -m standalone
-
linux 执行 :sh startup.sh -m standalone
访问Nacos,端口8848:http://127.0.0.1:8848/nacos/index.html ,用户名和密码都是:nacos
登录成功之后
1.3.基于数据库持久化Nacos
找到nacos安装目录config/application.properties 文件,编辑数据库信息,修改内容如下
spring.datasource.platform=mysql
### Count of DB:
db.num=1### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
找到config/ nacos-mysql.sql 文件 ,创建数据库 nacos-config,然后导入该sql脚本文件
2.项目结构搭建
2.1.服务调用流程
我们这里要演示的案例是两个服务的通信,用户服务(user-server)作为服务提供者需要编写接口返回User实体对象,订单服务(order-server)作为消费者需要调用用户服务获取User实体对象,浏览器调用订单服务,订单服务调用用户服务或到User实体后返回给容器,用户和订单都注册到Nacos中,如下:
注意:这里的订单服务和用户服务都用到了User实体,所以为了让User实体共用,我们为User实体抽取了一个公共的user-common模块,用户服务和订单服务都去依赖这个模块即可使用User实体。
2.2.项目结构搭建
我们根据上面的图例来搭建项目环境,这里使用多模块方式演示,搭建父工程,提供者服务,消费者服务,以及公共的user-common模块,结构如下:
springcloudalibaba-parent
pom.xml
springcloudalibaba-user-common //公共的user实体,服务调用传输对象
springcloudalibaba-order-server-10020 //消费者服务
springcloudalibaba-user-server-10010 //提供者服务
父工程搭建 搭建父工程springcloudalibaba-parent并管理相关依赖,Spring boot版本为2.1.3.RELEASE,Spring Cloud 版本为Greenwich.SR1,Alibaba版本为2.1.0.RELEASE ,父工程的pom如下:
<!--公共的一些配置-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!--SpringBoot-->
<parent>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<!--SpringCloud-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
3.服务注册到Nacos(重要)
3.1.导入依赖
修改springcloudalibaba-user-server-1010导入服务发现依赖
<dependency>
<groupId>com.alibaba.cloud </groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--加入WEB依赖是为了方便后面写Controller-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.2.主配置类
创建配置类加上@EnableDiscoveryClient注解开启服务发现功能,代码如下
@SpringBootApplication
@EnableDiscoveryClient
public class OrderServerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServerApplication.class,args);
}
}
@SpringBootApplication
@EnableDiscoveryClient
public class UserServerApplication {
public static void main(String[] args) {
SpringApplication.run(UserServerApplication.class,args);
}
}
3.3.配置文件
配置文件主要配置端口,服务名,已经nacos注册中心地址
server:
port: 10100
spring:
application:
name: server-user
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册中心地址
server:
port: 10200
spring:
application:
name: server-order
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册中心地址
3.4.启动测试
启动服务提供者,观察Nacos服务列表 , user-server已经注册进去了
4.服务通信
服务通信可以使用Ribbon,OpenFeign,甚至Dubbo,使用方式和在SpirngCloudNetflix中没有任何区别。
三.Nacos配置管理
1.Nacos配置中心
1.1.概述
在《SpringCloud极简入门》中我们通过Spring Cloud Config作为统一配置文件管理中心,其实我们总结一下发现Spring Cloud Config使用起来总归比较麻烦。Nacos作为Spring Cloud Alibaba的一个重要组件,它不仅可以用作服务注册与发现,也可以用来替代Spring Cloud Config作为统一配置文件管理,而且他的使用更为简单和人性化。
1.2.Nacos添加配置
第一步:打开Nacos监控面板 - 进入配置列表 -点击 “+” 图标添加配置 如下:
第二步:填写Data ID,选择YAML,编辑配置文件内容
这里定义了一个名字为application-user-dev.yaml的配置,使用的是YAML格式。
-
Data ID
: 非常重要,可以看做是配置的文件的名字,在程序中拉取配置文件的时候需要指定Data ID。 -
Group
: 分组,默认是 DEFAULT_GROUP , 可以针对不同的项目指定不同的配置组。
2.客户端接入配置中心(重要)
2.1.导入依赖
修改工程 springcloudalibaba-user-server-1010 ,添加配置中心依赖nacos-config,完整pom.xml如下。
<dependencies>
<!-- 配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 服务注册与发现-->
<dependency>
<groupId>com.alibaba.cloud </groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>springcloudalibaba-user-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
2.2.编写Controller
下面的Controller用来做配置刷新测试,temp.notify
对应了配置文件中的配置项目。@RefreshScope
注解是用来做配置自动刷新。那么当我们修改了Nacos中的配置文件,Controller中读取到的配置temp.notify
将会自动变化。
@RefreshScope //刷新配置
@RestController
public class UserController {
@Value("${temp.notify}")
private String notify;
@GetMapping("/user/{id}")
public User getById(@PathVariable Long id){
System.out.println("测试配置notify="notify);
return new User(id,"zs:"+id, "我是zs");
}
}
2.3.修改yml配置
注意,将原来的配置文件修改成bootstrap.yml
,然后增加如下内容:
server:
port: 1010
spring:
profiles:
active: dev
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册中心
config:
server-addr: localhost:8848 #配置中心
file-extension: yaml #配置文件格式
prefix: application-user #配置前缀 ,默认使用sring.application.name
group: DEFAULT_GROUP #默认分组
#如何查找配置文件:application-user + dev + yaml=application-user-dev.yaml 正好和Nacos配置的DataId一致
提示:客户端是如何从Nacos中找到配置文件的呢?
-
spring.cloud.nacos.config.server-addr
:配置了Nacos的地址 -
spring.cloud.nacos.config.file-extension
:指定了配置文件的格式为YAML,默认是properties, -
spring.cloud.nacos.config.prefix
:配置前缀,如果不配置前缀默认会把 服务名即spring.application.name
的值作为前缀 -
spring.cloud.nacos.config.group
:分组名,默认是DEFAULT_GROUP对应了Nacos配置中的Group -
spring.profiles.active
:配置了环境为dev .该配置可以实现多配置多环境管理
根据如上配置,那么config客户端会将:前缀+环境+后缀 拼接成的文件名“application-user-dev.yaml
” 去Nacos上查找是否有对应Data ID的配置文件。
2.4.测试
启动Nacos,启动 springcloudalibaba-user-server-1010 工程 , 修改Nacos中的配置文件内容,然后访问 http://localhost:1010/user/11
,观察控制台打印的 “notify”的值会发生变化。
2.5.注意细节
-
云端配置文件的后缀应该是 yaml而不是yml
-
客户端配置需要指定:spring.profiles.active=dev 环境名
-
客户端配置 :前缀 + 环境名 + 后缀应该和云端配置文件的DataId一致
3.命名空间
命名空间可以用来隔离不同项目的配置文件,在Nacos中配置了命名空间后,那么Java客户端需要指定命名空间后才能拉取到该命名空间下的配置文件。
3.1.创建命名空间
修改Nacos,添加命名空间如下:
这里建立了一个名字为“test”的命名空间,点击确定,然后你需要关注一下命名空间的ID,这个是需要在Java客户端进行配置的。如下:
3.2.在命名空间创建配置
进入配置列表 ,切换S到新建立的命名空间“test”,然后创建配置,如下:
需要注意后缀是yaml
需要注意:这里的配置文件名也叫 application-user-dev.yaml,但是他是属于 “test”这个命名空间的 , 我们之前在 默认的“public”命名空间中也有一个同名的配置。
3.3.客户端配置
这里需要指定一下从哪个命名空间拉取配置:
server:
port: 1010
spring:
profiles:
active: dev
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册中心
config:
server-addr: localhost:8848 #配置中心
file-extension: yaml #配置文件格式
prefix: application-user #配置前缀 ,默认使用sring.application.name
group: DEFAULT_GROUP #默认分组
namespace: 8ef8c1e5-6d20-4efc-80c8-2b2c05541fa3 #命名空间的ID
注意:这里的namespace对应了 Nacos中“test”这个命名空间的ID,意思是从“test”这个命名空间去找 application-user-dev.yaml的配置文件。
3.4.启动测试
启动Nacos,启动 springcloudalibaba-user-server-1010 工程 , 修改Nacos中的配置文件内容,然后访问 http://localhost:1010/user/11
,观察控制台打印的 “notify”的值
4.扩展需求
4.1.如何自定义Data ID
支持自定义扩展的 Data Id 配置 :https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
4.2.开启Nacos认证
开启Nacos认证,需要通知账号和密码进行注册,以及拉取配置。
四.Sentienl限流
1.Sentinel和Hystrix
1.1.限流和熔断
限流 , 限制流量,这里的流量我们可以理解成请求数量,其实就是限制服务器的请求并发数量,为什么要这么做?如果不做限流,那么在大量并发请求下我们的服务器会慢慢的变慢然后顶不住压力而挂掉(类似堵车)。并不是说并发越大越好,有的时候我们的项目规模和业务决定了我们不需要那么大的并发性,当大量的并发请求访问到服务器时我们需要把部分请求拒绝在外,这个是流量限制 - 限流。
熔断机制在在《Spring Cloud 极简入门》中有详细的解释,熔断机制是对服务调用链路的保护机制,如果链路上的某个服务不可访问,调用超时,发生异常等,服务会进行发熔断,触发降级返回托底数据。简单理解就是当服务器不可访问,可以返回一些预先准备好的兜底数据给用户,比如友好的提示信息,不至于直接向客户抛出异常。
1.2.Hystrix的熔断和资源隔离
其实在《Spring Cloud 极简入门》中我们已经学习过Hystrix的熔断和资源隔离机制,它的资源隔离可以通过线程池隔离和信号量隔离两种方式来实现对流量的控制。Hystrix相比Sentinel来说它的线程池隔离(限流)会造成线程上下切换对资源的消耗比较大;Hystrix使用的信号量进行资源的隔离效果不错,但是无法对慢调用进行自动降级。
1.3.Sentinel介绍
Sentinel诞生于阿里巴巴,其主要目标是流量控制和服务熔断
,2018年,Sentinel演变为一个开源项目现如今成为了Spring Cloud Alibaba的一个子项目。Sentinel是通过限制并发线程的数量来减少不稳定资源的影响
,而不是使用线程池,省去了线程切换的性能开销。
当资源的响应时间变长时,线程将开始被占用。当线程数累积到一定数量时,新的传入请求将被拒绝
。反之亦然,当资源恢复并变得稳定时,占用的线程也将被释放,新请求将被接受。
除了限制并发性外,Sentinel可以根据响应时间降级
不稳定资源也是保证可靠性的有效方法。当资源的响应时间太大时,将在指定的时间窗口中拒绝所有对该资源的访问
。-- 熔断机制
此外,Sentinel支持的熔断降级维度更多,可对多种指标进行流控、熔断,且提供了实时监控和控制面板,功能更为强大。
2.Sentinel限流实战(重要)
2.1.Sentinel Server服务端
Sentinel 提供了现成的服务端供我们使用,点我下载地址,下载之后通过命令行启动
java -jar -Dserver.port=1111 sentinel-dashboard-1.6.0.jar
访问:http://127.0.0.1:1111
进入控制台,使用 sentinel/sentinel登录。
注意:只有1.6.0及以上版本才有这个登录页面。默认用户名和密码都是sentinel
。对于用户登录的相关配置可以在启动命令中增加下面的参数来进行配置:
-
-Dsentinel.dashboard.auth.username=sentinel
: 用于指定控制台的登录用户名为 sentinel; -
-Dsentinel.dashboard.auth.password=123456
: 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel -
-Dserver.servlet.session.timeout=7200
: 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟; -
-Dserver.port=1111
:配置端口
主页面效果
2.2.Sentinel 客户端接入
1.导入依赖
修改用户服务 springcloudalibaba-user-server-1010 ,加入sentinel依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.配置Sentinel
修改yml配置,添加senticel服务控制台地址
spring:
cloud:
sentinel:
transport:
dashboard: localhost:1111
3.资源限流
Sentinel为我们提供了 @SentinelResource
注解标记需要限流的资源。 修改UserController,代码如下:
@GetMapping("/user/{id}") //限流降级 @SentinelResource(value="user",blockHandler="exceptionHandler") public User getById(@PathVariable Long id){ System.out.println(notify); return new User(id,"zs:"+id, "我是zs"); } // 限流与阻塞处理 : 参数要和 被降级的方法参数一样 public User exceptionHandler(@PathVariable Long id, BlockException ex) { ex.printStackTrace(); System.out.println("限流了..."); return new User(-1L,"限流了","限流了"); }
提示:这里通过@SentinelResource
的value属性为资源取名为 “user” ,后续我们可以根据该资源名来进行限流。
同时这里通过 blockHandler
属性我配置了一个限流降级方法,即当“user”资源触发限流了会调用blockHandler
指向的降级方法返回拖地数据,不至于抛出默认的限流异常信息给客户端(一串英文用户也看不懂) ,需要注意的是:降级方法要和被限流的方法参数一致,然后加上 BlockException异常对象。
当然,也可以通过 blockHandlerClass 属性把降级方法写在一个专门的类中,如:
@SentinelResource(value="user",blockHandler="exceptionHandler" ,blockHandlerClass=ExceptionUtil.Class)降级类
public final class ExceptionUtil { public static User exceptionHandler(Long id ,lockException ex) { //... } }
2.3.Sentinel设置限流策略
启动应用 springcloudalibaba-user-server-1010 ,然后通过浏览器访问 http://localhost:1010/user/11
,然后登录Sentinel控制台,在“实时监控”列表中可以看到资源的相关监控信息的
在 “族点链路” 列表中可以看到资源的调用链 ,并且可以通过“流控”按钮设置流控规则
也可以在“流量控制”菜单中我们可以针对资源进行限流规则的设置。如下:
这里我添加了一个流控规则,资源名对应客户端 @SentinelResource(value="user"..
注解的资源,通过QPS限流(每秒请求数量),阈值是 1 ,意思是“user”这个资源每秒只能有1个请求进来,多余的请求会触发限流,返回降级数据。
2.4.限流测试
通过浏览器频发访问 “user”资源,当QPS大于1就会触发限流,效果如下:
7.Gateway使用Sentinel限流(重要)
Spring Cloud Gateway 作为微服务的网关,它是微服务的访问入口,当请求的流量洪峰到来我们可以在Gateway网关层通过Sentinel对请求进行流控,把好第一道关。
7.1.导入依赖
这里我们需要导入sentinel基础依赖和 sentinel-gateway 整合依赖
<!-- 限流和gataway使用--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
7.2.配置Sentinel地址
修改yml配置,增加Sentinel服务地址
spring: cloud: sentinel: transport: dashboard: localhost:1111
7.3.配置限流规则
启动Gateway,登录sentinel控制台,对url资源进行流控限制,配置方式和前面的配置方式一样,童鞋们可以自己测试一下。
7.4.限流降级
@Configuration public class SentinelConfig { public SentinelConfig(){ GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() { @Override public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { return ServerResponse.ok().body(Mono.just("限流啦,请求太频繁"),String.class); } }); } }
五.Sentinel熔断
1.概述
1.1.什么是熔断
在上一章节我们探讨了Sentinel的流控(限流)功能,Sentinel除了流控还提供了服务熔断和降级机制,服务之间的调用关系错综复杂,微服务的调用链上的某些服务资源不稳定(宕机,异常,超时)可能会导致可能请求的失败和请求的堆积,调用链产生连锁反应可能会导致整个微服务架构瘫痪
。服务熔断降级机制是保障高可用的重要措施之一。
1.2.Sentinel熔断
Sentinel的服务熔断机制会对调用链上的某个不稳定(宕机,异常,超时)的资源,做出请求限制,快速失败,避免影响到其它的服务而导致级联错误
。资源熔断后,在后续的一定时间(时间窗口)之内,对该服务的请求都自动熔断,抛出 DegradeException异常。
Sentinel拥有比Hystrix更强大和丰富的功能,能满足我们的各种应用场景,并且经历过淘宝双十一的考验,是微服务架构中熔断机制的不二选择。
2.Sentnel熔断实战(重要)
2.1.资源熔断降级
修改springcloudalibaba-user-1010工程,修改UserController ,通过@SentinelResource
注解的fallback
属性指定降级方法。
// 限流降级 public User exceptionHandler(@PathVariable Long id, BlockException ex) { ex.printStackTrace(); System.out.println("限流了..."); return new User(-1L,"限流了","限流了"); } // 熔断降级,参数和返回值与源方法一致 public User getByIdfallback(@PathVariable Long id){ System.out.println(notify); return new User(id,"zs:"+id, "熔断托底了"); } @GetMapping("/user/{id}") //限流降级 @SentinelResource(value="user",blockHandler="exceptionHandler",fallback = "getByIdfallback") public User getById(@PathVariable Long id){ int i = 1 / 0; //方法异常,触发熔断 return new User(id,"zs:"+id, "我是zs"); }
提示:方法中通过 int i = 1 / 0;
模拟异常,然后会熔断触发降级调用降级方法 。 通过 fallback
属性指定熔断的降级方法 ,熔断方法参数也要和被熔断方法参数一致。
注意:这里可以通过 @SentinelResource
注解的 exceptionsToTrace
属性忽略异常,即针对某个异常不熔断。
2.2.配置降级策略
在Sentinel控制台,在族点链路菜单中找到“user”资源,然后点击“降级”按钮添加降级策略,如下:
这里的降级策略为“RT”,大概意思是:如果并发数大于5 (QPS > 5) ,然后平均响应时间大于200毫秒,那么接下来的2秒钟之内对该资源的请求会被熔断降级。
2.3.测试熔断
启动springcloudalibaba-user-1010工程,访问 http://localhost:1010/user/2
,浏览器返回:
4.Feign整合Sentinel熔断(重要)
Spring Cloud Alibaba是Spring Cloud的一个子项目,OpenFeign是Spring Cloud的客户端负载均衡器,使用Spring Cloud Alibaba依然可以很方便的集成OpenFeign,如果要使用OpenFeign作为服务客户端负载均衡,那么我们需要考虑OpenFeign开启Sentinel进行服务熔断降级。
4.1.开启Sentinel
OpenFeign与Sentinel组件集成除了引入sentinel-starter
依赖关系之外,还需要在属性文件中启用Sentinel支持:feign.sentinel.enabled=true
feign: sentinel: enabled: true #熔断
4.2.给Feign接口降级
这里跟Feign开启Hystrix降级一样,还是可以使用fallback属性
@FeignClient(value = "user-server",fallback = UserClientFallback.class) public interface UserClient { @GetMapping("/user/{id}") User getById(@PathVariable Long id); }
4.3.编写降级类
@Component public class UserClientFallback implements UserClient { @Override public User getById(Long id) { return new User(-1L,"无此用户","无此用户"); } }
到这里我们已经完成了Feign和Sentinel的兼容使用,是不是很简单呢,因为它的集成方式和Hystrix简直一模一样