背景:
最近线上系统遇到线程耗尽,导致不能正常办理业务问题。通过分析发现,因为其中两个定时任务触发时间短,每个处理耗时反而很长,线程耗尽,已获的线程部分报没有提供者,即服务不可用,同时导致部分业务请求无法获得线程,业务中断无返回。
解决此具体问题可以用具体方案,比如将线程数量调大,有问题的定时任务触发时间调长。但是,我们希望避免类似问题再出现,因此可以采用熔断限流组件。比如Netflix的一款开源限流组件Hystrix,作为作为Spring Cloud官方默认的熔断组件,但是已经停止维护。另外一款是18年7月开源的sentinel,行业应用普遍。
熔断:如果当调用失败达到指定的次数,则将熔断器打开一段时间,即将请求链路断开;在指定时间内,都不再让消费者向提供者发送请求;当熔断时间到了,就将熔断器设置为半打开的状态,此时消费者可以往提供者发送请求,并统计成功次数,如果达到指定的成功次数,熔断器则变为关闭状态,即将请求链路打开,否则熔断器又变回打开状态。
限流:限制单位时间内请求数量,比如每秒只能1个请求,多余请求直接返回,不会发到服务提供者上去。
由于系统采用的是dubbo框架,dubbo自带服务降级,但是其服务降级可理解为将后端报错包装成具有业务意义的返回,并不带熔断。所以尽管每次因为 RPC 异常而导致调用失败,也不会进行熔断处理;即不管调用失败多少次,消费者还是会继续进行调用。其实这样会导致服务的资源浪费:
只要服务提供者出现异常达到一定的次数,其实可以理解为服务提供者短时间内已经不能正常提供服务了,后续再调用也是浪费资源。当出现提供者不可用,消费者还会进行 1+retires 次的 RPC 调用,这样就更加浪费资源了。所以,为 dubbo 配一个熔断机制是非常有必要的了。
Sentinel(微服务的哨兵)简介:
随着分布式系统变得越来越流行,服务之间的可靠性变得比以往任何时候都更加重要。Sentinel以“流量”为切入点,在流量控制、 流量整形、熔断、系统自适应保护等多个领域开展工作,保障微服务的可靠性和弹性。
哨兵具有以下特点:
丰富的应用场景:Sentinel在阿里巴巴已经被广泛使用,几乎覆盖了近10年双11(11.11)购物节的所有核心场景,比如“秒杀”需要限制突发流量到满足系统容量、消息削峰填谷、下游不可靠业务断路、集群流量控制等。
实时监控:Sentinel 还提供实时监控能力。可以实时查看单台机器的运行时间信息,以及500个节点以下集群的聚合运行时间信息。
广泛的开源生态系统:Sentinel 提供与常用框架和库(例如 Spring Cloud、Dubbo 和 gRPC)的开箱即用集成。您只需将适配器依赖项添加到您的服务即可轻松使用 Sentinel。
多语言支持:Sentinel 为 Java、Go和C++提供了本机支持。
丰富的SPI扩展:Sentinel提供简单易用的SPI扩展接口,可以让您快速自定义逻辑,例如自定义规则管理、适配数据源等。
具体可以参考:Sentinel: 官网阿里 Sentinel
Sentinel使用
本demo使用技术springboot+dubbo+mybatis-puls+sentinel,工程已上传github,地址是:https://github.com/zbf2016/springboot-dubbo-sentinel.git
工程目录截图:
dubbo-service:接口模块,所有需要暴露的接口放此模块,会被dubbo-consumer和dubbo-service模块依赖。
dubbo-common:公共模块,主要放工具类等。
dubbo-consumer:消费者模块。
dubbo-provider:服务提供者模块
sentinel配置放在common模块,如下:
服务提供者接口:
服务提供者接口实现
消费者需要继承熔断流控规则类:
测试,服务提供者不启动,模拟100次请求,一秒请求2次
观察结果如下:
当第0次请求,第2次请求,第4次请求,第6次请求都是正常,没有被限流,也就是符合1QPS的限流规则,说明sentinel起了限流作用。
当第10次请求后,所有的请求都被熔断了,符合熔断规则设置的5秒内10个请求,有2个异常及以上即熔断。
Sentinel监控
Sentinel监控可以直接在github下载jar包,参考github即可,启动后如下所示:
账号密码都是sentinel,初次进入是空白
当有请求之后,可在控制界面配置限流规则和熔断规则,目前只在服务生效期间有用,服务重启需要重新配,如需要长期有效,可以整合nacos即可
总结:sentinel使用简单,功能强大,在微服务系统中被广泛使用,让系统高可用。