资讯动态

Sentinel Web Servlet Filter 接入指南:为 Java Web 请求注入流控防护

发布时间:2026/9/20 5:13:11 来源:尧图企业网站定制
Sentinel Web Servlet Filter 接入指南为 Java Web 请求注入流控防护【免费下载链接】SentinelA powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)项目地址: https://gitcode.com/gh_mirrors/sentine/Sentinel导读本文围绕 Sentinel 的sentinel-web-servlet适配器系统讲解如何通过标准的 Servlet Filter 机制为 Java Web 应用含传统 web.xml 部署与 Spring Boot 场景接入流控能力。读完本文你将掌握依赖引入、Filter 注册、资源命名规则、URL 归一化UrlCleaner、请求来源解析RequestOriginParser以及自定义限流阻断页与阻断 HTTP 状态码的完整实战方案并能结合源码理解其底层工作原理。Sentinel 是面向云原生微服务的高可用流控防护组件而 Servlet Filter 是它接入 Web 应用最轻量、侵入性最小的方式之一。本适配器基于javax.servlet标准接口实现无需改动业务代码即可将每个 HTTP 请求纳入 Sentinel 的流量统计与规则校验链路。一、依赖引入与工程结构1.1 Maven 依赖在pom.xml中添加如下依赖以 Maven 为例dependency groupIdcom.alibaba.csp/groupId artifactIdsentinel-web-servlet/artifactId versionx.y.z/version /dependency其中x.y.z请替换为实际使用的版本号可参考仓库父 POM 中revision属性对应的版本。从该模块的 pom.xml 可以看到它本身依赖sentinel-core流控核心与javax.servlet-api版本为 3.1.0provided作用域因此运行环境需自行提供 Servlet 容器如 Tomcat、Jetty。1.2 模块源码结构该适配器位于仓库sentinel-adapter/sentinel-web-servlet目录下核心源码组织如下CommonFilter对每个 URL 请求进行流控的过滤器按资源路径统计CommonTotalFilter对所有请求进行统一总量统计的过滤器资源名固定为total-url-requestcallback/包提供UrlCleaner、UrlBlockHandler、RequestOriginParser三个扩展接口及默认实现并通过WebCallbackManager统一注册config/WebServletConfig集中管理阻断页 URL 与阻断 HTTP 状态码等配置项util/FilterUtilURL 资源路径提取、归一化与阻断响应输出等工具逻辑。二、注册 Filter从 web.xml 到 Spring Bean2.1 传统 web.xml 方式对于传统 Servlet 应用直接在web.xml中配置过滤器即可filter filter-nameSentinelCommonFilter/filter-name filter-classcom.alibaba.csp.sentinel.adapter.servlet.CommonFilter/filter-class /filter filter-mapping filter-nameSentinelCommonFilter/filter-name url-pattern/*/url-pattern /filter-mappingurl-pattern设为/*表示拦截所有请求。Sentinel 会在doFilter中基于请求路径创建资源并执行规则校验若被流控规则拦截则转入阻断处理逻辑不再放行到后续 Filter 链与 Servlet。2.2 Spring / Spring Boot 方式对于 Spring Web 应用可通过 Spring Bean 注册过滤器并支持初始化参数Configuration public class FilterConfig { Bean public FilterRegistrationBean sentinelFilterRegistration() { FilterRegistrationBeanFilter registration new FilterRegistrationBean(); registration.setFilter(new CommonFilter()); // Set the matching URL pattern for the filter. registration.addUrlPatterns(/*); registration.setName(sentinelCommonFilter); registration.setOrder(1); // Set whether to support the specified HTTP method prefix for the filter. registration.addInitParameter(CommonFilter.HTTP_METHOD_SPECIFY, false); return registration; } }关键参数说明addUrlPatterns(/*)指定拦截的 URL 匹配模式setOrder(1)控制过滤器在链路中的执行顺序HTTP_METHOD_SPECIFY是否在资源名中附加 HTTP 方法前缀详见下文“初始化参数”小节。三、过滤器核心原理资源如何被创建与统计3.1 请求处理主流程CommonFilter实现了标准的javax.servlet.Filter其 doFilter 方法 的核心流程如下调用FilterUtil.filterTarget(sRequest)提取并规范化请求的资源路径若注册了UrlCleaner则用其对路径进行清洗与统一如把/foo/1、/foo/2归一化为/foo/:id若清洗后的目标非空则解析请求来源origin并通过ContextUtil.enter(contextName, origin)进入 Sentinel 上下文以目标路径可选附加 HTTP 方法前缀作为资源名调用SphU.entry(...)创建资源入口资源类型为ResourceTypeConstants.COMMON_WEB、流量方向为EntryType.IN入站流量放行chain.doFilter(request, response)继续执行后续业务逻辑捕获BlockException时调用WebCallbackManager.getUrlBlockHandler().blocked(...)返回阻断响应处理过程出现IOException、ServletException或RuntimeException时通过Tracer.traceEntry记录异常供熔断降级等规则感知finally中依次调用urlEntry.exit()与ContextUtil.exit()完成资源与上下文的退出。3.2 资源路径的提取与规范化FilterUtil.filterTarget见 FilterUtil.java会合并servletPath与pathInfo得到完整路径并统一以/开头同时会剔除路径中的.、..等冗余片段避免同一资源因路径写法差异产生多个统计维度。3.3 两个内置初始化参数CommonFilter在init阶段读取两个初始化参数见 CommonFilter.javaHTTP_METHOD_SPECIFY默认false开启后资源名会带上 HTTP 方法前缀形如POST:/api/order、GET:/api/order从而区分不同方法对同一路径的流量。实现上通过sRequest.getMethod().toUpperCase() : target拼装资源名WEB_CONTEXT_UNIFY默认true自 1.7.0 起开启时使用统一的默认上下文名sentinel_web_servlet_context否则以 URL 路径作为上下文名。官方注释特别提醒上下文EntranceNode数量会影响内存占用建议保持统一避免高基数 URL 造成上下文数量膨胀。3.4 总流量过滤器 CommonTotalFilter除CommonFilter外模块还提供了CommonTotalFilter它对所有请求统一建立名为total-url-request的全局资源见 CommonTotalFilter.java用于对整站总流量做整体限流适合“全局限流阈值”类场景可与按 URL 细分的CommonFilter配合使用。四、阻断行为默认阻断页、自定义页面与状态码4.1 默认阻断响应当请求被流控规则拦截时过滤器会返回一个默认阻断页面。默认的 HTTP 状态码为429Too Many Requests响应内容为Blocked by Sentinel (flow limiting)常量定义见 FilterUtil.java。4.2 自定义阻断状态码自 1.7.0 起默认状态码可通过配置项csp.sentinel.web.servlet.block.status修改例如通过 JVM 参数-Dcsp.sentinel.web.servlet.block.status429也可以调用WebServletConfig.setBlockPageHttpStatus(int)编程式设置。从 WebServletConfig.java 的源码可见其解析规则配置为空或非法如小于等于 0时自动回退并记录 WARN 日志最终仍使用默认值 429。4.3 自定义阻断页面若设置了阻断页通过WebServletConfig.setBlockPage(blockPage)方法或配置项csp.sentinel.web.servlet.block.page过滤器会将请求重定向到该 URL并在重定向地址后追加?http_referer原请求完整URL作为来源参数见 FilterUtil.blockRequest。也就是说用户被阻断后浏览器会跳转到你指定的错误页面页面可通过http_referer参数获知用户原本访问的地址。示例编程式设置阻断页WebServletConfig.setBlockPage(/block.html);4.4 完全自定义阻断处理器若默认的“返回阻断页或重定向”行为无法满足需求例如需要返回 JSON 数据、拼接自定义响应头可以实现UrlBlockHandler接口并注册到WebCallbackManagerpublic class MyUrlBlockHandler implements UrlBlockHandler { Override public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException { // 自定义阻断逻辑例如返回 JSON response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:429,\msg\:\blocked by sentinel\}); response.getWriter().flush(); } } WebCallbackManager.setUrlBlockHandler(new MyUrlBlockHandler());UrlBlockHandler接口只要求实现blocked(HttpServletRequest, HttpServletResponse, BlockException)一个方法见 UrlBlockHandler.javaBlockException参数可用于区分是流控FlowException还是熔断降级DegradeException等触发的阻断。默认实现DefaultUrlBlockHandler内部只是委托给FilterUtil.blockRequest。WebCallbackManager是全局静态注册中心其中urlBlockHandler不允许注册为null见 WebCallbackManager.java。五、URL 归一化REST 接口的必备配置5.1 为什么需要 UrlCleanerServlet Filter 默认以请求路径作为 Sentinel 资源名。对于 REST 风格接口路径中的路径变量会不断变化例如/foo/1和/foo/2会被视为两个不同资源若不加以清洗当路径变量取值种类很多时资源数量与上下文数量会迅速膨胀甚至超过阈值既浪费内存也让规则难以收敛。因此官方文档明确要求对于 REST API必须使用UrlCleaner将 URL 资源统一例如把/foo/1、/foo/2归一化为/foo/:id。5.2 实现与注册 UrlCleanerUrlCleaner接口只有一个方法String clean(String originUrl)见 UrlCleaner.java其默认实现DefaultUrlCleaner原样返回输入不做事。典型实现如下public class MyUrlCleaner implements UrlCleaner { Override public String clean(String originUrl) { // 将形如 /foo/123 的路径统一为 /foo/{id} return originUrl.replaceAll(/foo/\\d, /foo/{id}); } } WebCallbackManager.setUrlCleaner(new MyUrlCleaner());5.3 排除特定 URL自 1.6.3 起如果你希望某些 URL 不被记录为 Sentinel 资源例如静态资源、健康检查端点同样可以借助UrlCleaner在clean方法中把不需要纳入统计的 URL 统一返回为空字符串或null过滤器会直接跳过该请求的埋点。这一点在 CommonFilter 源码 中有明确注释与对应逻辑StringUtil.isEmpty(target)时不再创建 Entry。六、请求来源解析基于 IP / Header 的精细化限流RequestOriginParser接口用于从 HTTP 请求中提取调用来源origin例如客户端 IP、请求头中的 appName、用户标识等接口定义见 RequestOriginParser.java。提取出的 origin 会作为 Sentinel 上下文的 origin 参数传入可用于“按来源限流”等场景例如限制某个 appName 的调用量。实现并注册public class MyRequestOriginParser implements RequestOriginParser { Override public String parseOrigin(HttpServletRequest request) { String origin request.getHeader(S-user); return origin ! null ? origin : request.getRemoteAddr(); } } WebCallbackManager.setRequestOriginParser(new MyRequestOriginParser());注意WebCallbackManager中的requestOriginParser默认是null未注册时CommonFilter.parseOrigin 会返回空字符串作为 origin不影响正常埋点。若解析结果为空字符串也会回退为空 origin。七、测试验证与进阶参考仓库中为该适配器提供了完整的集成测试与 Spring Boot 测试骨架可以作为你接入时的参考实现CommonFilterTest.java覆盖CommonFilter的资源创建、URL 清洗、阻断返回等核心行为TestApplication.java 与 TestController.java以 Spring Boot 方式提供可运行的验证应用可直接对照学习过滤器的注册与请求链路。若你的应用使用 Servlet 3.0 注解方式WebFilter或 Spring Boot 的OncePerRequestFilter原理相同只要保证请求经过CommonFilter或CommonTotalFilter即可完成埋点规则下发与动态配置可通过 Sentinel 的数据源扩展如 Nacos、Zookeeper、Apollo见sentinel-extension目录实现。结语sentinel-web-servlet以标准的 Servlet Filter 为切入点让传统 Java Web 应用无需任何业务改动即可获得流量统计、流控、熔断等防护能力。接入时把握四个关键点即可正确注册 Filter、用UrlCleaner归一化 REST 路径、按需自定义阻断行为UrlBlockHandler与阻断页/状态码配置、用RequestOriginParser支撑按来源限流。结合 CommonFilter.java 与 WebServletConfig.java 的源码研读即可透彻掌握其内部机制并根据业务场景灵活扩展。【免费下载链接】SentinelA powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)项目地址: https://gitcode.com/gh_mirrors/sentine/Sentinel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价