作用:作为服务保护,可以对资源(包括接口,方法调用,远程 调用)进行限流,熔断降级等操作
快速入门使用:
1,下载Sentinel的jar包
下载不了的去这个https://github.com/alibaba/Sentinel/releases/tag/1.8.8
启动命令:java -jar sentinel
浏览器地址:localhost:8080 账号密码都是sentinel
2,引入Sentinel依赖
依赖名称 spring-cloud-starter-alibaba-sentinel
配置Sentinel的地址:spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080
3,项目中使用:
一共有三种场景使用,web接口进行保护,调用某个方法接口进行保护,远程调用时进行保护,并且限流等规则触发时会抛出BlockException,我们需要做好异常处理
web接口进行保护
在Sentinel中心的簇点链路中对服务的主接口进行保护--添加规则
报错处理
手动实现BlockExceptionHandler接口,并且将该类注册到容器当中,即可自定义异常处理
@Component public class MyBlockExceptionHandler implements BlockExceptionHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { // 所有被限流/熔断的请求都走到这里 response.setStatus(200); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("{\"msg\":\"请求太频繁了,请稍后再试\"}"); } }对方法进行保护
对于Sentinel而言,是无法直接感知到方法调用的,只能手动加上@SentinelResource注解,这样Sentinel就能识别到这个资源,并对其进行保护
@SentinelResource( value = "getProduct", blockHandler = "blockHandlerMethod", // Sentinel 限流/熔断时走这个 fallback = "fallbackMethod" // 业务代码报错时走这个 ) public Product getProduct(Long id) { // 远程调用 product 服务 return productClient.getProduct(id); } // blockHandler:参数和原方法一致,最后多一个 BlockException public Product blockHandlerMethod(Long id, BlockException e) { return new Product("请求太频繁了,请稍后再试"); } // fallback:参数和原方法一致,最后多一个 Throwable public Product fallbackMethod(Long id, Throwable e) { return new Product("服务暂时不可用"); }报错处理
同样的,违反规则是会抛出BlockException
首先Sentinel会去找注解上有没有blockHandler
如果没有再去找fallback
如果都没有则抛给SpringBoot来处理异常,我们可以自定义一个全局异常处理类
@RestControllerAdvice public class GlobalExceptionHandler { /** * 当没有给blockHandler时,会被默认处理 */ @ExceptionHandler(BlockException.class) public R handleBlockException(BlockException e){ return R.error("系统错误"+e.getMessage()+e.getClass()); } }对远程调用进行保护
我们只需要在配置中改写Feign远程调用的配置即可实现远程调用也被Sentinel保护起来
配置如下:feign.sentinel.enabled=true
同时编写一个降级类来实现远程调用的接口,自定义fallback逻辑,并在@FeignClient注解上加上fallback
@FeignClient(value = "service-product", fallback = ProductClientFallback.class) public interface ProductClient { @GetMapping("/product") Product getProduct(@RequestParam("productId") Long productId); }// 降级兜底 @Component public class ProductClientFallback implements ProductClient { @Override public Product getProduct(Long productId) { Product p = new Product(); p.setName("商品服务暂时不可用"); return p; } }异常处理总结