【发布时间】:2019-10-04 23:30:57
【问题描述】:
我们有一个 Spring Boot (2.0.4) 应用程序公开了许多端点,其中一个端点使客户端有时可以检索非常大的文件 (~200 GB)。该应用程序通过配置了滚动更新策略的 Kubernetes 部署在 Pod 中公开。
当我们通过将映像设置为最新版本来更新我们的部署时,Pod 会被破坏,新的 Pod 会启动。我们为新请求提供无缝服务。然而,当前的请求可能而且确实会被切断,这对于正在下载非常大文件的客户端来说可能很烦人。
我们可以在部署规范中配置 Container Lifecycle Pre-Stop 挂钩,以便在通过其 PID 向应用发送关闭信号之前注入暂停。这有助于防止任何新流量流向已设置为终止的 pod。有没有办法暂停应用程序关闭过程,直到所有当前请求都完成(这可能需要几十分钟)?
这是我们在 Spring Boot 应用程序中尝试过的:
实现一个拦截
ContextCloseEvents的关闭监听器;不幸的是,我们无法可靠地检索活动请求列表。在关闭过程的这个阶段,任何可能有用的执行器指标都不可用。通过实现
HttpSessionListener并覆盖sessionCreated/Destroy方法来更新计数器来计算活动会话。这会失败,因为这些方法不是在单独的线程上调用的,因此始终在关闭侦听器中报告相同的值。
我们应该尝试任何其他策略吗?来自应用程序本身、容器,还是直接通过 Kubernetes 资源描述符?建议/帮助/指针将不胜感激。
编辑:我们管理集群,因此我们只是在通过修改后的 pod 规范对我们的部署进行管理更新期间尝试减轻对当前连接的客户端的服务中断
【问题讨论】:
-
用 preStop 钩子注入暂停有什么问题?只要记住还要通过注入暂停的持续时间来增加terminationGracePeriodSeconds。您甚至可以进一步检查 netstat 表,看看是否还有任何已建立的网络连接。
标签: java spring-boot docker kubernetes spring-boot-actuator