-
使用 Sentinel 实现限流 , 参见springcloud-demo , 限流是给服务生产者的保护措施
-
添加 pom 依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.7.1</version>
</dependency>
<!-- 在dubbo使用 Sentinel 需要添加下面依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
<version>1.7.1</version>
</dependency>
- 添加配置
spring.cloud.sentinel.datasource.ds.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds.nacos.data-id=${spring.application.name}-flow-rules.json
spring.cloud.sentinel.datasource.ds.nacos.rule-type=flow
spring.cloud.sentinel.datasource.ds.nacos.data-type=json
- 在 nacos 后台中新增 payment-service-flow-rules.json 配置文件,在文件里添加内容如下,注意 Formet 选择 JSON 格式,具体含义,见下表:
[{
"resource": "protected-resource",
"controlBehavior": 2,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
}]

- 增加注解:@SentinelResource,value 就是 json里配的 protected-resource。dubbo做法也是一样
@Override
@RequestMapping(value = "/pay/balance", method = RequestMethod.GET)
@SentinelResource(value = "protected-resource", blockHandler = "handleBlock")
public Balance getBalance(@RequestParam("id") Integer id) {
System.out.println("request: /pay/balance?id=" + id + ", sleep: " + sleep);
return new Balance(0, 0, 0,"none");
}
// 添加 handleBlock 方法
public Balance handleBlock(Integer id, BlockException e) {
return new Balance(0, 0, 0, "限流");
}
- 测试: 不断刷新接口,观察接口返回的数据
- 使用 Sentinel 实现熔断 , 参见 springcloud-demo , 熔断是给服务消费者准备的
- 假设在用户登录时,为了简化客户端处理,account服务的登录接口在处理成功后会调用payment服务查询余额接口获得余额信息一并返回给客户端。当payment服务严重卡顿时,我们希望登录接口不会被拖慢,而是快速失败并降级
- 添加pom依赖,和 Sentinel之限流一样
- 添加配置
# 解决Read Timeout 异常
feign.client.config.default.read-timeout=5000
feign.client.config.default.connect-timeout=100
#================配置 sentinel ==================s
spring.cloud.sentinel.datasource.ds.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds.nacos.data-id=${spring.application.name}-degrade-rules.json
spring.cloud.sentinel.datasource.ds.nacos.rule-type=degrade
spring.cloud.sentinel.datasource.ds.nacos.data-type=json
spring.cloud.sentinel.eager=true
#使用dubbo 的话,这个不用配置
feign.sentinel.enabled=true
- 在 nacos 后台中新增 payment-service-degrade-rules.json 配置文件,在文件里添加内容如下,注意 Formet 选择 JSON 格式。
[{
"resource": "GET:http://payment-service/pay/balance",
// 使用 dubbo时, 修改为
//"resource": "com.example.demo.user.UserService:sayHello(java.lang.String)",
"count": 200,
"grade": 0,
"timeWindow": 10
}]
- 上面配置的含义:grade=0,表示平均响应时间,当资源的平均响应时间超过阈值500毫秒(count 单位ms)之后,资源进入准降级状态。如果接下来1秒内持续进入5个请求的Read Time都持续超过这个阈值,那么在接下的时间窗口(timeWindow,10秒)之内,对这个方法的调用都会自动地熔断
- grade=1时,表示异常比例,当资源的每秒异常总数占通过量的比值超过阈值(count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回
- grade=2时,当资源近 1 分钟的异常数目超过阈值(count)之后会进行熔断
- Feign:配置服务降级,当触发Read Timeout异常时,也会触发服务降级,不仅仅访问过慢时会降级
@FeignClient(name = "payment-service", fallback = BalanceServiceFallback.class)
public interface BalanceServiceEx extends BalanceService {
}
@Component
public class BalanceServiceFallback implements BalanceServiceEx {
@Override
public Balance getBalance(Integer id) {
return new Balance(0,0,0,"降级");
}
}
- Dubbo:服务降级是通过Mock实现的
// 首先设置 mock = true
@Reference(mock = "true" )
private UserService userService;
// 然后创建 UserServiceMock 类, 注意:要和UserService接口在同一 package 下
package com.example.demo.user;
public class UserServiceMock implements UserService {
public UserServiceMock(){
}
@Override
public String sayHello(String name) {
System.out.print("------ 降级");
return "降级";
}
}
测试:
- 需要启动两个 payment-service(启动1个不出现熔断,还不知道为什么), 用浏览器打开并连续刷新6次以上, 即可出现服务熔断和降级后的返回
- 使用 Sentinel 后台观察,更好理解
Sentinel 后台安装 , github
- 下载源码并运行
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
#访问: http://localhost:8080/
#密码:用户名和密码都是sentinel
- Client 端连接 Sentinel 后台
# 修改payment-service 项目的配置文件,添加如下配置
spring.cloud.sentinel.transport.dashboard=localhost:8080
感谢你看到这里,我是程序员麦冬,一个java开发从业者,深耕行业六年了,每天都会分享java相关技术文章或行业资讯
欢迎大家关注和转发文章,后期还有福利赠送!
发布于刚刚
网友评论