SpringMVC实践之集成Sentinel限流功能
文章目录
背景
近期收到线上报警,发现个别新接口在同1s内被请求了接近上百次,对系统的稳定造成了一些影响,近期调研了一下通用的限流框架,打算将Sentinel的限流功能集成进新服务
Sentinel前置知识
Sentinel 限流主要涉及以下几方面
Resource
限流的资源,资源支持动态加载,核心类为: AbstractDataSource
,Sentinel 默认提供了市面常见的资源管理服务的实现,也可以自定义实现
Rule
对定义的 Resouce 应用的限流规则,基于QPS、响应时间与系统负载。Sentinel 是通过一系列的功能Slot来实现不同的统计/控制功能,对于限流功能对应的就是 FlowSlot

FlowSlot
的功能实现需要依赖前面的 NodeSelectorSlot
和 ClusterBuilderSlot
等统计Slot,有了统计信息才可以针对配置进行限流操作,这里面借用一张官方的实现图
各Slot默认的顺序也可以在代码中找到
核心处理逻辑
核心逻辑是在执行调用chain的捕获Blockexcption然后执行后续操作

集成步骤
借助SpringMVC中提供的 HandlerInterceptor
拦截器功能 与 Sentinel 提供的SpringMVC框架集成类库可以方便快速的实现限流功能
引入Sentinel SpringMVC Adapter
|
|
配置SentinelWebInterceptor
Sentinel SpringMVC Adapter中提供了 SentinelWebInterceptor
来实现限流功能,这个 Interceptor 支持一些自定义的行为,主要通过 SentinelWebMvcConfig 来实现
SentinelWebMvcConfig 常用配置说明
SentinelWebMvcConfig 支持以下配置能力
-
urlCleaner
自定义对请求url的处理,比如厂商此次需要通过请求的设备id维度进行限流,对于其它的请求参数都进行忽略,最终可定义效果为:
/api/v1/test/ping?did=6308103f1026acf274bbcc1b10001291551xxX
-
httpMethodSpecify
是否指定特定的Http请求方法,此设置是对资源的请求方法进行了细粒度的配置,默认为false不开启,配置为true后,会在设定好的资源名前加上请求的方法,类似效果:
GET: /api/v1/test/ping?did=6308103f1026acf274bbcc1b10001291551xxX
-
blockExceptionHandler
被Block的请求异常处理器,对Block的请求进行自定义处理,可以设置返回的值,如果未配置则需要服务自己捕获 BlockException,可以通过配置
ExceptionHandler
进行统一处理
-
originParser
请求来源处理器,针对请求的来源进行处理,在配置资源的规则的可以使用此解析的origin细粒度控制,例如可以解析ip、用户做为请求 origin
配置 SentinelWebMvcConfig
由于此次只需要根据用户设备维度进行限流,所以只自定义配置了 urlCleaner,代码如下:
对于BlockException统一配置ExceptionHandler实现
新增 DefaultSentinelInterceptor
为了后续能将此功能做的更通用,没有直接使用 SentinelWebInterceptor
, 而是新增了 SentinelWebInterceptor
一个子类 DefaultSentinelInterceptor
,将 DefaultSentinelInterceptor
做为Spring的一个Component进行管理,这样就可以方便的把上述配置的 SentinelWebMvcConfig 进行注入

配置 DefaultSentinelInterceptor 到 Spring的WebMvcConfigurer中
在 WebMvcConfigurer 的实现类增加 DefaultSentinelInterceptor
拦截器配置,配置其优先级为 PrepareInterceptor 后

配置的资源在哪?
找了一下,Peacock已经提供了基于七彩石配置的Resouce实现 RainbowSentinelDatasourceInit
,配置在 SentinelDatasourceConfiguration
,解析的是 flowRule.json
文件,配置的内容就是官方的配置风格,这样看完全可以拿来一用而不需要再实现一遍了。
来看看 flowRule.json 能配置哪些内容
再借一张官方图
基本上使用了官方提供的默认配置值即可,对于 count 值可以根据线上提供服务的机器数进行配置即可。在实现配置时增加了一个 regex 项,即支持正则匹配,这样对于厂商根据设备id的维度进行限流就可以在 resource 项直接配置一个正则就可以了,具体配置如下:
- strategy可配置值为 0(直接)、1(链路)、2(关联)
- controlBehavior可配置值为 0. 直接拒绝, 1. WarmUp, 2. 匀速, 3. 排队等待