Daw*_*wel 5 java spring jvm autoscaling kubernetes
我正在尝试在 Kubernetes(托管在 Google Kubernetes Engine 中)中为我的 Java Spring 应用程序设置自动缩放。我遇到了两个问题:
Spring 应用程序在启动时使用大量 cpu(类似于 250mCPU*,但有时甚至是 500mCPU),这确实破坏了自动缩放,因为该应用程序的某些实例在或多或少不到 1 分钟后(Spring 上下文启动等),仅使用50mCPU。因为在某些环境下,应用程序使用少量的 mCPU(几乎在晚上的每个环境中),我想设置请求的 cpu=200mCPU max(= 80% 限制 cpu)(甚至更少!)。那么自动缩放就更有意义了。但我真的不能这么做,因为 Spring 的启动很繁重,如果我给他的 cpu 太少,它就不会完成。
当应用程序开始接收流量时(当由于自动缩放事件而创建新的 Pod 时),其 CPU 使用率可能会跳到标准使用率的 200% 之类的水平,然后又回到 100% - 看起来并不是因为太多的请求被推送到新的 pod,看起来更像是 JVM 在开始时速度较慢,并且在请求时收到了太多流量。看起来 JVM 需要诸如预热之类的东西(所以不要突然将 1/n 的流量推送到新 pod,而是将流量切换到新 pod 的速度更慢)。由于这种行为,自动缩放有时会变得疯狂 - 当它确实只需要多一个 Pod 时,它可以放大很多 Pod,然后缩小......
* 在 GKE 1000mCPU 中 = 1 个核心
在上传的图像上我们可以看到 cpu 图表。首先,我们可以看到启动后的cpu使用率比开始时要小得多。在第二个中,我们可以发现两个问题:开始时 CPU 使用率较高,然后是宽限期(就绪探测初始*延迟尚未完成),然后在接收流量开始时出现高选择。
* 我已将就绪探针初始延迟设置为比上下文加载更长。
我在互联网上找到的唯一一件事就是向该 Pod 添加容器,这只会“睡眠 x”,然后死掉。并将设置添加到该容器请求的 mCPU 数量,该数量将在 Spring 应用程序启动时使用(然后我必须增加该 Spring 应用程序容器的 cpu 限制,但无论如何它不应该造成损害,因为自动缩放应该防止 Spring 应用程序让其他应用程序挨饿)节点中的应用程序)。
我真的很感激任何建议。
确实,Spring 应用程序并不是最适合容器的应用程序,但您可以尝试以下几种方法:
使用 astartupProbe并给您的应用程序启动时间。这里很好地解释了如何计算延迟和阈值
调整您的部署策略中的maxSurge和maxUnavailable,使其最适合您的情况(例如,您可能有 10 个副本,最大激增/最大不可用率为 10%,因此您的 pod 将一一缓慢地推出)。这将有助于减少整个应用程序副本上的流量峰值(文档位于此处)。
如果您的用例允许,您可以考虑延迟加载 Spring 应用程序,这意味着它不会在启动时创建所有对象,而是会等到它们被使用为止。这可能有些危险,因为在某些情况下可能无法在启动时发现问题。
replicas值,则在部署时可能会遇到问题,我找不到相关的 GH 问题 ATM,但您可能希望在那里运行一些测试来了解其行为(扩展超出应有的范围等) )。您可以在这里做的事情有:调整自动缩放阈值和时间(默认为 3 分钟,据我所知),以允许您的部署顺利推出而不会触发自动缩放。
编写自定义自动缩放指标,而不是按 CPU 进行缩放。这需要一些工作,但可能会永久解决您的扩展问题(相关文档)。
最后,你所建议的边车看起来像是一个黑客:)虽然还没有尝试过,所以不能真正说出优点和缺点。
不幸的是,Spring Boot(或 Java)+ K8s 没有灵丹妙药,但情况比几年前要好得多。如果我找到一些有用的资源。我会回来并在这里链接它们。
希望以上内容有所帮助。
干杯
| 归档时间: |
|
| 查看次数: |
2284 次 |
| 最近记录: |