Sentinel - 介绍
sentinel
的使用可以分为两个部分
核心库不依赖任何框架/库,能够允许在jdk7
以上的版本运行时环境,同时对Dubbo、SpringCloud等框架也有比较好的支持。
控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。
一、sentinel core
引入依赖
<sentinel.version>1.8.3</sentinel.version> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-core</artifactId> <version>${sentinel.version}</version> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>${sentinel.version}</version> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> <version>${sentinel.version}</version> </dependency>
- sentinel-core核心包
- sentinel-annotation-aspectj适合spring切面和注解
-
sentinel-transport-simple-http便于接入console控制台
引入注解
@Configuration public class SentinelAspectConfiguration { @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); } }
使用方法:定义资源、定义规则
//定义资源使用注解方式 @SentinelResource("HelloWorld") public void helloWorld() { // 资源中的逻辑 System.out.println("hello world"); } //定义规则 private static void initFlowRules(){ List<FlowRule> rules = new ArrayList<>(); FlowRule rule = new FlowRule(); rule.setResource("HelloWorld"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // Set limit QPS to 20. rule.setCount(20); rules.add(rule); FlowRuleManager.loadRules(rules); }
-
SentinelResource为Sentinel的注解
- value为资源标识
以上就完成了sentinel的基本使用。
使用实例:
private static final String KEY = "queryGoodsInfo2"; /** * 模拟商品查询接口 * * @param spuId * @return */ @SentinelResource(value = KEY, blockHandler = "blockHandlerMethod", fallback = "queryGoodsInfoFallback") public String queryGoodsInfo(String spuId) { // 模拟调用服务出现异常 if ("0".equals(spuId)) { throw new RuntimeException(); } return "query goodsinfo success, " + spuId; } //用来处理Sentinel 限流/熔断等错误 处理方法中方法名、参数都需与受保护的函数保持一致 public String blockHandlerMethod(String spuId, BlockException e) { log.warn("queryGoodsInfo222 blockHandler", e.toString()); return "queryGoodsInfo error, blockHandlerMethod res: " + spuId; } //用来处理接口中业务代码所有异常 处理方法中方法名、参数都需与受保护的函数保持一致 public String queryGoodsInfoFallback(String spuId, Throwable e) { log.warn("queryGoodsInfo222 fallback", e.toString()); return "queryGoodsInfo error, return fallback res: " + spuId; } @PostConstruct public void initFlowQpsRule() { List<FlowRule> rules = new ArrayList<FlowRule>(); FlowRule rule1 = new FlowRule(); rule1.setResource(KEY); // QPS控制在2以内 rule1.setCount(2); // QPS限流 rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); rule1.setLimitApp("default"); rules.add(rule1); FlowRuleManager.loadRules(rules); }
如果使用了注解方式,异常处理方法必须手工定义,不会走全局异常。
二、Dashboard
控制台下载地址:
可以从https://github.com/alibaba/Sentinel/releases
下载sentinel-dashboard-$version.jar
包。
启动:
java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar D:\sentinel\sentinel-dashboard-1.8.0.jar
Sentinel Dashboard使用的是懒加载,因此需要调用接口后才会在控制台显示,如果只引入而不调用接口,是不会在控制台显示的。
控制台配置的规则,重启后规则会消失。
三、Openfeign sentinel 容错
Feign在调用远程服务的时候,由于远程服务的原因,可能会产生异常。就需要进行相应的容错降级设计,注意不是 流控。
当Feign远程调用服务出现问题后,进入到了容错工厂类中的同名方法,执行容错逻辑。而且,Feign调用产生的异常信息也可以获取到。
引入alibaba依赖
<!--sentinel客户端依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.3.RELEASE</version> </dependency>
1、开启openfeign对sentinel的支持,单独的标签:
feign: client: config: default: #连接超时时间 connectTimeout: 5000 #数据读取超时是时间 readTimeout: 5000 sentinel: enabled: true
注意:如果要启用控制台 则在 springcloud标签下加上如下配置,这样就可以使用控制台进行配置了。
sentinel: # 取消控制台懒加载 eager: true transport: # 控制台地址 dashboard: 127.0.0.1:8858
2、为被容错的interface指定容错类(容错工厂类)
//@FeignClient(name="stock-service",path="/stock",fallback = StockFeignServiceFallback.class) @FeignClient(name="stock-service",path="/stock",fallbackFactory = StockFeignFallbackFactory.class) public interface StockFeignService { /** * 声明需要调用的rest接口对应的方法 * @return */ @RequestMapping("/reduct2") String reduct(); @RequestMapping("/res") String res(); }
3、创建容错类
容错类的创建有两种方案:
1、直接继承被容错的接口,并为每个方法实现容错方案
2、实现FallbackFactory接口
推荐使用第2种方案,实现FallbackFactory接口。这样可以在容错工厂类中拿到具体的错误,便于后期排查问题。
实例:
@Component public class StockFeignFallbackFactory implements FallbackFactory<StockFeignService> { @Override public StockFeignService create(Throwable e) { System.out.println("打印流控错误信息" + e.getMessage()); return new StockFeignService() { @Override public String reduct() { return "factory 降级了"; } @Override public String res() { return "facotory 降级了"; } }; } }
4、controller处理
package cn.jack.controller; import cn.jack.domain.Order; import cn.jack.domain.Product; import cn.jack.service.OrderService; import cn.jack.service.ProductService; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController @Slf4j public class OrderController { @Autowired private RestTemplate restTemplate; @Autowired private OrderService orderService; @Autowired private DiscoveryClient discoveryClient; @Autowired private ProductService productService; /** * 下单 -- 基于Feign实现服务调用 * @param pid 商品id * @return */ @RequestMapping("/order/prod/{pid}") public Order order(@PathVariable("pid") Long pid) { log.info("收到下单请求,准备查询商品信息。pid={}", pid); // 通过Feign调用商品微服务,查询商品信息 Product product = this.productService.findByPid(pid); log.info("商品信息查询成功。内容为:{}", JSON.toJSONString(product)); // 进行容错判断 if (product.getPid() == -100) { Order order = new Order(); order.setOid(-100L); order.setPname("下单失败"); return order; } // 生成商品信息保存 Order order = new Order(); order.setNumber(1); order.setPid(pid); order.setPname(product.getPname()); order.setPprice(product.getPprice()); order.setUid(1); order.setUsername("测试用户"); this.orderService.createOrder(order); log.info("订单信息保存成功。内容为:{}", JSON.toJSONString(order)); return order; } }
注意:以上只是容错降级,如果有流控则可以统一定制流控异常处理类:
/** * 流控异常统一处理 */ @Component public class SentinelFallbackHandler implements BlockExceptionHandler { @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception { Map<String, Object> backMap = new HashMap<>(); if (e instanceof FlowException) { backMap.put("code", -1); backMap.put("msg", "限流-异常啦"); backMap.put("data", null); } else if (e instanceof DegradeException) { backMap.put("code", -2); backMap.put("msg", "降级-异常啦"); backMap.put("data", null); } else if (e instanceof ParamFlowException) { backMap.put("code", -3); backMap.put("msg", "热点-异常啦"); backMap.put("data", null); } else if (e instanceof SystemBlockException) { backMap.put("code", -4); backMap.put("msg", "系统规则-异常啦"); backMap.put("data", null); } else if (e instanceof AuthorityException) { backMap.put("code", -5); backMap.put("msg", "认证-异常啦"); backMap.put("data", null); } // 设置返回json数据 httpServletResponse.setStatus(200);//响应消息的状态码 httpServletResponse.setHeader("content-Type", "application/json;charset=UTF-8"); httpServletResponse.getWriter().write(JSON.toJSONString(backMap, SerializerFeature.WriteMapNullValue)); } }
满足流控条件时,走流控异常,满足降级异常时走降级异常
四、springcloud gateway sentinel nacos 持久化
引入:
<!-- SpringCloud Ailibaba Sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- SpringCloud Ailibaba Sentinel Gateway --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> <!-- sentinel datasource nacos --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
配合参数:
sentinel: # 取消控制台懒加载 eager: true transport: # 控制台地址 dashboard: 127.0.0.1:8858 # nacos配置持久化 datasource: ds1: nacos: server-addr: 127.0.0.1:8848 dataId: sentinel-ruoyi-gateway groupId: DEFAULT_GROUP data-type: json rule-type: flow
nacos配置:
[ { "resource": "ruoyi-auth", "count": 500, "grade": 1, "limitApp": "default", "strategy": 0, "controlBehavior": 0 }, { "resource": "ruoyi-system", "count": 1000, "grade": 1, "limitApp": "default", "strategy": 0, "controlBehavior": 0 } ]
dashboard查看流控规则:
sentinel做了持久化,一般不在需要控制台配置规则了,规则提前预置在nacos。
参考:https://blog.csdn.net/liaomingwu/article/details/122181098
posted on 2022-02-17 17:05 TrustNature 阅读(235) 评论(0) 编辑 收藏 举报