服务容错保护-Sentinel
一、 Sentinel 是个啥?为什么要用它?
1. 灵魂拷问:为什么要用?
想象一下这个场景:
上游服务(大哥)疯狂调用你的服务(小弟),你的服务又疯狂调用下游服务(小弟的跟班)。
突然,跟班(下游)挂了,或者大哥(上游)流量洪峰来了。
- 后果 :你的服务(小弟)直接被夹在中间,要么被上游累死(资源耗尽),要么被下游拖死(线程阻塞)。最后,整个系统像多米诺骨牌一样,啪!全挂了! 这就是传说中的服务雪崩。
2. Sentinel 登场
Sentinel(哨兵),阿里出品,必属精品。它是以流量为切入点的服务保护框架。
- 流量控制(防上游) :
- 就像水闸,控制每秒通过的请求数(QPS)或者同时干活的线程数(Thread)。
- 口号:上游大哥,慢点来,我顶不住啊!
- 熔断降级(防下游) :
- 熔断:发现下游不对劲(响应慢、报错多),直接切断连接,眼不见心不烦。
- 降级:熔断后不能干瞪眼啊,得返回个默认值(比如"系统繁忙"或空数据),给用户体验留条底裤。
- 口号:下游不行我就撤,绝不恋战!
二、 Sentinel 的四大规则(武功秘籍)
Sentinel 怎么保护你?靠的就是规则!
1. 流控规则(最常用)
- 流控 :直接对 URL 下手。比如
/hello接口,限制 QPS=2。超过?直接拒绝,没商量。 - 热点参数 :比如你有个接口查商品详情,参数是
id。如果id=1001的商品突然爆了,你可以单独限制这个参数,别让它把数据库打挂。 - 授权 :黑白名单机制。比如只允许
origin=app的请求访问,其他的(比如爬虫)统统踢走。 - 系统:这是"上帝视角"。如果整个服务的负载(Load)或 CPU 飙高了,Sentinel 会自动开启限流,保住小命要紧。
2. 降级规则(保命符)
这里有三个维度,满足一个就触发熔断:
- 异常比例 :5秒内,发了5次请求,如果有10%(0.1)都报错了 -> 熔断5秒。
- 异常数 :5秒内,发了5次请求,只要有1次报错 -> 熔断5秒。
- 慢调用比例 :5秒内,发了5次请求,如果有10%的请求超过1毫秒(RT)才返回 -> 熔断5秒 。
- 注:这里的阈值根据业务实际情况调整,别设太死板哦。
️ 三、 从零开始:环境搭建与整合(保姆级教程)
光说不练假把式,咱们来点实操的!
1. 启动 Sentinel 控制台(Dashboard)
你得先有个地方看监控吧?
- 下载 :去 GitHub 下载
sentinel-dashboard.jar。 - 启动 :命令行输入
java -jar sentinel-dashboard.jar。 - 访问 :浏览器打开
http://localhost:8080,账号密码默认都是sentinel。 - 注意:这一步不做,后面规则都没地方配!
2. 引入依赖(Maven)
在你的 pom.xml 里加上这个"护身符":
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
如果是整合 Feign,记得还要有 Feign 的依赖哦。
3. 配置文件(application.yml)
告诉你的服务,Sentinel 控制台在哪里:
yaml
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # 控制台地址
port: 8719 # 客户端端口,默认8719,被占用会自动+1
四、 Sentinel 整合 Feign(重中之重)
Consumer 调用 Provider 通常是用 Feign,所以熔断降级必须在 Feign 上做文章。
1. 开启 Feign 对 Sentinel 的支持
在 application.yml 中必须加这一句,否则 Feign 不会理你:
yaml
feign:
sentinel:
enabled: true
2. 编写降级逻辑(Fallback)
当 Provider 挂了,Feign 得知道该怎么办。我们需要一个"备胎"工厂。
java
@Component
public class UserFeignFallbackFactory implements FallbackFactory<UserFeign> {
@Override
public UserFeign create(Throwable t) {
// t 就是报错的原因,可以打印日志
return new UserFeign() {
@Override
public User getUserById(Integer id) {
// 返回一个假数据,或者包含错误信息的对象
return new User(id, "服务降级了:" + t.getMessage(), 0);
}
};
}
}
3. 指定降级工厂
在你的 Feign 接口上贴上 fallbackFactory 标签:
java
@FeignClient(value = "sentinel-provider", fallbackFactory = UserFeignFallbackFactory.class)
public interface UserFeign {
@GetMapping("/user/{id}")
User getUserById(@PathVariable("id") Integer id);
}
搞定!现在 Provider 挂了,Feign 会自动调用你的 Fallback 逻辑,用户看到的不再是 500 错误,而是友好的提示。
五、 全局异常处理(统一口径)
默认的 Sentinel 报错信息太丑了,而且格式不统一。我们要做一个"统一异常处理器"。
实现 BlockExceptionHandler 接口:
java
@Component
public class GlobalBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
response.setContentType("application/json;charset=utf-8");
Result result = null;
// 判断是哪种异常
if (e instanceof FlowException) {
result = new Result(-1, "哎呀,被限流了,稍后再试...");
} else if (e instanceof DegradeException) {
result = new Result(-2, "服务降级了,功能暂时不可用...");
} else if (e instanceof AuthorityException) {
result = new Result(-4, "授权失败,你谁啊?");
} else if (e instanceof SystemBlockException) {
result = new Result(-5, "系统负载过高,正在自救...");
}
// 返回 JSON 给前端
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
}
}
这样,不管触发什么规则,前端收到的都是统一的 JSON 格式,体验满分!
六、 规则持久化(告别"一重启就丢")
默认情况下,你在 Sentinel Dashboard 上配的规则都在内存里。服务一重启,或者控制台一关,规则全没了!这怎么行?我们需要把规则存到 Nacos 配置中心。
第一步:改造 Sentinel Dashboard
我们要让 Dashboard 能把规则推送到 Nacos。
-
下载
sentinel-dashboard-nacos-1.8.1.jar(这是阿里魔改过的版本,支持 Nacos)。 -
用压缩软件打开这个 jar 包(或者解压)。
-
找到
application.properties文件,修改:propertiesnacos.address=192.168.61.132:8848 -
重新打包(或者在解压目录下启动),启动这个新的 Dashboard。
第二步:微服务从 Nacos 拉取规则
-
引入依赖 :
xml<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> -
配置 application.yml :
yamlspring: cloud: sentinel: datasource: ds1: # 数据源名称,随便起 nacos: server-addr: ${spring.cloud.nacos.discovery.server-addr} namespace: sentinel # 建议单独搞个命名空间 groupId: SENTINEL_GROUP dataId: ${spring.application.name}-flow-rules # 规则文件的ID rule-type: flow # 告诉 Sentinel 这个文件里存的是流控规则 data-type: json # 数据格式
第三步:验证
- 在 Nacos 配置中心新建配置,Data ID 必须和上面配置的
dataId一致。 - 内容填 JSON 格式的规则(可以去 Dashboard 导出一个看看格式)。
- 启动微服务,你会发现规则自动生效了!
- 这时候,哪怕 Sentinel Dashboard 挂了,只要 Nacos 在,规则就在!
总结
Sentinel 就是微服务的保镖。
- 限流:防上游搞事。
- 熔断降级:防下游拖后腿。
- 整合 Feign:让远程调用更健壮。
- 持久化:让规则永久生效。