Ale*_*kin 5 java amazon-ecs docker microservices
我们在 AWS ECS 中运行 Java 微服务。因此,对于 Docker,我们使用 -Xmx 指定一些 Java 堆硬限制。确定可以为堆保留多少内存以及需要多少非堆内存(元空间、堆栈、JIT 缓存等)是一个非常棘手的部分。目前,我们正在运行压力测试来确定何时有 Docker OOMKiller。例如,对于 2GB AWS 任务(docker),我们最多可以为堆设置 -Xmx1400m(使用 -Xmx1450m 我们没有足够的内存用于非堆内容(退出代码137))实际上,Java 10+ 有“-XX:MaxRAMPercentage” “但我们仍然需要知道这个百分比。
如何确定 Java 微服务的堆/非堆大小?或者压力测试是唯一的解决方案?
从 Java 8u131 开始,有一个选项可以根据容器内存限制设置 JVM 限制。所以如果你运行类似的东西:
docker run \
-m 2g \ # set a container memory limit
openjdk:8 \
java \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseCGroupMemoryLimitForHeap \
com.example.Classname
Run Code Online (Sandbox Code Playgroud)
JVM 将设置堆限制,使其符合 2 GB 容器内存限制,-Xmx为您运行。原则上,这应该安排好事情,以便您永远不会达到容器内存限制,而是OutOfMemoryError首先获得 Java。
这篇博文还有关于该主题的更多示例,并且还建议-XX:MaxRamFraction=1允许使用“所有内存”,您可以使用该docker run -m选项来限制它。
在实践中,你可能会$JAVA_OPTS在 Dockerfile 中设置类似
FROM openjdk:8
COPY app.jar /
ENV JAVA_OPTS=-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRamFraction=1
CMD ["java", "-jar", "/app.jar"]
Run Code Online (Sandbox Code Playgroud)
然后运行它就像
docker run -d -p ... -m 2g myimage
Run Code Online (Sandbox Code Playgroud)
在 Kubernetes 环境中,Pod 资源约束中声明的内存限制起着相同的作用。
正如 @KarolDowbecki 在他们的答案中建议的那样,您确实需要进行一些分析和监视才能真正为此选择正确的数字。在本地运行应用程序并监视或RSS中的(驻留集大小)统计数据应该会给您一个合理的基线。pstop
| 归档时间: |
|
| 查看次数: |
2989 次 |
| 最近记录: |