Is it possible to configure WebClient to use a custom thread pool other than the reactor-http-nio thread pool (When using Netty)? If it is possible , can we somehow restrict that custom thread pool to run only on a particular processor core?
Configuring Spring WebFlux WebClient to use a custom thread pool
Asked Answered
Yes. You can.
Create some where your own Thread Pool and EventLoopGroup (or create NioEventLoopGroup bean). For example:
{ Intger THREADS = 10; BasicThreadFactory THREADFACTORY = new BasicThreadFactory.Builder() .namingPattern("HttpThread-%d") .daemon(true) .priority(Thread.MAX_PRIORITY) .build(); EXECUTOR = new ThreadPoolExecutor( THREADS, THREADS, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), THREADFACTORY, new ThreadPoolExecutor.AbortPolicy()); NioEventLoopGroup RESOURCE= new NioEventLoopGroup(THREADS,EXECUTOR); }
Register your own ReactorResourceFactory. And provide your own EventLoopGrooup based on custom thread Executor
@Bean public ReactorResourceFactory reactorResourceFactory(NioEventLoopGroup RESOURCE) { ReactorResourceFactory f= new ReactorResourceFactory(); f.setLoopResources(new LoopResources() { @Override public EventLoopGroup onServer(boolean b) { return RESOURCE; } }); f.setUseGlobalResources(false); return f; }
Then register ReactorClientHttpConnector. In example below it is used custom SSL Context
@Bean public ReactorClientHttpConnector reactorClientHttpConnector(ReactorResourceFactory r) throws SSLException { SslContext sslContext = SslContextBuilder .forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build(); return new ReactorClientHttpConnector(r, m -> m.secure(t -> t.sslContext(sslContext))); }
Finally build WebClient
@Bean public WebClient webClient(ReactorClientHttpConnector r) { return WebClient.builder().clientConnector(r).build(); }
If you want to use same for WebServer. Do same configuration for ReactiveWebServerFactory.
@Bean
public ReactiveWebServerFactory reactiveWebServerFactory(NioEventLoopGroup RESOURCE) {
NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory();
factory.addServerCustomizers(hs->hs.tcpConfiguration(s->s.runOn(RESOURCE)));
return factory;
}
Imports:
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.client.reactive.ReactorResourceFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.resources.LoopResources;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import java.util.concurrent.*;
Little late ;) but thanks anyway! Tried it in the similar fashion a while ago! –
Provoke
© 2022 - 2024 — McMap. All rights reserved.
publishOn
operator. But moving WebClient off reactor-http-nio pool will only increase the amount of context switching. Reactor's and Reactor Netty's team is doing a wonderful job already optimizing things and abstracting away the threads. – Almagest