在前面一篇文章我已经对 Sentinel 做了一个简单的介绍,相信大家对 Sentinel 有一个简单的了解,本次主要是讲 Sentinel 的使用。在 sentinel-dashboard
配置流控规则,以及使用 Sentinel 整合 RestTemplate、OpenFeign 进行流控使用(建议网页版阅读)。
安装 sentinel dashboard
我使用的 sentinel 版本是: sentinel-dashboard-1.8.0
启动控制台命令:
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
进行快速整合。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
对于 spring-cloud-alibaba 相关的版本依赖信息如下:
<properties> <spring-boot.version>2.3.10.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR8</spring-cloud.version> <spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version></properties><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
2. YML 配置
我们在业务服务中导入了依赖过后,我们需要修改 application.yml 文件让服务启动过后自动注册到 sentinel-dashboard
服务上。
spring: cloud: sentinel: transport: port: 8719 dashboard: localhost:8080
3. 测试接口定义
首先我们需要定义对外开放的接口。
@RestControllerpublic class HelloController { @GetMapping("/hello") public String hello () { return "OK"; }}
4. 通过控制台配置流控规则
注意:如果已经启动
snetinel-dashboard
后并且启动业务服务,在sentinel-dashboard
后台还是没有服务的话,我们可以先访问一下业务服务的接口,然后在刷新snetinel-dashboard
观察是否正常。如果还是不正常请考虑 sentinel 的 client 版本和dashboard
是否匹配。
首先选择自己对应服务展开,然后选择【簇点链路】 菜单。选择需要流控的接口 /hello
然后选择 【流控】按钮进行流控配置
Sentinel控制台1.8.0
应用名
搜索
树状视图
列表刻图
1.展开需要设置服务er-service
首页
(1/1)
order-service
赢点链路
刷新
关键字
172.20.10.3:8720
实时监控
通过QPS拒绝QPS线程数
分钟通过分钟拒绝
资源名
平均RT
操作
旗点链路
0
0
0
0
0
sentineldetaurt.context
+授权
流控
降级
热点
流控规则
0
0
13
0
授权
+降级
流控
热点
降级规则
.
o
0
13
0
mello
凌权
热点
降级
流控
热点规则
2.选择需要流控的接口
系统规则
授权规则
集群流控
机器列表
(0/1)
stock-service
我们可以配置, 我们选择【阀值类型】选择【QPS】,然后设置【单机阀值】 填入 1 。表示该接口每秒钟只能接受一个 QPS ,如果超过阈值过后就会触发 【流控】默认 Sentinel 返回 Blocked by Sentinel (flow limiting)
新增流控规则
资源名
hello
针对来源
default
单机阁值
单机阑值
闹值类型
线程数
QPS
是否集群
高级选项
取消
新增并继续添加
新增
5. 流控规则触发
如果我们需要触发流控规则我们频繁访问 /hello
接口即可。
~ curl http://127.0.0.1:8066/helloOK% ~ curl http://127.0.0.1:8066/hello~ curl http://127.0.0.1:8066/helloBlocked by Sentinel (flow limiting)%
通过上面的结果我们可以看到当单位时间内超过阈值过后, 就会触发 flow limit
整合 RestTemplate
1. YML 配置
Sentinel 整合 Resttemplate 除了需要导入 spring-cloud-starter-alibaba-sentinel
开需要开启 Sentinel 对 Resttemplate 的支持。
resttemplate: sentinel: enabled: true
2. 创建 RestTemplate
如果 RestTemplate 在使用的时候需要使用到 Sentinel 的流控规则,首先需要在创建 RestTemplate 的时候添加 @SentinelRestTemplate
注解。注意: SentinelExceptionHandler
中的方法都是 static 方法
@Configurationpublic class RestTemplateConfig { @Bean @ConditionalOnMissingBean(RestTemplate.class) @LoadBalanced @SentinelRestTemplate( blockHandler = "handlerException", blockHandlerClass = SentinelExceptionHandler.class, fallback = "handleFallback", fallbackClass = SentinelExceptionHandler.class) public RestTemplate restTemplate() { return new RestTemplate(); }}// 异常处理类public class SentinelExceptionHandler { //限流熔断业务逻辑 public static SentinelClientHttpResponse handlerException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) { String message = JSON.toJSONString(CommonResult.error(-100,"系统错误 (限流熔断业务逻辑)")); return new SentinelClientHttpResponse(message); } //异常降级业务逻辑 public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) { String message = JSON.toJSONString(CommonResult.error(-100,"系统错误 (异常降级业务逻辑)")); return new SentinelClientHttpResponse(message); }}
3. 接口定义
下面就是我们使用的代码,可能写得稍微有点复杂,我来解释一下。首先我是通过 RestTemplate
访问 stock-service
服务的 /getStockDetail
接口然后将接口的返回数据解析,通过CommonResult<StockModel>
实例对象进行接收, 如果失败就返回错误信息。
@Autowiredprivate RestTemplate restTemplate;@GetMapping("/hello2")public CommonResult<OrderModel> hello2() { ParameterizedTypeReference<CommonResult<StockModel>> typeRef = new ParameterizedTypeReference<CommonResult<StockModel>>() { }; ResponseEntity<CommonResult<StockModel>> forEntity = restTemplate.exchange("http://stock-service/getStockDetail", HttpMethod.GET, HttpEntity.EMPTY, typeRef); OrderModel orderModel = new OrderModel(); orderModel.setId(100); orderModel.setCode("100-100"); if (Objects.equals(forEntity.getStatusCode(), HttpStatus.OK) && Objects.nonNull(forEntity.getBody())) { CommonResult<StockModel> result = forEntity.getBody(); if (result.getCode() != 1) { return CommonResult.error(null, result.getCode(), result.getMessage()); } orderModel.setStockModel(result.getData()); } return CommonResult.success(orderModel);}
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
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
2. YML 配置
Sentinel 整合 Openfeign 需要开启对 feign 的支持,配置如下:
feign: sentinel: enabled: true
注意:启动类上要增加 @EnableFeignClients
来配置 Openfeign 的启用
3. 调用代码
Feign 接口调服务 stock-service
的 /getStockDetail
接口,如果触发流控规则就会执行 FallbackFactory
中返回 StockFeign
的本地存根方法。
@FeignClient(name = "stock-service", fallbackFactory = StockFeignFallbackFactory.class)public interface StockFeign { @GetMapping("/getStockDetail") CommonResult<StockModel> getStockDetail();}
StockFeignFallbackFactory
类是服务降级的处理。
@Componentpublic class StockFeignFallbackFactory implements FallbackFactory<StockFeign> { private Logger log = LoggerFactory.getLogger(StockFeignFallbackFactory.class); @Override public StockFeign create(Throwable throwable) { return new StockFeign() { @Override public CommonResult<StockModel> getStockDetail() { log.error("调用查询库存详情降级", throwable); return CommonResult.error(null, -100, "调用查询库存详情降级"); } }; }}
Controller 调用代码
@Autowiredprivate StockFeign stockFeign;@GetMapping("/hello1")public CommonResult<OrderModel> hello() { CommonResult<StockModel> result = stockFeign.getStockDetail(); if (result.getCode() != 1) { return CommonResult.error(null, result.getCode(), result.getMessage()); } StockModel stockDetail = result.getData(); OrderModel orderModel = new OrderModel(); orderModel.setStockModel(stockDetail); return CommonResult.success(orderModel);}
4. 业务执行
如果我们多次访问,Sentinel 就会触发降级策略。然后执行 StockFeignFallbackFactory
的本地存根方法返回
~ curl http://127.0.0.1:8066/hello1{"code":1,"message":"this is a success message","data":{"id":null,"code":null,"stockModel":{"id":1,"code":"STOCK==>1000"}}}~ curl http://127.0.0.1:8066/hello1{"code":-100,"message":"调用查询库存详情降级","data":null}%