sentinel 的基础知识参考官方文档和本人 SpringCloud 学习项目
一、概念
熔断
: 使用 Sentinel 直接快速返回失败的请求,而不是进行远程调用。例如: Fegin 有一个默认的过期时间 3s(不知道准不准确),如果某个服务宕机或者总是服务超时,每次都要等待 3s 才返回,资源得不到释放,降低了吞吐量降级
: 例如此时正处于秒杀流量高峰期,手工的停掉非核心业务【例如注册】,直接返回错误提示页面【降级页面】
熔断与降级比较
- 相同点
- 为了保证集群大部分服务的可用性和可靠性,防止崩溃,牺牲小我
- 用户最终都是体验某个功能不可用
- 不同点
- 熔断是调用放故障,触发的系统主动规则
- 降级是基于全局考虑,停止一些正常服务,释放资源
限流
对打入服务器的请求流量进行控制,使服务能够承担不超过自己的能力的流量压力,超过了流量的峰值的直接打回重试模式
Sentinel 与 Hystrix 对比
- 线程池隔离的弊端:每个请求都会由一个线程池来维护,导致很多线程池,线程池切换耗费大量资源 Sentinel 使用的信号量 semaphore 【JUC 的, 不是分布式的】
- Sentinel 的熔断降级策略多
- 动态规则配置:保存到 DB,下次可以继续使用
- 限流: Sentinel 做的好, QPS: 每秒请求速率,调用链关系
- 可视化控制台
二、环境搭建
导入依赖
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>2.1.8.RELEASE</version> </dependency>
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
|
基本配置
1 2 3 4 5 6 7 8 9 10 11 12
| spring: cloud: sentinel: transport: dashboard: localhost:8080
management: endpoints: web: exposure: include: "*"
|
注意
:
空空如也, 啥都没有
Sentinel 采用的懒加载说明
流控规则设置
效果:
三、自定义流控响应
1 2 3 4 5 6 7 8 9 10 11 12
| @Configuration public class GulimallSentinelConfig implements UrlBlockHandler {
@Override public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException { R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMsg()); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(JSON.toJSONString(error)); } }
TO_MANY_REQUEST(10003,"请求流量过大,请稍后再试")
|
四、 网关流控
如果能在网关层就进行流控,可以避免请求流入业务,减小服务压力
1 2 3 4 5 6
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> <version>2.1.0.RELEASE</version> </dependency>
|
五、Feign 的流控和降级
默认情况下,sentinel 是不会对 feign 进行监控的,需要开启配置
1 2 3
| feign: sentinel: enabled: true
|
开启后的效果
feign 的降级
在@FeignClient
设置fallback
属性
1 2 3 4 5 6
| @FeignClient(value = "gulimall-seckill",fallback = SeckillFallbackService.class) public interface SeckillFeignService { @ResponseBody @GetMapping(value = "/getSeckillSkuInfo/{skuId}") R getSeckillSkuInfo(@PathVariable("skuId") Long skuId); }
|
在降级类中实现对应的feign接口
,并重写降级方法
1 2 3 4 5 6 7
| @Component public class SeckillFallbackService implements SeckillFeignService { @Override public R getSeckillSkuInfo(Long skuId) { return R.error(BizCodeEnum.READ_TIME_OUT_EXCEPTION.getCode(), BizCodeEnum.READ_TIME_OUT_EXCEPTION.getMsg()); } }
|
降级效果
当远程服务被限流或者不可用时,会触发降级效果,如下所示
谷粒商城-Spring alibaba Sentinel