问题
I would like to customize Netty in my Spring Boot Webflux project. In my POM I added Spring Boot Webflux and Spring Boot Actuator dependencies. Next I overwrote the customize() method of WebServerFactoryCustomizer as described in the Spring documentation.
@Component
public class NettyConfiguration implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {
@Override
public void customize(NettyReactiveWebServerFactory factory) {
factory.addServerCustomizers(new NettyCustomizer());
}
}
Then I implemented the Netty bootstrapping in my NettyCustomizer:
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)
);
}
}
Now if I start the Spring Boot application I get a "Unable to start Netty" error.
org.springframework.boot.web.server.WebServerException: Unable to start Netty
Caused by: java.lang.IllegalStateException: group set already
So it seems there is no way to override Netty bootstrapping if using Webflux. Changing the addServerCustomizers() method to setServerCustomizers() in the customize() method leads to the same exceptions unfortunately. Does anybody know how to customize Netty together with Spring Boot?
回答1:
As mentioned in the Spring Boot reference documentation, you can customize the resources the Netty server and client are running on by defining your own ReactorResourceFactory
, like so:
@Bean
public ReactorResourceFactory resourceFactory() {
ReactorResourceFactory reactorResourceFactory = new ReactorResourceFactory();
reactorResourceFactory.setLoopResourcesSupplier(() -> LoopResources.create("custom-prefix"));
return reactorResourceFactory;
}
Note that we're using here the LoopResources abstraction provided by Reactor Netty for that. This allows to share resources between client and server for better efficiency.
Feel free to open enhancement requests in Reactor Netty or Spring Boot if you can't achieve what you want.
回答2:
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")))));
}
来源:https://stackoverflow.com/questions/53948033/how-to-customize-netty-with-spring-boot-2-1-webflux