编程

当前位置:时时彩平台 > 编程 > Spring Boot 2.0 教程系列 | 配置 Undertow 容器

Spring Boot 2.0 教程系列 | 配置 Undertow 容器

来源:http://www.mrmtshipyard.com 作者:时时彩平台 时间:2019-10-05 05:24

相关内容

Shut down embedded servlet container gracefully

所以,我们推荐您使用 Undertow 容器。接下来,就我们看看如何在 Spring Boot 中快捷地集成 Undertow。

Spring Boot Application 在接收到停机信号后,可以通过 DisposableBean 接口 、 @PreDestroy 注解 或者 ContextClosedEvent 事件来处理优雅停机的相关逻辑。

三、Undertow 相关配置

您可以针对 Undertow 容器做一些特定配置,如日志输出路径,设置工作者线程的个数等参数优化等,如下所示:

# 是否打开 undertow 日志,默认为 falseserver.undertow.accesslog.enabled=false# 设置访问日志所在目录server.undertow.accesslog.dir=logs# 指定工作者线程的 I/0 线程数,默认为 2 或者 CPU 的个数server.undertow.io-threads=# 指定工作者线程个数,默认为 I/O 线程个数的 8 倍server.undertow.worker-threads=# 设置 HTTP POST 内容的最大长度,默认不做限制server.undertow.max-http-post-size=0

图片 1

二、启动项目

添加完上面的 maven 依赖后,Undertow 容器就已经集成完毕了,接下来,让我们启动项目,看看控制台输出:

