github地址: https://hub.fastgit.org/alibaba/spring-cloud-alibaba/wiki/Sentinel
作用:流量控制、熔断降级、系统负载保护
使用步骤:
1.pom引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.下载sentinel控制台 https://hub.fastgit.org/alibaba/Sentinel/releases/tag/1.7.1
springcloudalibaba版本说明:https://hub.fastgit.org/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
3.配置 sentinel 控制台地址信息
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.transport.port=8719
management.endpoints.web.exposure.include=*
4.自定义全局错误返回
/**
* @Description: 自定义阻塞返回方法
* @Created: with IntelliJ IDEA.
* @author: lzp
* @createTime: 2020-07-13 11:30
**/
@Configuration
public class GulimallSeckillSentinelConfig implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
R error = R.error(BizCodeEnume.TO_MANY_REQUEST.getCode(), BizCodeEnume.TO_MANY_REQUEST.getMsg());
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json");
httpServletResponse.getWriter().write(JSON.toJSONString(error));
}
}
流控规则:
QPS是每秒的访问数量
比如单机阈值设为1,表示1秒只能有一个请求通过,超过就会进入自定义的错误返回页面。
快速失败是直接返回错误页面
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
排队等待:它的中心思想是,以固定的间隔时间让请求通过。当请求到来的时候,如果当前请求距离上个通过的请求通过的时间间隔不小于预设值(比如阈值设置为2,则500ms才允许通过一个请求),则让当前请求通过;否则,计算当前请求的预期通过时间,如果该请求的预期通过时间小于规则预设的 timeout 时间,则该请求会等待直到预设时间到来通过(排队等待处理);若预期的通过时间超出最大排队时长,则直接拒接这个请求。
熔断降级:
1.慢调用比例:(1s5次就是来自于上表的统计时长和熔断触发的最小请求数)
RT:最大的响应时间。一秒钟有五次请求的处理时间大于该值,则进入熔断状态,到达时间窗口的设置值之后才会再次开始处理请求。
比如RT设置为1ms,时间窗口设置为10s,则当一秒钟内有5此请求的处理时间都大于1ms,则进入熔断状态,10s过后,开始尝试处理请求,如果1s内再有5次请求的处理时间大于1ms,再次进入熔断。
2.异常比例
1s内的请求的异常比例大于设定值,则进入熔断状态,过了时间窗口的设定值之后继续处理请求。
3.异常数
1s内的异常数超过设定值则进入熔断状态,过了时间窗口的设定值之后继续处理请求。
feign远程调用的保护
配置文件添加配置:
feign.sentinel.enable=true
调用方在指定调用的远程服务名时,指定错误返回 fallback
@FeignClient(value = "service-seckill",fallback = SeckillFeignServiceFallBack.class)
public interface SeckillFeignService {
/**
* 根据skuId查询商品是否参加秒杀活动
* @param skuId
* @return
*/
@GetMapping(value = "/sku/seckill/{skuId}")
R getSkuSeckilInfo(@PathVariable("skuId") Long skuId);
}
自定义fallback
/**
* @Description:feign远程调用失败的统一处理
* @Created: with IntelliJ IDEA.
* @author: lzp
* @createTime: 2020-07-13 14:45
**/
@Slf4j
@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {
@Override
public R getSkuSeckilInfo(Long skuId) {
log.info("熔断方法调用");
return R.error(BizCodeEnume.TO_MANY_REQUEST.getCode(),
BizCodeEnume.TO_MANY_REQUEST.getMsg());
}
}
被调用方也可以指定降级策略。被调用方也是在运行,但是不允许自己的业务逻辑,返回的是默认的降级数据(限流的数据)
自定义受保护的资源
方式1: 错误后执行catch中代码
try (Entry entry = SphU.entry("seckillSkus")) {
//业务逻辑
} catch(Exception e) {}
方式2:错误后执行blockHandler 方法
//基于注解的方式自定义受保护资源
@SentinelResource(value = "getCurrentSeckillSkusResource",blockHandler = "blockHandler")
网关流控
1.引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
2.自定义错误处理
/**
* @Description:网关流控统一返回
* @Created: with IntelliJ IDEA.
* @author: lzp
* @createTime: 2020-07-13 17:18
**/
@Configuration
public class SentinelGatewayConfig {
public SentinelGatewayConfig() {
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
//网关限流了请求,就会调用此回调
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {
System.out.println("error");
R error = R.error(BizCodeEnume.TO_MANY_REQUEST.getCode(),
BizCodeEnume.TO_MANY_REQUEST.getMsg());
String errorJson = JSON.toJSONString(error);
Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errorJson), String.class);
return body;
}
});
}
}
为gulimall_seckill_route这个路由设置流控规则
备注: sentinel界面没有API管理选项:
在main中加入:
System.setProperty(“csp.sentinel.app.type”, “1”);