news 2026/10/15 12:50:56

Sentinel授权规则与系统规则实战:白名单、黑名单与整机兜底

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Sentinel授权规则与系统规则实战:白名单、黑名单与整机兜底

Sentinel系列写到第五篇,前几篇我们把流控规则、降级规则、热点规则都过了一遍,到这篇剩下的就是授权规则和系统规则两个模块。标题上虽然写了“简要说明”,但以我实际排查问题的经验来看,这两个模块看着简单,用起来翻车的概率比流控规则还高。很多人配了授权规则不生效,配了系统规则发现接口全被拦了,问题往往出在没搞懂这两类规则在Sentinel整个拦截链里到底处于什么位置,以及它们背后依赖了哪些前置条件。这篇就用实战的方式把这两块拆开讲清楚,适合已经跑通Sentinel基础流程、准备在生产环境细化管控的同学参考。

1. 授权规则与系统规则:流控之外的“横向兜底”

从Sentinel的规则体系来看,流控、降级、热点规则针对的是单个资源,解决的是“某个接口能不能扛住这个量”的问题;而授权规则和系统规则解决的是另一类问题:一个请求到底有没有资格进来,以及这个应用整体还能不能撑住。这两类规则是横向的,作用在整个调用链上,不单纯挂在某一个资源名下。

1.1 授权规则到底在管什么

授权规则的核心是“我不能让谁进来”,区分白名单和黑名单两种模式。举个例子,线上有个下单接口,原本只应该由订单服务内部调用,结果被外部某个脚本盯上了,每天定时刷你几千次。流量不大,触发不了流控规则,但接口逻辑确实在被白嫖,业务上也说不清这些请求到底是哪来的。这时候授权规则就能派上用场:给请求来源打上标记,在Sentinel入口处直接拒绝黑名单来源,或者反过来,只允许白名单来源访问。

它的设计思路是“来源识别 + 黑白名单判断”,所以有一个关键前提:请求里必须能被解析出“来源应用”。这个来源可以是一个Header、一个参数、甚至一段自定义逻辑。如果应用里没做来源解析,授权规则就是一堆永远不生效的配置。

1.2 系统规则是给“整机”设的保险丝

系统规则的价值不在于保护某个接口,而在于保护整个应用进程。它的阈值维度包括系统Load、CPU使用率、入口QPS、平均RT、线程数,五个维度任何一项超标,都会触发全局拦截。典型的场景是业务大促期间,某个接口流量暴涨,流控规则还没来得及在对应的资源上生效,整个应用就快被拖垮了。这时系统规则像保险丝一样先跳闸,保住进程不被打挂。

这套机制的思路是“机器级别的兜底”,不分接口、不分调用方,一视同仁地限制入口流量。但它也有偏科的地方,比如你设置了入口QPS为1000,结果所有Web接口的请求都会算进这1000,如果某个接口本身会调用外部服务导致RT很高,也可能把全局平均RT拉高触发拦截。所以系统规则的阈值设置比流控规则更依赖对整机负载的理解,不能拍脑袋填数字。

2. 授权规则从配置到落地:请求来源解析是关键

授权规则看起来只有两个选项:白名单、黑名单,再加一个来源应用名称。但实际上最容易出问题的环节是“来源应用名称从哪来”。Sentinel不会自动知道调用方是谁,它需要你告诉它一个来源标识。

2.1 授权规则的判定逻辑

授权规则在Sentinel拦截链中位于统计完成之后、流控规则之前,核心类是AuthoritySlot。当一个请求进入时,Sentinel会调用RequestOriginParser解析出origin,然后拿着这个origin和当前资源的授权规则做匹配。

白名单模式下,limitApp里列出的来源允许通过,未列出的来源直接抛AuthorityException;黑名单模式正好反过来,列出的来源被拒绝,未列出的放行。

这里有个容易被忽略的细节:如果请求解析出来的origin为空或者为null,在白名单模式下请求会直接拒绝。原因很简单,白名单的语义是“只有列表里的才放行”,一个连来源都标识不出来的请求,自然不在信任范围内。所以实现RequestOriginParser时,至少要给一个兜底值,比如default,避免误伤正常请求。

2.2 来源解析:RequestOriginParser的实现细节

在Spring Boot的Web MVC场景下,spring-cloud-starter-alibaba-sentinel自动装配了SentinelWebInterceptor,它会从Spring容器中查找RequestOriginParser的实现类来解析来源。实现这个接口很简单:

@Component public class HeaderRequestOriginParser implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { // 优先取自定义Header,很多内部系统约定用X-Origin标识调用来源 String origin = request.getHeader("X-Origin"); if (origin != null && origin.trim().length() > 0) { return origin; } // 兜底返回一个固定值,避免白名单模式下误伤没有来源标识的请求 return "default"; } }

这个类必须是Spring管理的Bean,否则SentinelWebInterceptor拿不到它,授权规则会静默失效。还有一个容易踩的坑:如果在项目里自定义了WebMvcConfigurer的addInterceptors方法,要注意别覆盖掉Sentinel的拦截器注册,否则整个Sentinel链路都不会生效。

另外,来源解析和资源名解析是两回事。资源名解析走的是UrlCleaner,用来把/order/create/123清洗成/order/create/*;来源解析走的是RequestOriginParser,只负责回答“这个请求是谁发来的”。这两个逻辑不要混在一起。

2.3 控制台配置步骤与白名单实战

假设现在有一个下单接口/order/create,我们希望只允许来源为gateway的请求访问,其他来源一律拒绝。操作很简单:

在控制台左侧菜单进入“授权规则”,点“新增授权规则”,资源名填/order/create,授权类型选“白名单”,来源应用填gateway,保存后这条规则就生效了。

规则底层逻辑等价于:

AuthorityRule rule = new AuthorityRule(); rule.setResource("/order/create"); rule.setLimitApp("gateway"); rule.setStrategy(RuleConstant.AUTHORITY_WHITE); AuthorityRuleManager.loadRules(Collections.singletonList(rule));

保存后可以启动一个请求,不带X-Origin头去访问这个接口,会看到类似SentinelBlockException: AuthorityException的异常;带上X-Origin: gateway就能正常通过。

实践中我建议同时配置一套黑名单规则来封杀恶意调用者,比如来源标识为spider的请求:

AuthorityRule blackRule = new AuthorityRule(); blackRule.setResource("/order/create"); blackRule.setLimitApp("spider"); blackRule.setStrategy(RuleConstant.AUTHORITY_BLACK); AuthorityRuleManager.loadRules(Collections.singletonList(blackRule));

这里有一个细节:授权规则的资源名必须和Sentinel埋点的资源名完全一致。Spring MVC适配器默认用请求URI作为资源名,所以/order/create这个写法没问题;如果项目里使用了自定义埋点SphU.entry("createOrder"),那授权规则的资源名就要填createOrder,而不是URL。

3. 系统规则拆解:五个维度的阈值怎么定、怎么生效

系统规则在控制台里看上去更简单:一行配置,五个可选项。但它的内部机制比授权规则复杂不少,因为涉及机器级指标的采集和入口流量的统计。

3.1 五个维度背后的含义

系统规则的五个维度分别是:

维度参数名含义典型设置参考
LoadhighestSystemLoad系统当前Load(1分钟平均),仅Linux等类Unix系统有效核数的1.5倍到2倍,比如4核机器设6.0
CPUhighestCpuUsageCPU使用率,0.0到1.0之间0.6到0.8,留出缓冲
RTavgRt所有入口流量的平均响应时间,单位毫秒业务P99耗时的1.5倍左右
线程数maxThreads入口流量的并发线程数参考压测得出的最大并发数
入口QPSqps所有入口流量的总QPS峰值QPS的70%左右

注意这里的RT和线程数都是“所有入口流量”的聚合指标,不是单个接口的指标。设置RT=300,意味着所有Web请求的平均RT超过300ms就会触发全局拦截,这在某些长接口业务里会显得很激进。比如有一个接口本身要跑5秒,但它的调用量很低,平均RT只有200ms,看起来不会触发;如果有一天这个慢接口调用量突然上来,平均RT被拉高到300ms以上,那所有接口都会被拦,这其实是合理的——因为整机已经被慢调用拖住了。

Load维度的判断逻辑是:只有当系统Load超过阈值且当前并发线程数超过系统容量时才会触发,单纯Load高但线程数不高,不触发。这个设计是防止机器负载瞬间尖峰导致误杀。在Windows上测试时,Load指标拿不到数据,所以源码里直接跳过这个维度的判断,也就是说你在Windows上调Load规则,它永远不会生效。

3.2 入口流量的统计机制

系统规则里反复提到“入口流量”,这个词很多人没细想。Sentinel把流量分为IN和OUT两种类型,Web请求默认是IN,微服务内部调用通常也是IN,而OUT代表出口调用。系统规则只统计入口流量,底层通过SystemMetricStatistics做滑动窗口聚合,默认统计窗口是1秒,每5秒检查一次阈值。

在默认的Spring MVC适配器场景下,所有被SentinelWebInterceptor拦截的请求都会自动标记为IN并累加到入口统计里。所以如果只配置了入口QPS=500,那应用上所有Web请求的总QPS超过500就会全部被拦下来。这个行为对单体应用来说很直观,但在微服务架构下要格外小心:你开了多个实例,每个实例的入口QPS是独立的,控制台上配置的500是单机值,不是集群值。

还有一个容易走弯路的地方:系统规则在控制台里只有“系统规则”一个入口,配置的规则是挂在默认入口资源Constants.ENTRY_RESOURCE上的。这个默认入口资源可以理解为“应用的总入口”,所有自动埋点的请求都会归到这里。但它也可以被替换,Sentinel提供了一个扩展点SystemRulesManager.registerSystemRulesProvider,大部分场景用不到,只需要知道有这么一个机制就好。

3.3 扩展入口规则与压测验证

我用一个实际案例来演示系统规则的完整落地过程。假设有一个4核8G的服务器,预期峰值入口QPS在800左右,线上要求P99 RT不高于300ms,CPU不能打满。先通过一次简单的压测拿到数据:压测工具设置200并发,跑5分钟,得到平均RT=180ms、入口QPS峰值=1050、CPU最高81%。这些数据就是设置阈值的依据。

控制台新增系统规则,配置一组合理阈值:

SystemRule rule = new SystemRule(); rule.setHighestSystemLoad(6.0); rule.setHighestCpuUsage(0.8); rule.setAvgRt(300); rule.setMaxThreads(200); rule.setQps(800); SystemRuleManager.loadRules(Collections.singletonList(rule));

保存后再次压测,当入口QPS超过800时,新请求开始被拒绝,控制台能看到SystemBlockException的拦截记录,CPU稳定在80%以下,服务不再响应超时。

这里要提醒一下:系统规则的阈值不是越快越好。如果设置得过低,比如CPU=0.5,业务上稍微有点波动就触发全局拦截,反而会影响正常流量。设置的原则是“在业务可接受的延迟范围内尽量多抗流量”,具体数值要基于压测数据迭代调整。

关于代码方式配置规则,生产环境有争议。用控制台配置的好处是改动即时生效、方便观察;用代码配置的好处是随应用启动一起加载,不依赖控制台连接。我的建议是测试环境用控制台快速调参,确定阈值后固化到配置文件里,用Sentinel的DataSource机制加载,避免生产环境控制台不稳定导致规则丢失。

4. 避坑指南:这两类规则最容易踩的坑

这两类规则看着简单,实际用起来问题不少。我整理了在多个项目里真实遇到的五类问题,基本可以覆盖大部分排查场景。

4.1 授权规则配了不生效

这是排在第一的高频问题。控制台里规则明明保存了,但请求进不来也出不去,心里没底。查这个问题的顺序一般是:

第一,确认有没有实现RequestOriginParser,并且类上标了@Component。没有实现请求来源解析,控制台填的来源应用名称就永远匹配不上,白名单模式下所有请求都会被拒绝,黑名单模式下规则形同虚设。

第二,确认请求来源解析返回值和控制台填写的值完全一致。解析逻辑里做了大小写转换或去空格,控制台填的是Gateway,解析返回的是gateway,匹配不上。建议解析逻辑只做trim,不做其他转换,避免自己给自己挖坑。

第三,确认Sentinel链路真的生效了。检查过滤器或拦截器有没有被自定义配置覆盖,最直接的办法是看请求日志里有没有Sentinel相关输出,或者故意配一个流控规则验证一下基础链路是否正常。

4.2 系统规则在Windows上不生效

很多人开发机是Windows,配了Load规则后发现压测怎么都触发不了,不是规则写错了,而是Windows没有Load这个概念,代码里检测到不支持就直接跳过了这个维度的判断。如果要在开发阶段验证系统规则,用CPU、RT、线程数、QPS这四个维度,Load维度放到Linux测试环境再验。

另外还要注意CPU使用率的获取在不同JDK版本下表现有差异,遇到CPU阈值始终不触发的情况,先看机器监控里CPU是不是真的超过了阈值,有时候虚拟机抢占导致监控工具看到的CPU很高,但Java层面拿到的数据有延迟。

4.3 网关场景的来源解析是另一套API

Spring Cloud Gateway场景下,Sentinel的接入方式不是SentinelWebInterceptor,而是SentinelGatewayFilter,请求来源解析的注册方式也完全不同。需要通过GatewayCallbackManager.setRequestOriginParser来注册:

@Configuration public class GatewayConfiguration { @PostConstruct public void init() { GatewayCallbackManager.setRequestOriginParser(exchange -> { String origin = exchange.getRequest().getHeaders().getFirst("X-Origin"); return origin != null ? origin : "default"; }); } }

很多人在网关场景下依然按Web MVC的方式写@Component实现RequestOriginParser,结果授权规则完全不生效,就是因为这套适配器根本不会从Spring容器里去找那个接口。网关场景的资源名默认是路由ID,不是URL路径,配置授权规则时要用路由ID,否则也匹配不上。

4.4 阈值设置不能只靠感觉

系统规则的五个维度不是所有都要配,更建议只配置当前需要的那一两个维度,避免相互干扰。比如只配入口QPS和CPU两个维度,其他维度保持未配置状态,Sentinel会跳过未配置的判断。如果五个维度全部配满,可能出现某个维度先触发导致其他规则来不及验证的情况,给排查增加难度。

阈值方面常见的错误有两种:一种是把入口QPS设成单接口压测的吞吐量,但入口QPS是所有接口的总和,二者差好几倍;另一种是把RT设成单个接口的P99,但系统规则统计的是全局平均RT,和单接口的延迟不是一个概念。这两种错都会导致线上误触发,压测时需要特别区分。

4.5 授权规则和系统规则的配合思路

最后聊聊这两类规则的配合。授权规则、系统规则、流控规则的触发顺序是:授权规则最先判断,系统规则次之,流控规则最后。也就是说,一个被授权规则拒绝的请求,不会计入系统规则的入口统计,也不会进入流控判断;一个被系统规则拦截的请求,不会再继续往下走流控逻辑。

基于这个顺序,我通常会这样设计:最外层用授权规则挡住明确不允许的调用方,这是第一道闸;第二道用系统规则保护整机资源,这是保命闸;再往内才是流控、降级、热点这些精细化规则,管控单个接口的流量形态。

我在实际项目里第一次用系统规则时,把入口QPS设置成了2000,结果白天流量稍微一冲就直接全局拦截,业务方半夜打电话来找我。后来把阈值改到压测峰值的50%再逐步上调,用了一周才找到安全值。这个经验是:任何规则上线前都先在压测环境压一轮,拿到真实数据再填阈值,宁可先收紧再放宽,也不要一开始就给一个想当然的大数字。

生产环境里还有个小技巧,系统规则触发时会拒绝入口流量,但返回给调用方的异常是BlockException,如果你统一封装了全局异常处理器,记得把SystemBlockException也处理掉,否则调用方拿到的可能是500而不是预期中的提示信息。授权规则抛出的AuthorityException同理,也应该在异常处理里做统一兜底,给前端一个明确的提示,而不是裸抛异常。

这一篇把授权规则和系统规则讲完,Sentinel的规则体系就补得差不多了。下一篇准备聊规则持久化和动态数据源,这应该是生产环境里最后一块拼图了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 12:50:15

Wilcoxon秩和检验:原理、应用与实现指南

1. 什么是Wilcoxon秩和检验?Wilcoxon秩和检验(Wilcoxon rank-sum test)是一种非参数统计方法,用于比较两个独立样本的中位数是否存在显著差异。它由Frank Wilcoxon在1945年提出,是Mann-Whitney U检验的等价形式&#x…

作者头像 李华
网站建设 2026/10/15 12:49:28

1.3万张截图泄露背后:AI编程智能体的权限失控与安全防线

1.3万张截图从一台开发机里悄悄流了出去,没有黑客、没有漏洞利用、没有社工钓鱼——泄露的源头,是那个每天帮你写代码、跑测试、提Pull Request的AI编程智能体。这起事件最扎眼的地方恰恰是“无人攻击”:智能体凭自己的判断力,把涉…

作者头像 李华
网站建设 2026/10/15 12:49:27

AI编程智能体泄露1.3万张截图的背后:默认配置与数据链路安全盲区

三个多月前,团队内部还在聊“AI编程智能体到底能不能放开权限让它自己跑”。当时我的结论是:可以跑,但必须圈在指定目录里。结果这两天曝出的消息,比我预想中更说明问题——某AI编程智能体在无人实施任何黑客攻击的情况下&#xf…

作者头像 李华
网站建设 2026/10/15 12:49:27

mLSHADE-RL算法:进化计算在复杂优化中的突破

1. 算法背景与核心价值mLSHADE-RL是2024年IEEE计算智能大会(CEC)竞赛的优胜算法,属于进化计算领域的最新研究成果。这个算法本质上是对经典LSHADE(线性缩放的混合自适应差分进化)框架的增强扩展,通过多操作…

作者头像 李华
网站建设 2026/10/15 12:49:27

mLSHADE-RL算法:进化计算中的高效优化技术

1. 算法背景与核心价值 mLSHADE-RL是进化计算领域针对CEC(Congress on Evolutionary Computation)基准测试问题优化的新一代算法。作为LSHADE(Success-History based Adaptive Differential Evolution with Linear Population Size Reduction…

作者头像 李华
网站建设 2026/10/15 12:49:17

EDI技术解析:企业数据交换的核心原理与实践

1. 项目概述:EDI技术的前世今生第一次听说EDI这个词是在2015年参加某跨国零售商的供应商大会时。当时他们的采购总监拿着厚厚一叠纸质订单说:"我们明年要全面推行EDI,还在用传真和邮件的供应商将被移出合格名单。"这句话让我意识到…

作者头像 李华