2

我们有一个非常简单的应用程序,其中我们有一个 spring 集成入站jdbc轮询器,它从 db 表中轮询数据并将这些记录放在直接通道中。从那个通道我们有服务激活器,它获取这些记录并将其放入rabbitmq队列。轮询器被配置为使用用户定义ThreadPoolTaskExecutor的轮询,最小和最大 1 个线程,这就是我们想要的。

这个应用程序运行良好几天,它以 5 秒的固定延迟进行轮询。还监视这个线程看起来像在 200 毫秒内完成它的工作。

然后突然之间这个轮询线程停止轮询几分钟,这个间隙有时是 1 分钟,有时是 20 分钟。这是不一致的。如果我们重新启动应用程序,那么一旦它重新启动它就会轮询一次,然后它会再次回到不一致的轮询。

我们通过弹簧启动执行器进行了多个线程转储,如果我们分析这些转储,那么我们看不到任何死锁。所有线程转储上显示的所有轮询线程都是WAITING状态。

我们使用带有 spring 集成的 spring boot 2.2.6,并且应用程序部署在 PCF 中。

自从 Spring Boot 从 2.1.4 升级到 2.2.6 以来,我们已经看到了这种行为,但我不能自信地这么说。

有人可以提供一些可能导致这种奇怪行为的提示吗?

4

1 回答 1

0

这是根本原因。当您在应用程序中添加 @EnableScheduling 注解时,Spring Boot 会添加单线程池。我们还有 spring-cloud-config-client 作为依赖项,由于我们使用 vault 来存储我们的秘密,我们必须更新令牌,所以我们提供了该令牌作为属性。这将添加另一个自动配置的 bean 来更新保险库令牌。现在由于池中有单线程并且我们遇到了网络/保险库性能问题,该线程一直卡在更新保险库令牌并且几乎没有被释放来进行数据库轮询。我们还使用保险库的默认续订率,这增加了这个问题。所以有两件事帮助解决了这个问题。我们将保险库令牌的 ttl 增加到 24 小时,并且我们的系统管理员修复了网络/保险库性能问题。

于 2020-12-11T14:21:30.890 回答