1.概念
作用:限流,熔断降级
限流方式 QPS(每秒请求数) 线程数限流
2.docker安装sentinel(M1芯片也可以亲测)
docker run --name sentinel -p 8858:8858 -d bladex/sentinel-dashboard:1.8.0
访问sentinel控制台 http://localhost:8858
3.使用
1.引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-webmvc-adapter</artifactId>
</dependency>
2.配置application.yml
spring:
cloud:
sentinel:
transport:
port: 8719 #这个端口可以随便填,没有被占用就行
dashboard: 127.0.0.1:8858
heartbeat-interval-ms: 10000
#开启sentinel对feign的支持
feign:
sentinel:
enabled: true
3.编写接口,测试流控和降级
/**
* value 限流的资源
* blockHandler 只捕获BlockException异常
* fallback 捕获Throwable
* 为了方便实际开发中只定义 fallback就行
* 可以把fallback方法都放到一个类里面,用 fallbackClass= 指定该类
* @return
*/
@Override
@SentinelResource(value = "testSentinel",fallbackClass = ProductcontrollerFallback.class, fallback = "testSentinel_fallback")
public String testSentinel() {
return "testSentinel";
}
4.编写fallbackClass,把降级方法放到一个类里面
/**
* @since 2022/6/5 8:29 PM
* fallback类,里面的方法在程序抛出throwable异常了执行
*/
public class ProductcontrollerFallback {
/**
* 这个方法必须是static
* 参数要和原方法一致,并且多一个Throwable
* @param e
* @return
*/
public static String testSentinel_fallback(Throwable e) {
return "throwable: >>>"+e;
}
}
5.为了方便判断是触发限流还是降级还是其他异常,可以编写一个异常处理类 ,实现BlockExceptionHandler
/**
* @author shentong
* @since 2022/6/5 7:00 PM
* 自定义Sentinel返回结果,根据不同的异常返回不同的类型
*/
@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
response.setContentType("application/json;charset=utf-8");
String result = "";
if (e instanceof FlowException) {
result = "你被限流了";
} else if (e instanceof DegradeException) {
result = "你被降级了";
}else if (e instanceof ParamFlowException){
result = "参数限流";
}else if (e instanceof SystemBlockException){
result = "系统异常";
}else if (e instanceof AuthorityException){
result = "权限不够";
}
response.getWriter().write(result);
}
6.在sentinel控制台针对testSentinel资源编写流控规则测试即可
4.sentinel结合feign 实现服务熔断降级
product是调用方,order是被调用方
1.创建一个熔断降级类实现FallbackFactory接口 泛型为熔断降级的order接口
/**
* @author shentong
* @since 2022/6/5 9:26 PM
*/
@Component
@Slf4j
public class OrderFallbackFactory implements FallbackFactory<OrderControllerApi> {
@Override
public OrderControllerApi create(Throwable throwable) {
return new OrderControllerApi() {
@Override
public Boolean createOrder(Integer id, Integer count) {
System.out.println("出错了:=>>>>"+throwable);
return false;
}
@Override
public String gateway() {
return "fallback gateway!!";
}
@Override
public String index() {
return "fallback index!!";
}
};
}
}
2.在order接口上@FeignClietn
注解上指定 fallbackFactory=熔断降级接口
@RequestMapping("order")
@FeignClient(value = "service-order",fallbackFactory = OrderFallbackFactory.class)
public interface OrderControllerApi {
@GetMapping("create")
Boolean createOrder(@RequestParam Integer id,
@RequestParam Integer count);
@GetMapping("gateway")
String gateway();
@GetMapping("index")
String index();
}
3.product调用order
@Autowired
private OrderControllerApi orderControllerApi;
@Override
public String decutProduct(Integer id, Integer count) {
Product product = productService.getById(id);
Integer stock = product.getStock();
if (stock >= count) {
product.setStock(stock - count);
productService.updateById(product);
// log.info("扣减库存成功,开始下单....");
System.out.println("扣减库存成功,开始下单....");
Boolean order = orderControllerApi.createOrder(id, count);
if (order) {
return "success";
}else {
return "false";
}
}else {
return "商品库存不足!!";
}
}
4.把order服务停掉,访问product接口测试会返回false