服务容错保护-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里加上这个“护身符”:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>如果是整合 Feign,记得还要有 Feign 的依赖哦。
3. 配置文件(application.yml)
告诉你的服务,Sentinel 控制台在哪里:
spring:cloud:sentinel:transport:dashboard:localhost:8080# 控制台地址port:8719# 客户端端口,默认8719,被占用会自动+1四、 Sentinel 整合 Feign(重中之重)
Consumer 调用 Provider 通常是用 Feign,所以熔断降级必须在 Feign 上做文章。
1. 开启 Feign 对 Sentinel 的支持
在application.yml中必须加这一句,否则 Feign 不会理你:
feign:sentinel:enabled:true2. 编写降级逻辑(Fallback)
当 Provider 挂了,Feign 得知道该怎么办。我们需要一个“备胎”工厂。
@ComponentpublicclassUserFeignFallbackFactoryimplementsFallbackFactory<UserFeign>{@OverridepublicUserFeigncreate(Throwablet){// t 就是报错的原因,可以打印日志returnnewUserFeign(){@OverridepublicUsergetUserById(Integerid){// 返回一个假数据,或者包含错误信息的对象returnnewUser(id,"服务降级了:"+t.getMessage(),0);}};}}3. 指定降级工厂
在你的 Feign 接口上贴上fallbackFactory标签:
@FeignClient(value="sentinel-provider",fallbackFactory=UserFeignFallbackFactory.class)publicinterfaceUserFeign{@GetMapping("/user/{id}")UsergetUserById(@PathVariable("id")Integerid);}搞定!现在 Provider 挂了,Feign 会自动调用你的 Fallback 逻辑,用户看到的不再是 500 错误,而是友好的提示。
五、 全局异常处理(统一口径)
默认的 Sentinel 报错信息太丑了,而且格式不统一。我们要做一个“统一异常处理器”。
实现BlockExceptionHandler接口:
@ComponentpublicclassGlobalBlockExceptionHandlerimplementsBlockExceptionHandler{@Overridepublicvoidhandle(HttpServletRequestrequest,HttpServletResponseresponse,BlockExceptione)throwsException{response.setContentType("application/json;charset=utf-8");Resultresult=null;// 判断是哪种异常if(einstanceofFlowException){result=newResult(-1,"哎呀,被限流了,稍后再试...");}elseif(einstanceofDegradeException){result=newResult(-2,"服务降级了,功能暂时不可用...");}elseif(einstanceofAuthorityException){result=newResult(-4,"授权失败,你谁啊?");}elseif(einstanceofSystemBlockException){result=newResult(-5,"系统负载过高,正在自救...");}// 返回 JSON 给前端response.getWriter().write(newObjectMapper().writeValueAsString(result));}}这样,不管触发什么规则,前端收到的都是统一的 JSON 格式,体验满分!
六、 规则持久化(告别“一重启就丢”)
默认情况下,你在 Sentinel Dashboard 上配的规则都在内存里。服务一重启,或者控制台一关,规则全没了!这怎么行?我们需要把规则存到Nacos配置中心。
第一步:改造 Sentinel Dashboard
我们要让 Dashboard 能把规则推送到 Nacos。
- 下载
sentinel-dashboard-nacos-1.8.1.jar(这是阿里魔改过的版本,支持 Nacos)。 - 用压缩软件打开这个 jar 包(或者解压)。
- 找到
application.properties文件,修改:nacos.address=192.168.61.132:8848 - 重新打包(或者在解压目录下启动),启动这个新的 Dashboard。
第二步:微服务从 Nacos 拉取规则
- 引入依赖:
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency> - 配置 application.yml:
spring:cloud:sentinel:datasource:ds1:# 数据源名称,随便起nacos:server-addr:${spring.cloud.nacos.discovery.server-addr}namespace:sentinel# 建议单独搞个命名空间groupId:SENTINEL_GROUPdataId:${spring.application.name}-flow-rules# 规则文件的IDrule-type:flow# 告诉 Sentinel 这个文件里存的是流控规则data-type:json# 数据格式
第三步:验证
- 在 Nacos 配置中心新建配置,Data ID 必须和上面配置的
dataId一致。 - 内容填 JSON 格式的规则(可以去 Dashboard 导出一个看看格式)。
- 启动微服务,你会发现规则自动生效了!
- 这时候,哪怕 Sentinel Dashboard 挂了,只要 Nacos 在,规则就在!
总结
Sentinel 就是微服务的保镖。
- 限流:防上游搞事。
- 熔断降级:防下游拖后腿。
- 整合 Feign:让远程调用更健壮。
- 持久化:让规则永久生效。