为什么zuul网关应用程序花了这么长时间才以优雅的方式关闭



我在通过自己开发的CICD模块更新和重新启动应用程序时遇到了一种情况。

我有尤里卡作为注册中心,祖尔作为网关。

通过使用kill-15命令运行shell脚本,我希望以一种优雅的方式关闭我的应用程序。并且shell脚本运行正确。

但到目前为止,在测试和观察这个CICD模块的过程中,我发现重新启动zuul网关应用程序将需要很长时间才能关闭(大约5分钟等待,其他应用程序只需要不到5秒(。

据我所知,springboot将首先关闭线程池以拒绝解析新请求,然后让剩余的线程完成,然后关闭应用程序上下文。

重新启动网关应用程序时,我已完成以下步骤:

  1. 从nginx上游拉下这个网关服务
  2. 从尤里卡服务器上删除此网关服务,但不关闭
  3. 等待90秒
30 (eureka server refresh to readable server list cache default 30s )
+ 30 (eureka client fetching interval default 30s)
+ 30 (ribbon refreshing after eureka client fething server list cache default 30s)
  1. 使用kill -15 applicationPid关闭应用程序
  2. 循环查看此pid是否已关闭
  3. 重新启动新应用程序
  4. 如果可以从eureka服务器的api访问应用程序,请等待60秒
30 (eureka client fetching interval default 30s)
+ 30 (ribbon refreshing after eureka client fething server list cache default 30s)
  1. 从nginx中调出此网关服务

测试计划如下所示:

  1. 通过从20个线程发送请求,每个线程每秒将发送3个请求
  2. 2台Linux服务器A和B,每台服务器上都有一个网关服务
  3. 当关闭A的网关时,nginx会指向B并让B承担任务,当B的网关关闭时,选项相同



正如我所观察到的,所有请求都将得到正确解决,并且在重新启动网关应用程序的过程中没有出现任何错误。

但我不知道为什么关闭网关应用程序要花这么多时间。在nginx被关闭后,完全没有请求混合,应用程序仍然停留在那里,似乎没有有用的日志来显示发生了什么。

几分钟后,应用程序将最终关闭。

如果我不发送请求,网关应用程序将立即正常关闭。

当它被卡住时,控制台日志如下所示:

....normal log....
2021-07-19 14:42:08.195 [app:web-gateway,traceId:,spanId:,parentId:] [SpringContextShutdownHook] INFO  | EurekaServiceRegistry.java:65 | o.s.c.n.e.s.EurekaServiceRegistry | Unregistering application WEB-GATEWAY with eureka with status DOWN
2021-07-19 14:42:08.195 [app:web-gateway,traceId:,spanId:,parentId:] [SpringContextShutdownHook] WARN  | DiscoveryClient.java:1351 | c.netflix.discovery.DiscoveryClient | Saw local status change event StatusChangeEvent [timestamp=1626676928195, current=DOWN, previous=UP]
2021-07-19 14:42:08.195 [app:web-gateway,traceId:,spanId:,parentId:] [DiscoveryClient-InstanceInfoReplicator-0] INFO  | DiscoveryClient.java:870 | c.netflix.discovery.DiscoveryClient | DiscoveryClient_WEB-GATEWAY/192.168.24.200:web-gateway:8005:NEW_GATEWAY_DEFAULT_GROUP: registering service...
2021-07-19 14:42:08.199 [app:web-gateway,traceId:,spanId:,parentId:] [DiscoveryClient-InstanceInfoReplicator-0] INFO  | DiscoveryClient.java:879 | c.netflix.discovery.DiscoveryClient | DiscoveryClient_WEB-GATEWAY/192.168.24.200:web-gateway:8005:NEW_GATEWAY_DEFAULT_GROUP - registration status: 204
2021-07-19 14:42:08.252 [app:web-gateway,traceId:,spanId:,parentId:] [Thread-17] INFO  | EurekaNotificationServerListUpdater.java:71 | c.n.n.l.EurekaNotificationServerListUpdater | Shutting down the Executor for EurekaNotificationServerListUpdater
2021-07-19 14:42:08.745 [app:web-gateway,traceId:,spanId:,parentId:] [SpringContextShutdownHook] INFO  | DirectJDKLog.java:173 | o.a.coyote.http11.Http11NioProtocol | Pausing ProtocolHandler ["http-nio-8005"]
2021-07-19 14:43:18.087 [app:web-gateway,traceId:,spanId:,parentId:] [AsyncResolver-bootstrap-executor-0] INFO  | ConfigClusterResolver.java:43 | c.n.d.s.r.aws.ConfigClusterResolver | Resolving eureka endpoints via configuration
.....stuck here.....

因为我已经手动从eureka中删除了网关应用程序,所以这里的应用程序日志显示代码204是可以接受的。

我曾经猜测,如果是代码204错误导致应用程序被卡住而关闭。但是,在调用kill-15命令后,其他同样承载请求的应用程序将立即优雅地关闭。只有网关应用程序将被卡住。



有人能告诉我如何从卡住的应用程序中结账,看看kill-15命令完成后发生了什么吗?

问题解决了。
从不质疑稳定的结构。。。。
我的线程池出了问题,所以在使用kill -15时,我的自定义线程池有很多任务没有结束。
通过检查JVM的堆栈,我发现了这个问题。通过更正代码,问题解决了。

最新更新