springboot 优雅重启 钩子函数执行完成之后进程未消失 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
yangyuhan12138
V2EX    程序员

springboot 优雅重启 钩子函数执行完成之后进程未消失

  •  1
     
  •   yangyuhan12138 2020-02-28 15:12:49 +08:00 3710 次点击
    这是一个创建于 2083 天前的主题,其中的信息可能已经有所发展或是发生改变。

    springboot1.x 优雅重启,钩子函数执行完成之后进程未消失,stop 脚本一直打印停止中,我也去看了 进程确实还在,但是请求也不再接收,而且钩子函数里的日志也打完了,说明钩子函数执行完成 测试环境测试无问题,生产上启动后过一会关闭也没问题,但是如果生产上程序跑了一两天,就关不了了

    22 条回复    2020-03-10 18:10:15 +08:00
    leonard916
        1
    leonard916  
       2020-02-28 15:32:18 +08:00
    啥不升到 Spring boot 2.2.x ?
    yangyuhan12138
        2
    yangyuhan12138  
    OP
       2020-02-28 15:36:28 +08:00
    @leonard916 版本不是你想升 想升就能升
    qfdk
        3
    qfdk  
    PRO
       2020-02-28 15:38:55 +08:00 via iPhone
    优雅劝退 之前用过 actuator 里面有个重启的 boom
    yangyuhan12138
        4
    yangyuhan12138  
    OP
       2020-02-28 15:42:55 +08:00
    @qfdk 我没用 actuator 就是加了个钩子函数关闭 tomcat 线程池 在外边杀进程用的是 kill-15 ,很奇怪就是生产上不行 而且看日志 线程池是关完了的 就是进程一直在
    dzh213
        5
    dzh213  
       2020-02-28 16:16:09 +08:00
    之前遇到过,有任何线程关闭不了,都会造成程序假死,比如用过 Timer 写定时任务,kill -15 是杀不死的,手动申请的线程池没关闭等情况,尽量是优化代码。
    Kyle18Tang
        6
    Kyle18Tang  
       2020-02-28 16:20:31 +08:00
    我们按照官方文档, 打包成的 jar 可以用 systemctl restart 重启, 不知道 1.x 支不支持.
    yangyuhan12138
        7
    yangyuhan12138  
    OP
       2020-02-28 16:49:52 +08:00
    @dzh213 有没有办法看 java 中还在运行的所有线程啊 我这边没有单独开其他线程了 也没有定时任务
    yangyuhan12138
        8
    yangyuhan12138  
    OP
       2020-02-28 16:50:27 +08:00
    @Kyle18Tang 我们并没有把他做成系统服务 稍后我可以试试
    yangyuhan12138
        9
    yangyuhan12138  
    OP
       2020-02-28 17:12:24 +08:00
    systemctl 下边的停止命令还是自己写的啊 还不是得写 kill-15 应该没啥区别吧
    @Kyle18Tang
    Kyle18Tang
        10
    Kyle18Tang  
       2020-02-28 17:34:31 +08:00
    @yangyuhan12138 #9 停机也是使用的 stop, 不用自己写命令, 只是需要在打包的时候设置为可执行 jar 就行了, 但是要往 /etc/systemd/system/里新建一个.service 文件, 这个文件第一次建立就行了, 以后启动 jar 吧就可以使用 systemctl 了.
    dzh213
        11
    dzh213  
       2020-02-28 18:25:22 +08:00
    @yangyuhan12138 我是用比较笨的方法,一边猜一边测出来的,然后把相关代码优化了,比如我刚开始启动然后 kill 掉也是没问题的,启动后再请求一个接口,里面执行了一个没关闭的线程池,就 kill 不掉了。确实不好排查,建议修改 stop 脚本,先 kill -15,一定时长关闭不了,就强制 kill -9。
    AmmeLid
        12
    AmmeLid  
       2020-02-28 18:34:47 +08:00
    @dzh213 #11 可以 jstack 查线程状态
    yangyuhan12138
        13
    yangyuhan12138  
    OP
       2020-02-29 15:04:58 +08:00
    @AmmeLid 收到 我下周再试试 这个不是必然发生的 测试环境基本没有过 生产我们是双机 昨天测试的时候一台没 kill 掉 一台 kill 掉了
    yangyuhan12138
        14
    yangyuhan12138  
    OP
       2020-02-29 15:06:43 +08:00
    @Kyle18Tang 对啊 这个.service 文件里有 stop 的命令,但这个 stop 命令不还是自己写的吗 他只是把你写的 stop 命令执行了一下
    yangyuhan12138
        15
    yangyuhan12138  
    OP
       2020-02-29 15:38:26 +08:00
    @dzh213 可能是还有别的线程池没关到吧 我也觉得 但具体是哪个有点不好找
    Lighfer
        16
    Lighfer  
       2020-02-29 16:49:23 +08:00
    jstack 进程 id,所有线程都列出来,看看线程执行栈信息,过滤掉非 daemon 线程,基本就能定位了
    Kyle18Tang
        17
    Kyle18Tang  
       2020-02-29 21:08:41 +08:00
    @yangyuhan12138 没有 stop 命令,你可以看看官方文档。
    yangyuhan12138
        18
    yangyuhan12138  
    OP
       2020-03-04 17:02:12 +08:00
    @Lighfer 终于被我逮住了 又发生了两次 我 jstack 看了 我把文件 down 下来了 怎么分享出来给大家一起看呢 V2EX 咋分享文件啊
    yangyuhan12138
        19
    yangyuhan12138  
    OP
       2020-03-04 17:22:54 +08:00
    @Lighfer https://github.com/smartisanyyh/gracefulshutdowntrace 麻烦帮忙看看呢... 我看了下除掉 daemon 线程 有台机器上有些 rabbitmq 的连接没有关,另一台机器好像要正常许多 但是进程也没有掉
    yangyuhan12138
        20
    yangyuhan12138  
    OP
       2020-03-04 17:26:30 +08:00
    正常点的那台机器上只有三个线程不是 daemon 都处于 waiting 状态

    "DestroyJavaVM" #37 prio=5 os_prio=0 tid=0x00007f8d38008800 nid=0x49e waiting on condition [0x0000000000000000]
    java.lang.Thread.State: RUNNABLE

    "container-0" #20 prio=5 os_prio=0 tid=0x00007f8d39033800 nid=0x4bb waiting on condition [0x00007f8ce34f9000]
    java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at org.apache.catalina.core.StandardServer.await(StandardServer.java:427)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer$1.run(TomcatEmbeddedServletContainer.java:177)



    "Thread-3" #36 prio=5 os_prio=0 tid=0x00007f8ca8001000 nid=0x2e4e waiting on condition [0x00007f8ca0dda000]
    java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <0x0000000086ede2a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1475)
    at com.dooffe.epay.common.api.DooffeEpayApiApplication$GracefulShutdown.shutDownThreadPool(DooffeEpayApiApplication.java:79)
    at com.dooffe.epay.common.api.DooffeEpayApiApplication$GracefulShutdown.onApplicationEvent(DooffeEpayApiApplication.java:69)
    at com.dooffe.epay.common.api.DooffeEpayApiApplication$GracefulShutdown.onApplicationEvent(DooffeEpayApiApplication.java:53)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:991)
    at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:929)
    - locked <0x0000000085fe8e38> (a java.lang.Object)
    yangyuhan12138
        21
    yangyuhan12138  
    OP
       2020-03-10 18:06:41 +08:00
    @Kyle18Tang 我把生产上的服务变成了 service 启动 ,观察后发现还是有这个问题 ,执行完钩子函数后应用没有停止,因为 service stop 有超时时间所以一段时间后会强制结束进程
    yangyuhan12138
        22
    yangyuhan12138  
    OP
       2020-03-10 18:10:15 +08:00
    @Kyle18Tang 本质上和自己写脚本没有区别, 只是官方写了一段脚本让我们可以更方便的做成系统服务
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5289 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 08:36 PVG 16:36 LAX 00:36 JFK 03:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86