使用Sentinel实现接口限流

本文转载自微信公众号「运维开发故事」,作者老郑。转载本文请联系运维开发故事公众号。

集贤ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!

在前面一篇文章我已经对 Sentinel 做了一个简单的介绍,相信大家对 Sentinel 有一个简单的了解,本次主要是讲 Sentinel 的使用。在 sentinel-dashboard 配置流控规则,以及使用 Sentinel 整合 RestTemplate、OpenFeign 进行流控使用(建议网页版阅读)。

安装 sentinel dashboard

我使用的 sentinel 版本是: sentinel-dashboard-1.8.0

启动控制台命令:

 
 
 
 
  1. java -jar sentinel-dashboard-1.8.0.jar

默认启动的是 8080 端口, 登录账号和密码默认都是: sentinel。 如果需要修改启动端口可以在启动命令前面加 -Dserver.port=9999 进行修改。

使用介绍

通常我们在项目中对于 Sentinel 最常用的场景,就是默认的流控对接口的访问添加流控规则。Sentinel 也提供了对于 RestTemplate 、OpenFegin 的支持。

简单案例

1. 导入依赖

如果我们需要使用 Sentinel ,首先我们需要在业务服务中,导入 Sentinel 客户端的依赖。下面是 Maven 的 pom 依赖。 我们可以直接使用 spring-coud-starter-alibaba-sentinel 进行快速整合。

 
 
 
 
  1.   com.alibaba.cloud
  2.   spring-cloud-starter-alibaba-sentinel

对于 spring-cloud-alibaba 相关的版本依赖信息如下:

 
 
 
 
  1.   2.3.10.RELEASE
  2.   Hoxton.SR8
  3.   2.2.5.RELEASE
  4.   
  5.     
  6.       org.springframework.boot
  7.       spring-boot-dependencies
  8.       ${spring-boot.version}
  9.       pom
  10.       import
  11.     
  12.     
  13.       org.springframework.cloud
  14.       spring-cloud-dependencies
  15.       ${spring-cloud.version}
  16.       pom
  17.       import
  18.     
  19.     
  20.     
  21.       com.alibaba.cloud
  22.       spring-cloud-alibaba-dependencies
  23.       ${spring-cloud-alibaba.version}
  24.       pom
  25.       import
  26.     
  27.   

2. YML 配置

我们在业务服务中导入了依赖过后,我们需要修改 application.yml 文件让服务启动过后自动注册到 sentinel-dashboard 服务上。

 
 
 
 
  1. spring:
  2.   cloud:
  3.     sentinel:
  4.       transport:
  5.         port: 8719
  6.         dashboard: localhost:8080

3. 测试接口定义

首先我们需要定义对外开放的接口。

 
 
 
 
  1. @RestController
  2. public class HelloController {
  3.     
  4.     @GetMapping("/hello")
  5.     public String hello () {
  6.         return "OK";
  7.     }
  8. }

4. 通过控制台配置流控规则

注意:如果已经启动 snetinel-dashboard 后并且启动业务服务,在 sentinel-dashboard 后台还是没有服务的话,我们可以先访问一下业务服务的接口,然后在刷新snetinel-dashboard 观察是否正常。如果还是不正常请考虑 sentinel 的 client 版本和 dashboard 是否匹配。

首先选择自己对应服务展开,然后选择【簇点链路】 菜单。选择需要流控的接口 /hello 然后选择 【流控】按钮进行流控配置

我们可以配置, 我们选择【阀值类型】选择【QPS】,然后设置【单机阀值】 填入 1 。表示该接口每秒钟只能接受一个 QPS ,如果超过阈值过后就会触发 【流控】默认 Sentinel 返回 Blocked by Sentinel (flow limiting)

5. 流控规则触发

如果我们需要触发流控规则我们频繁访问 /hello 接口即可。

 
 
 
 
  1. ~ curl http://127.0.0.1:8066/hello
  2. OK%                                                                                                                                                   ~ curl http://127.0.0.1:8066/hello
  3. ~ curl http://127.0.0.1:8066/hello
  4. Blocked by Sentinel (flow limiting)%

通过上面的结果我们可以看到当单位时间内超过阈值过后, 就会触发 flow limit

整合 RestTemplate

1. YML 配置

Sentinel 整合 Resttemplate 除了需要导入 spring-cloud-starter-alibaba-sentinel 开需要开启 Sentinel 对 Resttemplate 的支持。

 
 
 
 
  1. resttemplate:
  2.   sentinel:
  3.     enabled: true

2. 创建 RestTemplate

如果 RestTemplate 在使用的时候需要使用到 Sentinel 的流控规则,首先需要在创建 RestTemplate 的时候添加 @SentinelRestTemplate 注解。注意: SentinelExceptionHandler 中的方法都是 static 方法

 
 
 
 
  1. @Configuration
  2. public class RestTemplateConfig {
  3.     @Bean
  4.     @ConditionalOnMissingBean(RestTemplate.class)
  5.     @LoadBalanced
  6.     @SentinelRestTemplate(
  7.             blockHandler = "handlerException", blockHandlerClass = SentinelExceptionHandler.class,
  8.             fallback = "handleFallback", fallbackClass = SentinelExceptionHandler.class)
  9.     public RestTemplate restTemplate() {
  10.         return new RestTemplate();
  11.     }
  12. }
  13. // 异常处理类
  14. public class SentinelExceptionHandler {
  15.     
  16.     //限流熔断业务逻辑
  17.     public static SentinelClientHttpResponse handlerException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
  18.         String message = JSON.toJSONString(CommonResult.error(-100,"系统错误 (限流熔断业务逻辑)"));
  19.         return new SentinelClientHttpResponse(message);
  20.     }
  21.     //异常降级业务逻辑
  22.     public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
  23.         String message = JSON.toJSONString(CommonResult.error(-100,"系统错误 (异常降级业务逻辑)"));
  24.         return new SentinelClientHttpResponse(message);
  25.     }
  26. }

