Search code examples
springspring-bootthreadpool

How to override the thread pool in Spring Boot app


I am writing below code to override the thread pool. But it is not working properly. What is the correct way to set override the thread pool in spring boot app startup. Note that i don't have a control in my code over the Server instance, so instantiating a Server is not a solution for my need.

        @Bean
        public EmbeddedServletContainerCustomizer getContainerCustomizer() {
            return (configurableEmbeddedServletContainer) -> {
                if (configurableEmbeddedServletContainer instanceof JettyEmbeddedServletContainerFactory) {
                    ((JettyEmbeddedServletContainerFactory)configurableEmbeddedServletContainer).addServerCustomizers((server) -> {
                        QueuedThreadPool newPool = new QueuedThreadPool(10);
                        QueuedThreadPool oldPool = server.getBean(QueuedThreadPool.class);
                        server.updateBean(oldPool, newPool);        
                    });
                }
            };
        }

When i execute the code, it was throwing below error Exception in thread "main"

java.util.concurrent.RejectedExecutionException: org.eclipse.jetty.io.ManagedSelector@1ee0005 id=0 keys=0 selected=0
    at org.eclipse.jetty.util.thread.QueuedThreadPool.execute(QueuedThreadPool.java:377)
    at org.eclipse.jetty.io.SelectorManager.execute(SelectorManager.java:125)
    at org.eclipse.jetty.io.SelectorManager.doStart(SelectorManager.java:255)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
    at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:260)
    at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81)
    at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:244)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.server.Server.doStart(Server.java:384)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)

I tried by sample main code also, and it is also giving same error.

public class FileServer
{
    public static void main(String[] args) throws Exception
    {
         Server server = new Server(9090);

        QueuedThreadPool newPool = new QueuedThreadPool(10);
        QueuedThreadPool oldPool = server.getBean(QueuedThreadPool.class);
        server.updateBean(oldPool, newPool);


        ResourceHandler resource_handler = new ResourceHandler();

        resource_handler.setDirectoriesListed(true);
        resource_handler.setWelcomeFiles(new String[]{ "index.html" });
        resource_handler.setResourceBase(".");

         HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
        server.setHandler(handlers);

         server.start();
        server.join();
    }
}

Solution

  • Here is an example of configuring a thread pool in Jetty with properties and a different type of thread pool. The thread pool in my case is InstrumentedQueuedThreadPool.

    @Configuration
    public class CustomJettyConfiguration {
    
        @Bean
        public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory(
                @Value("${server.port:8080}") final String port,
                @Value("${jetty.threadPool.maxThreads:600}") final String maxThreads,
                @Value("${jetty.threadPool.minThreads:10}") final String minThreads,
                @Value("${jetty.threadPool.idleTimeout:5000}") final String idleTimeout) {
            final JettyEmbeddedServletContainerFactory factory =
                    new JettyEmbeddedServletContainerFactory(Integer.valueOf(port));
    
            // Tweak the connection pool used by Jetty to handle incoming HTTP connections
            InstrumentedQueuedThreadPool instThreadPool =
                    new InstrumentedQueuedThreadPool(registry);
            instThreadPool.setPrefix("jetty");
            instThreadPool.setMaxThreads(Integer.valueOf(maxThreads));
            instThreadPool.setMinThreads(Integer.valueOf(minThreads));
            instThreadPool.setIdleTimeout(Integer.valueOf(idleTimeout));
            factory.setThreadPool(instThreadPool);
    
            ...
            return factory;
        }
    }