Dubbo使用Sentinel来对服务进行降级与限流

一、Sentinel 是什么

Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。 点此地址了解更多Sentinel

二、Sentinel 怎么用

Sentinel分为两个部分:客户端以及控制台。

  • 控制台用于管理限流,熔断规则的发布与监控。
  • 客户端则用于接收规则,并执行相关规则。

1. 下载Sentinel控制台

当前最新的release版本为1.4.0

https://github.com/alibaba/Sentinel/releases/tag/1.4.0

2. 运行Sentinel控制台

注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

使用如下命令启动控制台:

1java -Dserver.port=8080 \ 2-Dcsp.sentinel.dashboard.server=localhost:8080 \ 3-Dproject.name=sentinel-dashboard \ 4-jar sentinel-dashboard.jar

其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080。

访问http://localhost:8080查看控制台信息。 

3. 客户端Dubbo集成

使用时需引入以下模块(以 Maven 为例):

1<dependency> 2 <groupId>com.alibaba.csp</groupId> 3 <artifactId>sentinel-dubbo-adapter</artifactId> 4 <version>1.4.0</version> 5</dependency> 6 7<dependency> 8 <groupId>com.alibaba.csp</groupId> 9 <artifactId>sentinel-transport-simple-http</artifactId> 10 <version>1.4.0</version> 11</dependency>

启动时加入 JVM 参数

1-Djava.net.preferIPv4Stack=true \ 2-Dcsp.sentinel.api.port=8720 \ 3-Dcsp.sentinel.dashboard.server=localhost:8787 \ 4-Dproject.name=example-customer

启动项参数说明:

  • -Dcsp.sentinel.api.port 接受数据推荐的http端口
  • -Dcsp.sentinel.dashboard.server 指定控制台地址
  • -Dproject.name 指定控制台显示的项目名称

更详细的信息可以参考启动配置项

然后你可以愉快的打开控制台对你的服务进行限流,熔断降级了。

三、现有的问题

  1. 规则的推送目前采用的是以http接口的形式进行数据处理,当发布规则时,需要采用遍历所有的客户端,以http的形式进行数据推送,此方式的问题在于服务部署数量越来越多,发布规则也就越来越慢,越来越困难。
  2. Sentinel的熔断限流统计则是以异常发生数为依据,真正使用过程中还需要排除业务异常。
  3. 监控数据目前的做法是遍历所有的客户端采用http进行批量远程读取,并存储入库,且实时监控仅能查看5分钟内的metric数据。
  4. Sentinel的启动注入参数的方式太过原始。

四、如何改造

1. 关于Dashboard的数据推送问题的改造,思路可以考虑将数据传递到配置中心,利用配置中心来进行数据推送广播。

  • 改造前:客户端利用sentinel-transport-simple-http模块暴露一个特定的端口,Sentinel Dashboard通过http的形式进行数据推送,客户端接收后将规则保存在本地内存中。 改造前
  • 改造后:客户端注册到相关的注册中心中,Sentinel Dashboard控制台将配置信息推送到配置中心,如nacos,zookeeper中,由配置中心去进行配置推送。 改造后

2. 关于Sentinel的业务异常问题,可以考虑采用类似于Hystrix的方法,HystrixBadRequestException被Hystrix认定为这是消费者自身的问题,而非提供者的服务不稳定,即我们常说的业务异常不被熔断。

方法1:采用包装异常的形式,将所有的异常包装为统一的结构体,并设定异常状态码,例如业务异常都是400,服务异常是500。

1public class Result<T> { 2 3 /** 4 * 状态码 5 */ 6 private int code; 7 8 /** 9 * 消息 10 */ 11 private String message; 12 13 /** 14 * 数据 15 */ 16 private T result; 17 18 // TODO 忽略get,set 19} 20 21Entry entry = null; 22try { 23 entry = SphU.entry(resourceName, entryType, 1, pjp.getArgs()); 24 Object result = pjp.proceed(); 25 26 // 核心判断 27 if (result instanceof Result && ((Result) result).getCode() == 500) { 28 Tracer.trace(new RuntimeException(((Result) result).getMessage())); 29 } 30 return result; 31} catch (BlockException ex) { 32 return handleBlockException(pjp, annotation, ex); 33} catch (Throwable ex) { 34 Tracer.trace(ex); 35 throw ex; 36} finally { 37 if (entry != null) { 38 entry.exit(); 39 } 40}

方法2:采用抛异常的形式,定义一个BussinessException业务异常。

1Entry entry = null; 2try { 3 entry = SphU.entry(resourceName, entryType, 1, pjp.getArgs()); 4 return pjp.proceed(); 5} catch (BlockException ex) { 6 return handleBlockException(pjp, annotation, ex); 7} catch (BussinessException ex) { 8 // 核心处理 9 throw ex; 10} catch (Throwable ex) { 11 Tracer.trace(ex); 12 throw ex; 13} finally { 14 if (entry != null) { 15 entry.exit(); 16 } 17}

至于采用何种方式进行改造,见仁见智吧。

3. Sentinel监控问题,可以考虑采用CrateDB + Grafana/或者数据落地InfluxDB等方式。

相关链接参考:

4. Sentinel的启动注入参数的方式太过原始,可以考虑使用spring-boot-starter的方式,采用自动化配置。

五、项目推荐

楼主自己改造了一个版本,目前已实现的功能如下:

  1. 新增dubbo的filter将异常包装成统一返回体,将异常状态码定义为>=500的值(与HttpStatus相对应),修改SentinelResourceAspect实现,判断返回的状态码是否为>=500,如果是则进行熔断统计。
  2. 并新增sentinel-dubbo-starter,进行自动配置化。
  3. Sentinel Dashboard改造:控制台规则 -> 配置中心 -> 客户端。

欢迎start,如有问题,欢迎指出,共同进步:

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

00:Java简单了解

浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。