文章目录
一、雪崩效应
二、常见容错方案
1、超时:设置调用服务的时间
2、限流:在一个高并发系统中,为微服务设置一个限流的值
3、仓壁模式
4、断路器模式:监控+开关
断路器模式原文
断路器三态转换
三、使用Sentinel实现容错
1、什么是Sentinel?
2、整合Sentinel
添加依赖
<!--sentinel依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--/actuator/sentinel-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.yml
management:
endpoints:
web:
exposure:
include: '*'
测试结果
四、sentinel控制台
1、搭建sentinel控制台
下载地址
启动sentinel-dashboard
访问地址
2、整合应用和控制台
application.yml
spring:
cloud:
sentinel:
transport:
# 指定sentinel控制台的地址
dashboard: localhost:8080
五、流控规则
1、直接流控模式
2、关联流控模式
测试类进行测试
此时http://localhost:8010/shares/1一直处于限流状态
3、链路流控模式
分别访问http://localhost:8010/test-a和http://localhost:8010/test-b
再次访问http://localhost:8010/test-a会发生限流,而访问http://localhost:8010/test-b没有
排队等待流控效果
测试代码
六、降级规则
1、降级策略-RT
注意:RT默认最大值为4900ms,可以通过
-Dcsp.sentinel.statistic.max.rt=xxx修改
2、降级策略-异常比例
3、降级策略-异常数
注意点:
时间窗口 < 60秒可能会出问题
七、热点规则
对http://localhost:8010/test-hot?a=5&b=2不限流
八、系统规则
◆当系统load1(1分钟的load)超过阈值,且并发线程数超过系统容量时触发,建议设置为CPU核心数*2.5。(仅对Linux/Unix- like 机器生效)◆系统容量=maxQps*minRt
◆maxQps:秒级统计出来的最大QPS
◆minRt:秒级统计出来的最小响应时间
系统-RT、线程数、入口QPS
◆RT:所有入口流量的平均RT 达到阈值触发
◆线程数:所有入口流量的并发线程数达到阈值触发
◆入口QPS:所有入口流量的QPS达到阈值触发
九、代码配置规则
Alibaba Sentinel 规则参数总结
测试代码TestController.java
@GetMapping("/test-add-flow-rule")
@SentinelResource("hot")
public String testHot(){
this.initFlowQpsRule();
return "success";
}
private void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule("/shares/1");
// set limit qps to 20
rule.setCount(20);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
测试结果
十、Sentinel与控制台通信原理分析
十一、控制台相关配置项
1、应用端连接控制台配置项
2、控制台配置项
配置Dashboard登录的账号和密码
java -jar -Dsentinel.dashboard.auth.username=czy -Dsentinel.dashboard.auth.password=123456 sentinel-dashboard-1.6.3.jar
十二、Sentinel API
TestController.java
@GetMapping("/test-sentinel-api")
public String testSentinelApi(@RequestParam(required = false) String a) {
Entry entry = null;
String resourceName = "test-sentinel-api";
// 针对来源
ContextUtil.enter(resourceName,"test-wfw");
try {
// 定义需要保护资源的名称
entry = SphU.entry(resourceName);
// 被保护的业务逻辑
if (StringUtils.isBlank(a)) {
throw new IllegalArgumentException("a不能为空");
}
return a;
}
// 如果被保护的资源被限流或降级,就会抛出BlockException异常
catch (BlockException e) {
log.warn("限流,或降级了",e);
return "限流,或降级了";
}
catch (IllegalArgumentException e2) {
// 统计IllegalArgumentException发生的次数等
Tracer.trace(e2);
return "参数非法";
}
finally {
if (entry != null) {
// 退出entry
entry.exit();
}
ContextUtil.exit();
}
}
三个核心API
- SphU:定义、监控、保护资源
- Tracer:对异常进行统计
- ContextUtil:实现调用来源,标记调用
十三、@SentinelResource注解
TestController.java
@GetMapping("/test-sentinel-resource")
@SentinelResource(value = "test-sentinel-api",blockHandlerClass = TestControllerBlockHandlerClass.class,fallback = "fallback")
public String testSentinelResource(@RequestParam(required = false) String a) {
if (StringUtils.isBlank(a)) {
throw new IllegalArgumentException("a can not be blank");
}
return a;
}
/**
* Sentinel 1.5 处理降级
* Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。
* @param a
* @return
*/
public String fallback(String a) {
return "限流,或降级了 fallback";
}
十四、RestTemplate整合Sentinel
application,yml
resttemplate:
sentinel:
# false 关闭@SentinelRestTemplate注解
enabled: true
TestController.java
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test-rest-template-sentinel/{userId}")
public UserDTO test(@PathVariable Integer userId){
return this.restTemplate.getForObject("http://user-center/users/{userId}",UserDTO.class,userId);
}
十五、Feign整合Sentinel
application.yml
feign:
sentinel:
# 为feign整合sentinel
enabled: true
UserCenterFeignClientFallbackFactory .java
package com.uos.contentcenter.feignclient.fallbackfactory;
import com.uos.contentcenter.domain.dto.user.UserDTO;
import com.uos.contentcenter.feignclient.UserCenterFeignClient;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class UserCenterFeignClientFallbackFactory implements FallbackFactory<UserCenterFeignClient> {
@Override
public UserCenterFeignClient create(Throwable cause) {
return new UserCenterFeignClient() {
@Override
public UserDTO findById(Integer id) {
log.warn("远程调用被限流/降级了",cause);
UserDTO userDTO = new UserDTO();
userDTO.setWxNickname("一个默认用户");
return userDTO;
}
};
}
}
十六、Sentinel总结
十七、规则持久化-拉模式
十八、规则持久化-推模式
十九、在生产环境中使用sentinel
参考我的另一篇博客在生产环境中使用sentinel