我有一个在Ubuntu 16.04 LTS上运行的Java应用程序。关闭线程在执行端点呼叫时消失
当应用程序接收到关闭信号,停止序列像这样运行:
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
shutdown();
}
});
这工作得很好,但只要我尝试调用外部REST端点(我用的改造,其中Rx Observable)线程完全消失,端点永远不会被调用,并且连续的命令不再被执行。
- 我首先想到Observables会是问题,并使用改造
Call
来代替。同样的问题。 - 然后我尝试进行同步调用,而不是调用端点异步。同样的问题。
- 关机时间不是问题。我明确地给了30秒。
我认为这与线程有关,当一个库在关闭时创建额外的线程时,JVM似乎会杀死所有内容。
任何人都可以摆脱光线或建议我可以尝试什么,请。
-
额外信息:
我需要执行长期运行的清理。问题是我无法确定关闭信号是如何看起来像什么时候发生的,因为JVM运行在一个Docker容器中,该容器在docker stop
(当主机停止时)首先发送SIGTERM
,然后在超时之后(我可以设置,目前60秒)SIGKILL
。容器中的JVM运行socket.io,可以连接数千个客户端。我希望使用60秒向每个客户端发送good-bye
,并干净地断开这些连接,并从负载均衡器注销服务器。所以在清理过程中有很多潜在的阻塞操作。
如果你的Java认为,清理总是短暂的,那么Java是错误的:(
关闭挂钩应尽快退出,并且肯定不参与网络操作。看到Javadoc。 – EJP