在之前的代碼中,創建mina連接時,NioSocketAcceptor
採用的註解@bean
中,destroyMethod
是destroy
。
在tomcat中執行shutdown.sh
後,可能會出現內存泄漏的情況,例如:
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
2019-07-08 15:26:14.928 INFO 27200 --- [250-startStop-1] org.my.ServletInitializer : Starting ServletInitializer on ybtserver with PID 27200 (/usr/src/springboot_mina-0.0.1-SNAPSHOT/WEB-INF/classes started by root in /usr/local/tomcat/bin)
2019-07-08 15:26:14.932 INFO 27200 --- [250-startStop-1] org.my.ServletInitializer : No active profile set, falling back to default profiles: default
08-Jul-2019 15:26:15.844 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
2019-07-08 15:26:15.845 INFO 27200 --- [250-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 860 ms
2019-07-08 15:26:16.136 INFO 27200 --- [250-startStop-1] org.my.mina.handler.ServerHandler : >>>>>> server handlers set success!
2019-07-08 15:26:16.595 INFO 27200 --- [250-startStop-1] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-07-08 15:26:16.825 INFO 27200 --- [250-startStop-1] org.my.ServletInitializer : Started ServletInitializer in 2.394 seconds (JVM running for 4.674)
2019-07-08 15:26:16.832 INFO 27200 --- [250-startStop-1] org.my.mina.MinaServerRun : ---springboot mina server start---
08-Jul-2019 15:26:16.895 INFO [192.168.10.250-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
08-Jul-2019 15:26:16.941 WARNING [main] org.apache.catalina.mapper.MapperListener.findDefaultHost Unknown default host [localhost] for service [StandardService[Catalina]]
08-Jul-2019 15:26:16.943 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:26:16.952 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:26:16.954 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 4059 ms
08-Jul-2019 15:26:44.670 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:26:44.671 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:26:44.682 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:26:44.688 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:26:44.696 INFO [192.168.10.250-startStop-2] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:26:44.722 WARNING [192.168.10.250-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [NioSocketAcceptor-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:760)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2401)
org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:859)
org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1333)
org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1185)
ch.qos.logback.classic.spi.PackagingDataCalculator.populateFrames(PackagingDataCalculator.java:74)
ch.qos.logback.classic.spi.PackagingDataCalculator.calculate(PackagingDataCalculator.java:58)
ch.qos.logback.classic.spi.ThrowableProxy.calculatePackagingData(ThrowableProxy.java:142)
ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:122)
ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
ch.qos.logback.classic.Logger.warn(Logger.java:692)
org.apache.mina.util.DefaultExceptionMonitor.exceptionCaught(DefaultExceptionMonitor.java:47)
org.apache.mina.core.polling.AbstractPollingIoAcceptor$Acceptor.run(AbstractPollingIoAcceptor.java:497)
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
08-Jul-2019 15:26:44.734 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:26:44.738 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:26:44.741 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:26:44.742 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
查詢了網上的資料,打算採用ServletContextListener
來啓動mina,通過contextDestroyed
方法來關閉mina,同時去掉@bean
註解中的destroyMethod
參數。
首先註釋掉MinaServerRun
類的@Component
註解,不再由這個類啓動mina。
然後創建一個listener來啓動mina,實現如下:
@WebListener
public class MinaRunServletContextListener implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(MinaRunServletContextListener.class);
@Autowired
private NioSocketAcceptor acceptor;
@Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("---server acceptor unbind---");
// System.out.println("---server acceptor unbind---" + Thread.currentThread().getName());
acceptor.unbind();
logger.info("---server acceptor dispose---");
// System.out.println("---server acceptor dispose---" + Thread.currentThread().getName());
acceptor.dispose();
}
@Override
public void contextInitialized(ServletContextEvent sce) {
WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext())
.getAutowireCapableBeanFactory().autowireBean(this);
try {
acceptor.bind(new InetSocketAddress(Const.PORT));
logger.info("---springboot mina server start---");
} catch (IOException e) {
logger.error("---springboot mina server start error : ", e.getMessage() + "---");
}
}
}
同時啓動類中,加上@ServletComponentScan
註解, 以便能夠掃描到自定義的這個listener。
結果如下:
08-Jul-2019 15:36:48.361 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:36:48.362 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:36:48.373 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:36:48.379 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:36:48.386 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:36:48.414 WARNING [192.168.10.250-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [NioSocketAcceptor-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.apache.mina.core.future.DefaultIoFuture.await0(DefaultIoFuture.java:218)
org.apache.mina.core.future.DefaultIoFuture.awaitUninterruptibly(DefaultIoFuture.java:148)
org.apache.mina.core.polling.AbstractPollingIoProcessor.dispose(AbstractPollingIoProcessor.java:188)
org.apache.mina.core.service.SimpleIoProcessorPool.dispose(SimpleIoProcessorPool.java:337)
org.apache.mina.core.polling.AbstractPollingIoAcceptor$Acceptor.run(AbstractPollingIoAcceptor.java:515)
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
08-Jul-2019 15:36:48.416 WARNING [192.168.10.250-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [NioProcessor-5] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:351)
java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
08-Jul-2019 15:36:48.423 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:36:48.428 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:36:48.432 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:36:48.433 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
好像不太對,除了NioSocketAcceptor
外,NioProcessor
創建的線程也出現了內存泄漏的情況,而且定義的contextDestroyed
方法中的日誌也沒打印,怎麼回事?
查詢了網上的衆多帖子,終於在一個帖子中找到了可能的原因:
springboot優雅的關閉應用
裏面提到:
將springboot應用註冊爲linux服務時,發現通過service xxx stop命令停止應用時,contextDestroyed的日誌根本沒打印出來,懷疑是LOGGER對象已經被jvm回收,於是改成System.out,這次begin打印出來了,但是並沒有調用 ShutdownUtil.destroy()方法,懷疑同上,具體的機制沒去詳細瞭解,猜測是springboot自己的回收策略,或者是該插件的坑。
於是採用sysout試了一下,結果如下:
08-Jul-2019 15:42:15.213 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:42:15.214 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:42:15.224 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:42:15.230 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:42:15.237 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
---server acceptor unbind---192.168.10.250-startStop-1
---server acceptor dispose---192.168.10.250-startStop-1
08-Jul-2019 15:42:15.262 WARNING [192.168.10.250-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [NioSocketAcceptor-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.security.AccessController.getStackAccessControlContext(Native Method)
java.security.AccessController.getContext(AccessController.java:820)
java.lang.Thread.init(Thread.java:412)
java.lang.Thread.init(Thread.java:349)
java.lang.Thread.<init>(Thread.java:675)
java.util.concurrent.Executors$DefaultThreadFactory.newThread(Executors.java:613)
java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:612)
java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:925)
java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1368)
org.apache.mina.core.polling.AbstractPollingIoProcessor.startupProcessor(AbstractPollingIoProcessor.java:475)
org.apache.mina.core.polling.AbstractPollingIoProcessor.dispose(AbstractPollingIoProcessor.java:185)
org.apache.mina.core.service.SimpleIoProcessorPool.dispose(SimpleIoProcessorPool.java:337)
org.apache.mina.core.polling.AbstractPollingIoAcceptor$Acceptor.run(AbstractPollingIoAcceptor.java:515)
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
08-Jul-2019 15:42:15.271 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:42:15.275 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:42:15.279 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:42:15.280 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
發現sysout確實打印出來了,看來logger對象可能已經被spring回收了,但還是出現了內存泄漏的情況,這個可能是因爲NioSocketAcceptor
對象已經被回收了,於是註釋掉contextDestroyed
方法中的內容,同時在@bean
註解中添加destroyMethod = "unbind"
參數。
重新嘗試:
08-Jul-2019 15:49:58.150 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:49:58.151 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:49:58.161 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:49:58.167 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:49:58.174 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:49:58.197 WARNING [192.168.10.250-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-3-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
08-Jul-2019 15:49:58.207 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:49:58.210 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:49:58.213 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:49:58.214 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
還是存在內存泄漏情況,打算放棄這種方式,採用最初的方式試一下,通過MinaServerRun
類啓動,畢竟最初的方式沒有嘗試修改destroyMethod
後是否能正常使用。
結果如下:
08-Jul-2019 15:53:27.170 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:53:27.171 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:53:27.182 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:53:27.188 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:53:27.193 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:53:27.206 WARNING [192.168.10.250-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-3-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
08-Jul-2019 15:53:27.211 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:53:27.214 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:53:27.217 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:53:27.218 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
怎麼還是有問題,頭都大了。。。。。。
嘗試將destroyMethod
換成dispose
:
08-Jul-2019 15:55:52.872 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:55:52.873 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:55:52.883 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:55:52.888 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:55:52.895 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:55:52.941 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:55:52.944 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:55:52.948 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:55:52.949 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
終於不再出現內存泄漏情況。。。。。。
爲避免是偶爾出現,再次嘗試:
08-Jul-2019 15:57:06.149 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:57:06.150 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:57:06.161 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:57:06.167 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:57:06.173 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:57:06.213 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:57:06.216 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:57:06.219 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:57:06.219 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:57:57.310 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 15:57:57.311 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:57:57.319 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:57:57.325 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 15:57:57.330 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 15:57:57.358 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:57:57.361 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 15:57:57.364 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 15:57:57.365 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
貌似可以了,看來採用listener的方式應該也行的通,於是嘗試使用listener,調整的地方和上面嘗試listener時一樣,在contextDestroyed
方法中多打印一句System.out.println("---test contextDestroyed method---");
結果如下:
08-Jul-2019 16:03:03.981 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
08-Jul-2019 16:03:03.982 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
08-Jul-2019 16:03:03.992 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 16:03:03.998 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 16:03:04.003 INFO [192.168.10.250-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
---test contextDestroyed method---
08-Jul-2019 16:03:04.041 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 16:03:04.043 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 16:03:04.046 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 16:03:04.046 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
God bless me !!!
終於優雅的關閉了mina!!!
還是建議通過MinaServerRun
類來啓動mina,因爲可以在啓動mina服務後,增加鉤子方法,當linux採用kill指令關閉tomcat時,還可以優雅的關閉mina:
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
logger.info("---server acceptor unbind---");
acceptor.unbind();
logger.info("---server acceptor dispose---");
acceptor.dispose();
}
});
首先查出來tomcat所在的進程,然後使用kill指令:
[root@server bin]# ps -ef|grep tomcat
root 31849 1 0 16:08 pts/0 00:00:00 /bin/sh /usr/local/tomcat/bin/catalina.sh start
root 31850 31849 99 16:08 pts/0 00:00:18 /usr/local/jdk1.8.0_66/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
root 31926 15970 0 16:08 pts/0 00:00:00 grep tomcat
[root@server bin]# kill 31850
[root@server bin]# tail -n 50 -f /usr/local/tomcat/logs/catalina.out
查看日誌關鍵內容如下:
2019-07-08 16:08:29.872 INFO 31850 --- [ Thread-7] org.my.mina.MinaServerRun : ---server acceptor unbind---
08-Jul-2019 16:08:29.873 INFO [Thread-8] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-20080"]
2019-07-08 16:08:29.878 INFO 31850 --- [ Thread-6] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2019-07-08 16:08:29.880 INFO 31850 --- [ Thread-7] org.my.mina.MinaServerRun : ---server acceptor dispose---
08-Jul-2019 16:08:29.894 INFO [Thread-8] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 16:08:29.900 INFO [Thread-8] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
08-Jul-2019 16:08:29.906 INFO [192.168.10.250-startStop-2] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
08-Jul-2019 16:08:29.918 INFO [Thread-8] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-20080"]
08-Jul-2019 16:08:29.921 INFO [Thread-8] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-20009"]
08-Jul-2019 16:08:29.924 INFO [Thread-8] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-20080"]
08-Jul-2019 16:08:29.924 INFO [Thread-8] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-20009"]
可以看到NioSocketAcceptor
對象被正常的關閉了。
工程的github地址:
https://github.com/gavinL93/springboot_mina