zoukankan      html  css  js  c++  java
  • springboot优雅的关闭应用

    1. 使用actuator,通过发送http请求关闭
    2. 将应用注册为linux服务,通过service xxx stop关闭

    具体这两种方式如何实现,这里就不说了,网上百度一堆,主要讲一下在这两种情况下web应用listener的一些问题

    一般来讲,我们的应用都应该在结束的时候对资源进行回收处理,jvm帮我们做了一部分,springboot也做了相应bean的回收,那如果是我们自己创建的线程池或是其他未托管于spring的资源呢?

    1. 在非web的应用中,我们一般使用勾子来实现,从而保证在jvm退出时,能够进行一些资源的回收(直接kill无法保证执行),kill命令相当于直接把应用干掉,是一种非正常情况下中止应用的方式。ctrl+c,System.exit(),程序正常退出都会触发勾子

      Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
      	            @Override
      	            public void run() {
      	                try {
      	                    shutdown(componentName);
      	                } catch (Exception e) {
      	                    LOGGER.error("shutdown error:", e);
      	                }
      
                  }
              }, componentName + <span class="hljs-string">"_shutdown_hook_thread"</span>));</pre> </li> 
      
    2. 在web应用中,勾子就不一定能够生效了,而是通过实现ServletContextListener接口,可以在context初始化和结束的时候做一些资源创建和回收的操作

      public class ContextListener implements ServletContextListener {
      	    private static final Logger LOGGER = LoggerFactory.getLogger(ContextListener.class);
      
          <span class="hljs-annotation">@Override</span>
          <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">contextInitialized</span><span class="hljs-params">(ServletContextEvent servletContextEvent)</span> </span>{
              LOGGER.info(<span class="hljs-string">"contextInitialized"</span>);
          }
      
          <span class="hljs-annotation">@Override</span>
          <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">contextDestroyed</span><span class="hljs-params">(ServletContextEvent servletContextEvent)</span> </span>{
              LOGGER.info(<span class="hljs-string">"contextDestroyed begin..."</span>);
              ShutdownUtil.destroy();
              LOGGER.info(<span class="hljs-string">"contextDestroyed end..."</span>);
          }
      }</pre> </li> 
      

    问题来了,在使用第二种方式将springboot应用注册为linux服务时,发现通过service xxx stop命令停止应用时,contextDestroyed的日志根本没打印出来,怀疑是LOGGER对象已经被jvm回收,于是改成System.out,这次begin打印出来了,但是并没有调用 ShutdownUtil.destroy()方法,怀疑同上,具体的机制没去详细了解,猜测是springboot自己的回收策略,或者是该插件的坑。

    使用actuator的方式没有问题,会正常的执行destroyed的回收

    原文地址:http://www.voidcn.com/article/p-ojakqglj-bqp.html
  • 相关阅读:
    转:裸接口防护,避免恶意盗刷和爬取
    oracle = : := 和变量绑定 oracle通配符和运算符
    169.254地址无网关信息 ----- 解决方案 启动DHCP服务
    NAS DAS SAN 磁带机 tco
    linux 权限详解
    转载:哈希加密算法 MD5,SHA-1,SHA-2,SHA-256,SHA-512,SHA-3,RIPEMD-160
    MD5,SHA1 都是哈希 摘要算法 MD5+SALT BCRYPT
    iOS开发JSON字符串和字典互转
    iOS开发线程之NSThread
    iOS开发NSMutableArray数组越界处理
  • 原文地址:https://www.cnblogs.com/jpfss/p/10860811.html
Copyright © 2011-2022 走看看