前言
JVM 预热(warm-up)是一个臭名昭著的问题。尽管基于JVM的应用程序有着出色的性能,但是需要一个预热的过程,在预热期间,性能不是最佳的。它可以归因于即时(JIT)编译之类的事情,它通过收集使用情况配置文件信息来优化常用代码。最终的负面影响是,与平均时间相比,在预热期间收到的请求将具有非常高的响应时间。在容器化,高吞吐量,频繁部署和自动伸缩的环境中,此问题可能会加剧。
在这篇文章中,我将讨论我们在Kubernetes集群中使用Java服务关于JVM预热问题的经验和方法。
创世记
几年前,我们从单体架构逐步转为微服务架构,并且部署到Kubernetes中。大多数新服务都是用Java开发的。当我们启用Java服务时,我们首先遇到了这个问题。通过负载测试执行了正常的容量规划过程,并确定N个容器足以处理超出预期的峰值流量。
尽管该服务可以毫不费力地处理高峰流量,但我们开始在部署过程中发现问题。我们的每个Pod在高峰时间处理的RPM都超过10k,而我们使用的是Kubernetes滚动更新机制。在部署期间,服务的响应时间会激增几分钟,然后再稳定到通常的稳定状态。在我们的NewRelic仪表板中,我们将看到类似于以下的图形:
同时,依赖于我们该部署的其他服务在相关时间段内也发生了高响应时间和超时错误。
Take 1: 增加应用数目
我们很快意识到该问题与JVM预热阶段有关