3. 接口定义

下面就是我们使用的代码,可能写得稍微有点复杂,我来解释一下。首先我是通过 RestTemplate 访问 stock-service 服务的 /getStockDetail 接口然后将接口的返回数据解析,通过CommonResult 实例对象进行接收, 如果失败就返回错误信息。

 
 
 
 
  1. @Autowired
  2. private RestTemplate restTemplate;
  3. @GetMapping("/hello2")
  4. public CommonResult hello2() {
  5.   ParameterizedTypeReference> typeRef =
  6.     new ParameterizedTypeReference>() {
  7.   };
  8.   ResponseEntity>
  9.     forEntity = restTemplate.exchange("http://stock-service/getStockDetail", HttpMethod.GET,
  10.                                       HttpEntity.EMPTY, typeRef);
  11.   OrderModel orderModel = new OrderModel();
  12.   orderModel.setId(100);
  13.   orderModel.setCode("100-100");
  14.   if (Objects.equals(forEntity.getStatusCode(), HttpStatus.OK) && Objects.nonNull(forEntity.getBody())) {
  15.     CommonResult result = forEntity.getBody();
  16.     if (result.getCode() != 1) {
  17.       return CommonResult.error(null, result.getCode(), result.getMessage());
  18.     }
  19.     orderModel.setStockModel(result.getData());
  20.   }
  21.   return CommonResult.success(orderModel);
  22. }

4. 流控触发

如果我们频繁的访问我们的接口 /hello2 就会出现限流的逻辑

~ curl http://127.0.0.1:8066/hello2

{"code":1,"message":"this is a success message","data":{"id":100,"code":"100-100","stockModel":{"id":1,"code":"STOCK==>1000"}}}

~ curl http://127.0.0.1:8066/hello2

{"code":-100,"message":"系统错误 (限流熔断业务逻辑)","data":null}

整合 OpenFegin

1. 导入 openfeign 依赖

Sentinel 整合 Openfeign 需要导入 spring-cloud-starter-openfeign

 
 
 
 
  1.   org.springframework.cloud
  2.   spring-cloud-starter-openfeign

2. YML 配置

Sentinel 整合 Openfeign 需要开启对 feign 的支持,配置如下:

 
 
 
 
  1. feign:
  2.   sentinel:
  3.     enabled: true

注意:启动类上要增加 @EnableFeignClients 来配置 Openfeign 的启用

3. 调用代码

Feign 接口调服务 stock-service 的 /getStockDetail 接口,如果触发流控规则就会执行 FallbackFactory 中返回 StockFeign 的本地存根方法。

 
 
 
 
  1. @FeignClient(name = "stock-service", fallbackFactory = StockFeignFallbackFactory.class)
  2. public interface StockFeign {
  3.     @GetMapping("/getStockDetail")
  4.     CommonResult getStockDetail();
  5. }

StockFeignFallbackFactory 类是服务降级的处理。

 
 
 
 
  1. @Component
  2. public class StockFeignFallbackFactory implements FallbackFactory {
  3.     private Logger log = LoggerFactory.getLogger(StockFeignFallbackFactory.class);
  4.     @Override
  5.     public StockFeign create(Throwable throwable) {
  6.         return new StockFeign() {
  7.             @Override
  8.             public CommonResult getStockDetail() {
  9.                 log.error("调用查询库存详情降级", throwable);
  10.                 return CommonResult.error(null, -100, "调用查询库存详情降级");
  11.             }
  12.         };
  13.     }
  14. }

Controller 调用代码

 
 
 
 
  1. @Autowired
  2. private StockFeign stockFeign;
  3. @GetMapping("/hello1")
  4. public CommonResult hello() {
  5.   CommonResult result = stockFeign.getStockDetail();
  6.   if (result.getCode() != 1) {
  7.     return CommonResult.error(null, result.getCode(), result.getMessage());
  8.   }
  9.   StockModel stockDetail = result.getData();
  10.   OrderModel orderModel = new OrderModel();
  11.   orderModel.setStockModel(stockDetail);
  12.   return CommonResult.success(orderModel);
  13. }

4. 业务执行

如果我们多次访问,Sentinel 就会触发降级策略。然后执行 StockFeignFallbackFactory 的本地存根方法返回

源码地址

gitee: https://gitee.com/zhengsh/excavator

参考

https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/en-us/index.html#_spring_cloud_alibaba_sentinel

https://segmentfault.com/a/1190000019070557

新闻名称:使用Sentinel实现接口限流
分享路径:http://www.stwzsj.com/qtweb/news35/5685.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联