I have created an object of HttpClient class(from Reactor Netty jar), and used this httpClient to create an object of Webclient class(from Spring Webflux jar) as below:
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(EpollChannelOption.TCP_KEEPIDLE, 300)
.option(EpollChannelOption.TCP_KEEPINTVL, 60)
.option(EpollChannelOption.TCP_KEEPCNT, 8)
.doOnConnected(//custom stuff);
Webclient webclient = WebClient.builder()
.baseUrl()
.defaultHeader()
.codecs(
configurer -> {
configurer.defaultCodecs().jaxb2Encoder(new Jaxb2XmlEncoder());
configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder());
})
.clientConnector(new ReactorClientHttpConnector(httpClient)
.build();
Then I'm using this WebClient to make a POST API request.
Although I'm getting the API response correctly, I was getting below warnings in the logs:
Unknown channel option 'io.netty.channel.epoll.EpollChannelOption#TCP_KEEPIDLE' for channel '[id: 0x76c8c652]'
Unknown channel option 'io.netty.channel.epoll.EpollChannelOption#TCP_KEEPCNT' for channel '[id: 0x76c8c652]'
Unknown channel option 'io.netty.channel.epoll.EpollChannelOption#TCP_KEEPINTVL' for channel '[id: 0x76c8c652]'
The properties(TCP_KEEPIDLE, TCP_KEEPCNT, TCP_KEEPINTVL etc) in the above warning are set in the HttpClient` object creation code as shown in the above code.
I debugged this and found out that the warnings are getting generated in
TransportConnector.setChannelOptions(Channel channel, Map<ChannelOption<?>, ?> options, boolean isDomainSocket) method which is there in the reactor netty jar.
And the reason the warnings are coming is because the Channel object in the above mentioned method is an object of NioSocketChannel. After reading the reactor netty documentation I realized that if the Channel is NioSocketChannel then we need to change the configs from EpollChannelOption to NioChannelOption as below:
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(NioChannelOption.of(ExtendedSocketOptions.TCP_KEEPIDLE), 300)
.option(NioChannelOption.of(ExtendedSocketOptions.TCP_KEEPINTERVAL), 60)
.option(NioChannelOption.of(ExtendedSocketOptions.TCP_KEEPCOUNT), 8)
.doOnConnected(//custom stuff);
And it worked fine after the above change, as no warnings are coming now.
However here is my problem needing clarification:
This exact project has been working fine in one of our production environment. Also from the logs I could see the underlying channel in production was EpollSocketChannelConfig in contrast to my local where the channel was NioSocketChannel.
In what circumstances can the underlying Channel be different for the same codebase?
I haven't used the runOn method either anywhere in the codebase.
Some info about my setup: My local is a Mac M1 is where the Channel is NIO whereas the Production is running Linux where the Channel is NIO.
The java version in both the machines is Java 11.
Please help