开发者说:Sentinel 流控功能在 SpringMVC/SpringBoot 上的实践
从用户的视角来感受一个开源项目的成长,是我们推出「开发者说」专栏的初衷,即在开发者进行开源项目选型时,提供更为立体的项目信息。专栏所有内容均来自作者原创/投稿,本文是「开发者说」的第6篇,作者 Jason Joo,@友乐活(北京),Sentinel Committer.
1st:《深度剖析开源分布式事务方案 Seata 的事务协调器》
3st:《消息队列 Kafka 和 RocketMQ 之我见》
集成 Sentinel 前生
流控在分布式系统中是较为基本的需求,其需要在系统负载、服务质量、流量甄别、安全⻛控等⽅⾯进⾏保障,并根据业务需求,进⾏动态调整或⼈工临时介入,尤其是在⼀些事件性的时期,以实现快速控制和恢复服务的效果。
流控手段一般挂载在流量网关和业务内的逻辑。
流量网关常见于 Nginx 这类代理层,通过扩展插件、Lua脚本进⾏针对 IP/Path/Query 等形式的流控。业务内则⼤多在局部或框架层进行信号量、线程池、超时时间或其它逻辑来实现流控。前者主要体现在运维的可操作性,不侵⼊业务线,而后者则针对性更强,但有侵⼊性或修改时需要部署,⾯向业务团队可控。
两种类型的流控往往⽐较割裂(由不同的团队在不共享的空间内进行控制),常出现指标的不协调性。
为了解决这⼀问题,我们开始汇总现有的需求,调研相关的系统,并准备实现⼀套可以同时面向业务和运维,进行应用级隔离和满足基本规则类型需求的流控实现,预期是在 Nginx 端利用LuaJIT实现一套更为强大的流控模块。
调研过程中,适逢 Sentinel 0.1/0.2的发布,⽀持servlet集成(URL限流),带有操作⾯板(Dashboard),支持基本的实时状况查看、实时的修改分发规则、全局负载和单点熔断,能基于QPS、信号量等形式进行流控。除了零侵入以外,基本满⾜我们的需求,所以准备基于 Sentinel 进行方案落地尝试。
集成 Sentinel 的实践
我们的基本需求如下:
- 基于 URL 做流控
- 基于 Dashboard 做动态修改规则
- 业务端针对 SpringMVC/SpringBoot
- ⽀持异步 Servlet (后续提出)
- sentinel-transport 监听端⼝可定制(涉及防⽕墙配置、同⼀节点多服务)
集成适配
基于 Sentinel 所提供的功能、适配方式,需要进行基本的配置和修改。
集成方式
现有项⽬流量⼊口部分⼤多为基于 SpringMVC 的项目,少部分为 SpringBoot 项目,并且从运维部署的角度看,⽬前主要有普通运⾏方式(JVM/Tomcat)和容器化方式。
- 普通运行方式:尽量避免修改 JVM 启动参数,参数通过集中配置中心或 properties ⽂件来定义;
- 容器化⽅式:参数⼤多是通过 ENV 环境变量进行定义。
所以我们根据实际的需求,将 Sentinel 初始化⼯作进⾏了封装,基于 SpringMVC 提供了XML初始化方式,基于 SpringBoot 提供了注解初始化方式,例如:
集成框图
集成要点
- ⾃动判断是否引⼊了对应的 Sentinel 依赖
- ⾃动配置
- 采用ZooKeeper为规则存储中心(重⽤现有基建)
- 节点端支持对规则的读和写
- 集成sentinel-transport-netty-http来支持Dashboard
- 利用 Dashboard 通过 API 操作单⼀节点的能⼒间接地将规则写入Zookeeper,从而分发⾄所有节点
主要使⽤了sentinel-web-servlet,采用这个方案,⽆需对Dashboard做任何⼆次开发,可跟随升级,对业务侵入较少
对 Sentinel 的期待
- 简化不同场景下的流控集成与落地
- 更简单非严格的集群限流,引入⾼可⽤
- Dashboard
- 实现 Dubbo/ZooKeeper/Spring/Servlet 相关适配标准的开箱即用
本文作者:
Jason Joo,Sentinel Committer,@友乐活(北京),hblzxsj@163.com,拥有超过⼗年的软硬件体系技术实践,傍身技能:Java/C/Golang,数据中间件/分布式系统设计/容器编排调度熟悉TCP/IP协议栈与优化(*nix),Linux内核⼆次开发。
本文作者:中间件小哥
本文为云栖社区原创内容,未经允许不得转载。