随着近些年系统稳定性要求越来越高,而系统限流则是其中提高系统稳定性的手段之一,而在众多限流平台中Sentinel凭着丰富功能特性和多次阿里双十一的线上实践,成为最热门限流平台之一,本文就Sentinel相关特性进行分析并测试并对底层原理进行分析,为后续相关系统建设积累经验。
限流;熔断;自适应保护;Sentinel;流量控制
应用系统应对高并发访问时怎么保证系统稳定性?常用解决方案有两种,分别为系统限流、系统动态扩容,相对于扩容技术复杂度来说,限流成本则低很多,因为动态扩容需要引入Kubernetes、Docker等容器化技术(如检查当前系统负载达到一个阈值,动态加入指定数量的机器,来分担并发请求,来降低系统压力),而是容器化技术对人员技术和成本投入要求都比较高,所以大部分中小规模的公司都不会选择这种方案,但是系统稳定性还是要保证,因此就把目光聚焦到系统限流领域,因为系统限流对人力成本和技术要求都不是特别高,业界也有很多现有开源优秀解决方案,而其中最热门当属Sentinel限流平台,因此本次就以Java语言为基础调研Sentinel相关特性,为后续相关系统建设积累经验。
随着近些年互联网的快速普及,互联网用户数开始进行指数倍增长,而系统限流成为了是比较火热技术话题,因为他是保证系统稳定性的手段之一,纵观国内外,在toC、toB相关业务公司,信息系统都会进行限流处理,而限流的领域很广,从前端界面、负载均衡器(Nginx、Apache、F5)、软件系统层面都有涉及,在软件系统层面,国内外公司在2018年之前都是以较为简单方式进行限流如基于Guava、Resilience4j、Hystrix框架的单机限流和Redis共享存储分布式限流,很少有平台型的限流平台供他们做统一的限流管理,直到2018年阿里巴巴开源限流平台Sentinel,国内外用户才开始进行了平台化集成。
本次主要对Sentinel基本特性进行了解,并对Sentinel常用功能进行集成测试以及底层实现原理进行分析。
Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付应用、运行应用。 Docker允许用户将基础设施中的应用单独分割出来,形成更小的颗粒,从而提高交付软件的速度,Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
官方链接:https://www.docker.com/
Kubernetes 是用于自动部署,扩展和管理容器化应用程序的开源系统,例如对Docker容器的管理, 源自Google 15 年生产环境的运维经验,同时凝聚了社区的最佳创意和实践,此平台目前在市场占有超一半的市场份额。
官方链接:https://kubernetes.io/zh/
GitHub是世界上最大的代码托管平台,超5千万开发者正在使用。GitHub中文社区是一个致力于分享和传播GitHub上优质开源项目的中文社区平台。
官方链接:https://github.com/
Guava是google开源的Java工具库,包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。 所有这些工具每天都在被Google的工程师应用在产品服务中。
官方链接:https://github.com/google/guava
SPI(Service Provider Interface),是JDK内置的一种 服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是 *解耦*,具体请查看:https://pdai.tech/md/java/advanced/java-advanced-spi.html
Spring cloud是Spring官方推出的一系列框架的有序集合,致力于简化分布式系统基础设施的开发,如注册中心、配置中心、负载均衡、数据监控等,是一套非常完善的分布式系统基础开发框架,此框架使用在Java语言生态中占比非常高,有70%以上的公司在使用它。
官方链接:https://spring.io/projects/spring-cloud
ZooKeeper 是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。ZooKeeper 的架构通过冗余服务实现高可用性。
Zookeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
官方链接:https://zookeeper.apache.org/
QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
计算公式:QPS = req/sec = 请求数/秒
执行一个请求从开始到最后收到响应数据所花费的总体时间,即从客户端发起请求到收到服务器响应结果的时间。响应时间RT(Response-time),是一个系统最重要的指标之一,它的数值大小直接反应了系统的快慢。
并发数是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。
Apache Dubbo 是一款高性能、轻量级的开源服务框架,用于构建企业的分布式系统。
官方链接:https://dubbo.apache.org/zh/
Sentinel是阿里巴巴开源的分布式限流平台,目前在Github有18.4k的star,Github地址:https://github.com/alibaba/Sentinel.git,他主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性,他具有以下特征:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据,然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。
任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的,因此需要根据系统的处理能力对流量进行控制,而Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状, 见图1
图1 流量控制示意图
流量控制有以下几个角度:
资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
运行指标,例如 QPS、线程池、系统负载等;
控制的效果,例如直接限流、冷启动、排队等。
Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果
熔断降级也是Sentinel一大特性,现代的软件系统架构都是采用的微服务建构,由很多的服务组成,不用的服务相关调用,组成非常复杂的调用链路,如果其中一个服务不稳定,比如响应过慢,就会层层级联,最后导致整个链路都不可用。因此需要对不稳定的弱依赖的服务进行熔断降级,来提高系统的稳定性,避免因为局部不稳定,导致整个系统雪崩。
见图2不熔断降级,导致整个服务不可用的场景,如Service D服务不稳定,那么调用的Service F和Servce G,都在等待返回结果,而这会Servce A和Service B还在一直持续请求Service G和Service F,那么这会就会把整个链路的线程池打满,导致整个系统雪崩。
系统自适应保护也是Sentinel特性之一,当系统负载较高时,如果这时还持续有请求进入,那么就有可能导致系统雪崩。而现代的系统为了保证高可用和高可靠都会进行集群部署最少2台节点,如果这会当前节点已经崩溃,那么网络负载均衡器会把请求转发其他节点,如果这时其他节点也负载比较高,那么持续的转发过去请求也会导致其他节点崩溃,最后导致整个集群都可用 ,针对以上场景,Sentinel 提供了自适应保护机制,让系统的请求流量和系统负载达到一个平衡,以此来保证在范围之内处理更多的请求。
见图3,为Sentinel功能架构,主要分为控制台和客户端2部分:
• 控制台是基于SprintBoot框架开发并且可独立部署,主要有功能有应用系统流量实时监控、应用机器发现、限流规则配置等功能。
• 客户端需要集成到应用系统中,是Sentinel最核心的部分,支持适配多种语言和框架,目前支持Java语言和Go语言,支持Spring-cloud、Dubbo、gRPC、Service Mesh框架、以及普通的Java应用和Go应用都支持,限流规则存储默认采用的基于内存的方式,支持用户扩展支持ZooKeeper、Nacos、Apollo配置中心,其次功能特性都是围绕着流量控制、熔断降级、自适应保护这三个点扩展而来。
图3 Sentinel功能架构
为了能更直观的展示出Sentinel的优势,因此特意整理了目前市场上比较热门的限流方案进行对比,见表1
表1 Sentinel与其他限流方案支持功能特性一览
Sentinel | Hystrix | resillence4j | |
---|---|---|---|
隔离策略 | 信号量隔离(并发控制) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于慢调用比例、异常比例、异常数 | 基于异常比例 | 基于异常比例、响应时间 |
实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于RxJava) | Ring Bit Buffer |
动态规则配置 | 支持近十种动态数据源 | 支持多种数据源 | 有限支持 |
扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
单机限流 | 基于QPS,支持调用关系的限流 | 有限支持 | Rate Limiter |
集群限流 | 支持 | 不支持 | 不支持 |
流量整形 | 支持慢启动、匀速排队模式 | 不支持 | 简单的Rate Limiter |
系统自适应保护 | 支持 | 不支持 | 不支持 |
热点识别/防护 | 支持 | 不支持 | 不支持 |
多语言支持 | Java/Go/C++ | Java | Java |
Service Mesh支持 | 支持Envoy/Istio | 不支持 | 不支持 |
控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 简单监控查看 | 不提供控制台,支持对接其他监控平台 |
框架适配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix | Servlet、Spring Cloud |
Github star | 18.4k | 22.3k | 7.6k |
社区活跃度 | 高 | 低,停止维护 | 中 |