如何使用Spring Boot 2.1 Webflux自定义Netty?

时间:2018-12-27 16:27:40

标签: java spring-boot spring-webflux reactor-netty

我想在Spring Boot Webflux项目中自定义Netty。在我的POM中,我添加了Spring Boot Webflux和Spring Boot Actuator依赖项。接下来,我按照Spring documentation中所述重写了WebServerFactoryCustomizer的customize()方法。

@Component
public class NettyConfiguration implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    @Override
    public void customize(NettyReactiveWebServerFactory factory) {
        factory.addServerCustomizers(new NettyCustomizer());
    }
}

然后我在NettyCustomizer中实现了Netty引导:

public class NettyCustomizer implements NettyServerCustomizer {

    private final EventLoopGroup bossGroup = new NioEventLoopGroup(22);
    private final EventLoopGroup workerGroup = new NioEventLoopGroup();

    @Override
    public HttpServer apply(HttpServer httpServer) {
        return httpServer.tcpConfiguration(tcpServer ->
                tcpServer.bootstrap(serverBootstrap ->
                        serverBootstrap
                                .group(bossGroup, workerGroup)
                                .channel(NioServerSocketChannel.class)
                                .handler(new LoggingHandler(LogLevel.DEBUG))
                                .childHandler(new ChannelInitializer<SocketChannel>() {
                                    @Override
                                    public void initChannel(final SocketChannel socketChannel) {
                                        socketChannel.pipeline().addLast(new BufferingInboundHandler());
                                    }
                                })
                                .option(ChannelOption.SO_BACKLOG, 128)
                                .childOption(ChannelOption.SO_KEEPALIVE, true))
                        .port(8899)
        );
    }
}

现在,如果我启动Spring Boot应用程序,则会收到“无法启动Netty”错误。

org.springframework.boot.web.server.WebServerException: Unable to start Netty
Caused by: java.lang.IllegalStateException: group set already

因此,如果使用Webflux,似乎没有办法替代Netty自举。不幸的是,在custom()方法中将addServerCustomizers()方法更改为setServerCustomizers()会导致相同的异常。有人知道如何与Spring Boot一起定制Netty吗?

2 个答案:

答案 0 :(得分:0)

the Spring Boot reference documentation中所述,您可以通过定义自己的ReactorResourceFactory来自定义Netty服务器和客户端正在运行的资源,如下所示:

@Bean
public ReactorResourceFactory resourceFactory() {
    ReactorResourceFactory reactorResourceFactory = new ReactorResourceFactory();
    reactorResourceFactory.setLoopResourcesSupplier(() -> LoopResources.create("custom-prefix"));
    return reactorResourceFactory;
} 

请注意,我们在这里使用LoopResources abstraction provided by Reactor Netty。这样可以在客户端和服务器之间共享资源,从而提高效率。

如果您无法实现所需的功能,请随时在Reactor Netty或Spring Boot中打开增强请求。

答案 1 :(得分:0)

If you want to replace it with your own server, you need to delete some of netty's dependencies from pom.xml. However if you want to configure pipeline or stuff like that i guess you can manipulate web server configuration in spring boot as follows;

@Override
public void customize(WebServerFactory factory) {
    NettyReactiveWebServerFactory nettyReactiveWebServerFactory = (NettyReactiveWebServerFactory) factory;
    nettyReactiveWebServerFactory.addServerCustomizers(builder -> builder
            .tcpConfiguration(tcpServer -> tcpServer.bootstrap(i -> i.handler(new ObjectEchoServerHandler("1")))));
}