You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Webflux中NettyWebServerFactoryCustomizer未触发及Metrics配置问题

关于NettyWebServerFactoryCustomizer的两个问题解答

问题1:customize方法未触发的原因及解决

可能的原因和对应解决方式:

  • 配置类未被Spring扫描:确保@Configuration注解的类所在包在Spring Boot的组件扫描范围内(默认是启动类所在包及其子包),如果不在,需要手动通过@ComponentScan指定扫描路径。
  • 项目不是Reactive栈:如果你的项目依赖的是spring-boot-starter-web(Servlet栈),Netty不会作为Web服务器被使用,NettyReactiveWebServerFactory也不会被实例化,定制器自然不会触发。需要切换为Reactive栈,将依赖改为spring-boot-starter-webflux。
  • 依赖缺失:确保项目中引入了spring-boot-starter-webflux依赖,否则Netty相关的工厂类不会被加载。

另外,关于开启Netty metrics,Spring Boot有自动配置支持:只要引入spring-boot-starter-actuator和对应的Micrometer注册中心依赖(如micrometer-registry-prometheus),并在配置文件中开启相关配置(比如management.endpoints.web.exposure.include=metrics),Spring Boot会自动为Netty配置metrics,无需手动编写定制器。

问题2:metrics方法的uriTagValue参数示例及避免基数爆炸

问题说明

直接使用s->s会将原始请求URI(如/api/user/123)作为标签值,不同的路径参数会生成大量不同的标签,导致基数爆炸,影响监控系统性能。

获取模板化URL的实现示例

要获取类似/api/user/{id}的模板化URL,需要结合Spring Web的请求上下文和Netty的Channel属性传递信息:

  1. 编写WebFilter传递模板化路径
    创建WebFilter,在请求处理时将Spring匹配到的模板化路径存入Netty Channel属性:
@Component
public class TemplateUriWebFilter implements WebFilter {

    private static final AttributeKey<String> TEMPLATE_URI_ATTR = AttributeKey.valueOf("TEMPLATE_URI");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // 获取Spring匹配到的模板化路径
        String templateUri = exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        if (templateUri != null) {
            // 将模板路径存入Netty Channel的属性中
            Channel channel = exchange.getRequest().getNativeRequest(Channel.class);
            channel.attr(TEMPLATE_URI_ATTR).set(templateUri);
        }
        return chain.filter(exchange);
    }
}
  1. 在定制器中读取模板化路径
    修改NettyWebServerFactoryCustomizer的metrics配置,从Channel属性读取模板化路径,不存在则 fallback 到原始URI:
@Configuration
public class NettyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    private static final AttributeKey<String> TEMPLATE_URI_ATTR = AttributeKey.valueOf("TEMPLATE_URI");

    @Override
    public void customize(NettyReactiveWebServerFactory factory) {
        factory.addServerCustomizers(httpServer -> {
            return httpServer
                .wiretap(true)
                .metrics(true, request -> {
                    Channel channel = request.channel();
                    String templateUri = channel.attr(TEMPLATE_URI_ATTR).get();
                    // 优先使用模板化路径,否则用原始URI
                    return templateUri != null ? templateUri : request.uri();
                })
                .doOnConnection(conn -> {
                    conn.addHandlerFirst(new ReadTimeoutHandler(50, TimeUnit.MILLISECONDS));
                });
        });
    }
}

这样就能确保metrics中的uri标签使用模板化路径,避免基数爆炸问题。


内容的提问来源于stack exchange,提问作者gfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:09:48