Connected to the target VM, address: '127.0.0.1:50915', transport: 'socket'  .   ____          _            __ _ _ /\ / ___'_ __ _ __ __  __ _    \___ | '_ | '_| | '_ / _` |     \/  ___)| |_)| | | | | ||  ) )  '  |____| .__|_| |_|_| |___, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot ::        (v2.1.2.RELEASE)2019-02-22 20:29:28.876  INFO 21908 --- [           main] s.e.s.SpringBootUndertowApplication      : Starting SpringBootUndertowApplication on DESKTOP-RL6P6LA with PID 21908 (C:devidea_workspace_personalspring-boot-tutorialspring-boot-undertowtargetclasses started by allen in C:devidea_workspace_personalspring-boot-tutorial)2019-02-22 20:29:28.885  INFO 21908 --- [           main] s.e.s.SpringBootUndertowApplication      : No active profile set, falling back to default profiles: default2019-02-22 20:29:34.388  WARN 21908 --- [           main] io.undertow.websockets.jsr               : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used2019-02-22 20:29:34.478  INFO 21908 --- [           main] io.undertow.servlet                      : Initializing Spring embedded WebApplicationContext2019-02-22 20:29:34.478  INFO 21908 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 5449 ms2019-02-22 20:29:35.471  INFO 21908 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'2019-02-22 20:29:36.423  INFO 21908 --- [           main] org.xnio                                 : XNIO version 3.3.8.Final2019-02-22 20:29:36.447  INFO 21908 --- [           main] org.xnio.nio                             : XNIO NIO Implementation Version 3.3.8.Final2019-02-22 20:29:36.614  INFO 21908 --- [           main] o.s.b.w.e.u.UndertowServletWebServer     : Undertow started on port 8080  with context path ''2019-02-22 20:29:36.621  INFO 21908 --- [           main] s.e.s.SpringBootUndertowApplication      : Started SpringBootUndertowApplication in 8.912 seconds (JVM running for 10.232)2019-02-22 20:29:48.534  INFO 21908 --- [  XNIO-1 task-1] io.undertow.servlet                      : Initializing Spring DispatcherServlet 'dispatcherServlet'2019-02-22 20:29:48.534  INFO 21908 --- [  XNIO-1 task-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'2019-02-22 20:29:48.547  INFO 21908 --- [  XNIO-1 task-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 12 ms

启动成功,当您看到 Undertow started on port 8080 with context path '' 的行输出时,说明此时正在使用的是 Undertow 容器,而非 Tomcat !

图片 2

版本信息

Spring Boot 版本: 2.0.0.RELEASE

欢迎关注公众号: 小哈学Java

图片 3

Spring Boot 在关闭时,如果有请求没有响应完,在不同的容器会出现不同的结果,例如,在 Tomcat 和 Undertow 中会出现中断异常,那么就有可能对业务造成影响。所以,优雅停机非常有必要性,目前官方是没有提供很好的策略来实现。

本节中,您将学习如何在 Spring Boot 2.0 中配置 Undertow 容器。配置之前,您需要知道的是,Tomcat, Jetty, Undertow 作为三大主流 Servelt 容器,Undertow 的性能要优于前两者。

Each SpringApplication registers a shutdown hook with the JVM to ensure that the ApplicationContext closes gracefully on exit. All the standard Spring lifecycle callbacks (such as the DisposableBean interface or the @PreDestroy annotation) can be used.

欢迎关注微信公众号: 小哈学Java
文章首发于个人网站

Jetty 优雅停机

默认支持所有请求完毕后再关闭,缺点:客户端接收不到响应,有待改进!

一、添加 Maven 依赖

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>    <!-- 移除掉默认支持的 Tomcat -->    <exclusions>        <exclusion>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-tomcat</artifactId>        </exclusion>    </exclusions></dependency><!-- 添加 Undertow 容器 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-undertow</artifactId></dependency>

Tomcat 优雅停机

@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } /** * 用于接受 shutdown 事件 */ @Bean public GracefulShutdown gracefulShutdown() { return new GracefulShutdown(); } @Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); tomcat.addConnectorCustomizers(gracefulShutdown; return tomcat; } /** * 优雅关闭 Spring Boot */ private class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> { private final Logger log = LoggerFactory.getLogger(GracefulShutdown.class); private volatile Connector connector; private final int waitTime = 30; @Override public void customize(Connector connector) { this.connector = connector; } @Override public void onApplicationEvent(ContextClosedEvent contextClosedEvent) { this.connector.pause(); Executor executor = this.connector.getProtocolHandler().getExecutor(); if (executor instanceof ThreadPoolExecutor) { try { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor; threadPoolExecutor.shutdown(); if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) { log.warn("Tomcat thread pool did not shut down gracefully within " + waitTime + " seconds. Proceeding with forceful shutdown"); } } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } } }}

六、GitHub 源码

Undertow 优雅停机

@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } /** * 优雅关闭 Spring Boot */ @Component public class GracefulShutdown implements ApplicationListener<ContextClosedEvent> { @Autowired private GracefulShutdownWrapper gracefulShutdownWrapper; @Autowired private ServletWebServerApplicationContext context; @Override public void onApplicationEvent(ContextClosedEvent contextClosedEvent){ gracefulShutdownWrapper.getGracefulShutdownHandler().shutdown(); try { UndertowServletWebServer webServer = (UndertowServletWebServer)context.getWebServer(); Field field = webServer.getClass().getDeclaredField("undertow"); field.setAccessible; Undertow undertow =  field.get(webServer); List<Undertow.ListenerInfo> listenerInfo = undertow.getListenerInfo(); Undertow.ListenerInfo listener = listenerInfo.get; ConnectorStatistics connectorStatistics = listener.getConnectorStatistics(); while (connectorStatistics.getActiveConnections{} }catch (Exception e){ // Application Shutdown } } }}

@Componentpublic class GracefulShutdownWrapper implements HandlerWrapper{ private GracefulShutdownHandler gracefulShutdownHandler; @Override public HttpHandler wrap(HttpHandler handler) { if(gracefulShutdownHandler == null) { this.gracefulShutdownHandler = new GracefulShutdownHandler; } return gracefulShutdownHandler; } public GracefulShutdownHandler getGracefulShutdownHandler() { return gracefulShutdownHandler; }}

@Component@AllArgsConstructorpublic class UndertowExtraConfiguration { private final GracefulShutdownWrapper gracefulShutdownWrapper; @Bean public UndertowServletWebServerFactory servletWebServerFactory() { UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); factory.addDeploymentInfoCustomizers(deploymentInfo -> deploymentInfo.addOuterHandlerChainWrapper(gracefulShutdownWrapper)); factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_STATISTICS, true)); return factory; }}

五、环境说明

上述 Demo 是基于 Spring Boot 2.1.2.RELEASE,需要注意一下 !

四、Tomcat Vs Undertow 容器性能对比

在文章的开始,我们提到过 Undertow 的性能要优于 Tomcat, 但是口说无凭,需要拿出实际的证据,新建一个 Web 项目,通过 JDK 自带的工具对比一下各项指标情况:

先看看 Tomcat:

图片 4

可以看到,Tomcat 大约使用了 110M 的堆内存以及大约 16 个线程数!

再来看看轻量级 Servlet 容器 Undertow 的指标:

图片 5

Undertow 的内存使用情况大约为 90M, 线程数大约 13 个线程的样子。这还是在应用不复杂的情况下,大型应用出入会更大。

本文由时时彩平台发布于编程,转载请注明出处:Spring Boot 2.0 教程系列 | 配置 Undertow 容器

关键词:

上一篇:Spring(5)——Spring 和数据库编程

下一篇:没有了