当前位置: 首页 > 科技观察

使用Sentinel实现接口限流

时间:2023-03-19 17:23:02 科技观察

本文转载自微信公众号《运维开发故事》,作者老郑。转载本文请联系运维开发故事公众号。在上一篇文章中,我对Sentinel做了简单的介绍。相信大家对Sentinel都有一个简单的了解。这次主要讲一下Sentinel的使用。在sentinel-dashboard配置流控规则,使用Sentinel集成RestTemplate和OpenFeign进行流控(推荐网页版阅读)。安装sentineldashboard我使用的sentinel版本是:sentinel-dashboard-1.8.0启动控制台命令:java-jarsentinel-dashboard-1.8.0.jar默认8080端口,默认登录账号和密码是:sentinel。如果需要修改启动端口,可以在启动命令前加上-Dserver.port=9999进行修改。使用介绍通常,我们项目中Sentinel最常用的场景就是默认对接口的访问添加流控规则进行流控。Sentinel还提供对RestTemplate和OpenFegin的支持。简单案例1.导入依赖如果我们需要使用Sentinel,首先我们需要在业务服务中导入Sentinel客户端的依赖。下面是Maven的pom依赖项。我们可以直接使用spring-coud-starter-alibaba-sentinel进行快速集成。com.alibaba.cloudspring-cloud-starter-alibaba-sentinel对于spring-cloud-alibaba相关的版本依赖信息如下:2.3.10.RELEASEHoxton.SR82.2。5.发布org.springframework.bootspring-boot-dependencies<版本>${spring-boot.version}pomimportorg.springframework.cloudspring-cloud-dependencies${spring-cloud.version}<type>pom导入com.alibaba.cloudspring-cloud-alibaba-dependencies${spring-cloud-alibaba.version}pomimport2.YML配置我们在业务服务中导入依赖后,我们需要修改application.yml文件,让服务自动注册到sentinel-dashboard服务spring:cloud:sentinel:transport:port:8719dashboard:localhost:80803。要定义测试接口,我们首先需要定义对外开放的接口。@RestControllerpublicclassHelloController{@GetMapping("/hello")publicStringhello(){return"OK";}}4.通过控制台配置流控规则注意:如果你已经启动了snetinel-dashboard并且启动了业务服务,在sentinel后台-dashboard如果还是没有服务,我们可以先访问业务服务的界面,然后刷新snetinel-dashboard看是否正常。如果还是不正常,请考虑sentinel客户端版本是否与dashboard匹配。先选择你对应的服务展开,然后选择【ClusterLink】菜单。选择需要流控的接口/hello,然后选择【流控】按钮进行流控配置。我们可以配置它。我们选择【ThresholdType】,选择【QPS】,然后设置【SingleThreshold】,填1。表示该接口每秒只能接受一个QPS。如果超过阈值,就会触发【流控】DefaultSentinelreturnsBlockedbySentinel(限流)5.流控规则的触发如果我们需要触发流控规则,我们频繁访问/hello接口就可以了。~curlhttp://127.0.0.1:8066/helloOK%~curlhttp://127.0.0.1:8066/hello~curlhttp://127.0.0.1:8066/helloBlockedbySentinel(flowlimiting)%通过上面的结果我们可以看出,当单位时间超过阈值后,会触发限流整合RestTemplate1。YML配置Sentinel集成Resttemplate。除了导入spring-cloud-starter-alibaba-sentinel,还需要开启Sentinel对Resttemplate的支持。resttemplate:sentinel:enabled:true2.创建RestTemplate如果在使用RestTemplate时需要使用Sentinel的流控规则,首先需要在创建RestTemplate时添加@SentinelRestTemplate注解。注意:SentinelExceptionHandler中的方法都是静态方法@ConfigurationpublicclassRestTemplateConfig{@Bean@ConditionalOnMissingBean(RestTemplate.class)@LoadBalanced@SentinelRestTemplate(blockHandler="handlerException",blockHandlerClass=SentinelExceptionHandler.class,fallbackClass="SentinelFallback="SentinelFallbackClass")publicRestTemplaterestTemplate(){returnnewRestTemplate();}}//异常处理类publicclassSentinelExceptionHandler{//限流熔断业务逻辑publicstaticSentinelClientHttpResponsehandlerException(HttpRequestrequest,byte[]body,ClientHttpRequestExecutionexecution,BlockExceptionex){Stringmessage=JSON.toJSONString(CommonResult.error(-100,"系统错误(限流熔断器业务逻辑)"));returnnewSentinelClientHttpResponse(message);}//降级业务逻辑异常publicstaticSentinelClientHttpResponsehandleFallback(HttpRequestrequest,byte[]body,ClientHttpRequestExecution.JSONToStringexecution,BlockonStringResponsex){error(-100,"系统错误(异常降级业务logiC)”));returnnewSentinelClientHttpResponse(message);}}3.接口定义下面是我们使用的代码,可能写起来有点复杂,我来解释一下。首先,我通过RestTemplate访问stock-service服务的/getStockDetail接口,然后解析接口返回的数据,通过CommonResult实例对象接收,如果失败则返回错误信息。@AutowiredprivateRestTemplaterestTemplate;@GetMapping("/hello2")publicCommonResulthello2(){ParameterizedTypeReference>typeRef=newParameterizedTypeReference>(){};ResponseEntity>forEntity=restTemplate.exchange("http://stock-service/getStockDetail",HttpMethod.GET,HttpEntity.EMPTY,typeRef);OrderModelorderModel=newOrderModel();orderModel.setId(100);orderModel.setCode("100-100");if(Objects.equals(forEntity.getStatusCode(),HttpStatus.OK)&&Objects.nonNull(forEntity.getBody())){CommonResultresult=forEntity.getBody();if(result.getCode()!=1){returnCommonResult.error(null,result.getCode(),result.getMessage());}orderModel.setStockModel(result.getData());}returnCommonResult.success(orderModel);}4。如果我们频繁访问我们的接口/hello2,就会触发限流逻辑~curlhttp://127.0.0.1:8066/hello2{"code":1,"message":"这是一条成功消息","data":{"id":100,"code":"100-100","stockModel":{"id":1,"code":"STOCK==>1000"}}}~curlhttp://127.0.0.1:8066/hello2{"code":-100,"message":"系统错误(限流和熔断业务逻辑)","data":null}集成OpenFegin1.导入openfeign依赖Sentinel集成Openfeign需要导入spring-cloud-starter-openfeignorg.springframework.cloudspring-cloud-starter-openfeign2.YML配置Sentinel集成Openfeign需要开启feign支持,配置如下:feign:sentinel:enabled:true注意:启动类要加上@EnableFeignClients配置Openfeign的启用3.调用代码Feign接口调用服务stock-service的/getStockDetail接口,如果触发流控规则,将执行FallbackFactory中返回StockFeign的本地stub方法。@FeignClient(name="stock-service",fallbackFactory=StockFeignFallbackFactory.class)publicinterfaceStockFeign{@GetMapping("/getStockDetail")CommonResultgetStockDetail();}StockFeignFallbackFactory类是服务降级的处理。@ComponentpublicclassStockFeignFallbackFactoryimplementsFallbackFactory{privateLoggerlog=LoggerFactory.getLogger(StockFeignFallbackFactory.class);@OverridepublicStockFeigncreate(Throwablethrowable){returnnewStockFeign(){@OverridepublicCommonResultgetStockDetailquerythrowable(log){“详细信息”调用;returnnull,CommonResult-10("库存明细降级查询调用");}};}}控制器调用代码@AutowiredprivateStockFeignstockFeign;@GetMapping("/hello1")publicCommonResulthello(){CommonResultresult=stockFeign.getStockDetail();if(result.getCode()!=1){returnCommonResult.error(null,result.getCode(),result.getMessage());}StockModelstockDetail=result.getData();OrderModelorderModel=newOrderModel();orderModel.setStockModel(stockDetail);returnCommonResult.success(orderModel);}4.业务执行如果我们多次访问,Sentinel会触发降级策略。然后执行StockFeignFallbackFactory的本地stub方法返回源码地址gitee:https://gitee.com/zhengsh/excavator参考https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html#_spring_cloud_alibaba_sentinelhttps://segmentfault.com/a/1190000019070557