如何在 Spring 引导应用程序中覆盖线程池
How to override the thread pool in Spring Boot app
我正在编写下面的代码来覆盖线程池。但它不能正常工作。在 spring 启动应用程序启动时设置覆盖线程池的正确方法是什么。请注意,我的代码无法控制 Server 实例,因此实例化服务器不是满足我需要的解决方案。
@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);
});
}
};
}
当我执行代码时,它抛出了以下错误
线程异常 "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)
我也尝试了示例主代码,它也给出了同样的错误。
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();
}
}
这里是在 Jetty 中使用属性和不同类型的线程池配置线程池的示例。我的线程池是 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;
}
}
在 spring 引导 2.x 中,JettyEmbeddedServletContainerFactory
已被 org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory
替换。
需要自定义JettyServletWebServerFactory并设置自己的线程池
@Component
public class JettyConfiguration implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {
@Override
public void customize(JettyServletWebServerFactory factory) {
// customize your thread pool here
QueuedThreadPool qtp = new QueuedThreadPool(80, 500);
qtp.setName("jettyThreadPool");
factory.setThreadPool(qtp);
}
}
我正在编写下面的代码来覆盖线程池。但它不能正常工作。在 spring 启动应用程序启动时设置覆盖线程池的正确方法是什么。请注意,我的代码无法控制 Server 实例,因此实例化服务器不是满足我需要的解决方案。
@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);
});
}
};
}
当我执行代码时,它抛出了以下错误 线程异常 "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)
我也尝试了示例主代码,它也给出了同样的错误。
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();
}
}
这里是在 Jetty 中使用属性和不同类型的线程池配置线程池的示例。我的线程池是 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;
}
}
在 spring 引导 2.x 中,JettyEmbeddedServletContainerFactory
已被 org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory
替换。
需要自定义JettyServletWebServerFactory并设置自己的线程池
@Component
public class JettyConfiguration implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {
@Override
public void customize(JettyServletWebServerFactory factory) {
// customize your thread pool here
QueuedThreadPool qtp = new QueuedThreadPool(80, 500);
qtp.setName("jettyThreadPool");
factory.setThreadPool(qtp);
}
}