AWS beanstalk 中 docker 容器中的 JVM 内存设置

Posted

技术标签:

【中文标题】AWS beanstalk 中 docker 容器中的 JVM 内存设置【英文标题】:JVM memory settings in docker container in AWS beanstalk 【发布时间】:2016-10-10 02:07:39 【问题描述】:

我在 docker 容器中运行我的 java 应用程序。我使用 AWS Beanstalk。 docker 基础镜像是 CentOS。我在 Amazon Linux AMI for Beanstalk 上运行具有 4GB RAM 的 EC2 实例上的容器。

我应该如何配置容器和 JVM 内存设置。 现在我有:

4GB 在 Amazon Linux Beanstalk AMI ec2 实例上

我将 3GB 的 4 专用于一个 docker 容器


  "AWSEBDockerrunVersion": 2,
  "Authentication": 
    "Bucket": "elasticbeanstalk-us-east-1-XXXXXX",
    "Key": "dockercfg"
  ,
  "containerDefinitions": [
    
      "name": "my-service",
      "image": "docker-registry:/myapp1.0.2",
      "essential": true,
      "memory": 3184,
      "portMappings": [
        
          "hostPort": 80,
          "containerPort": 8080
        
      ]
    

JVM设置是

  -Xms2560m
  -Xmx2560m
  -XX:+UseConcMarkSweepGC
  -XX:+CMSParallelRemarkEnabled
  -XX:+UseCMSInitiatingOccupancyOnly
  -XX:CMSInitiatingOccupancyFraction=70
  -XX:+ScavengeBeforeFullGC
  -XX:+CMSScavengeBeforeRemark
  -XX:+HeapDumpOnOutOfMemoryError
  -XX:HeapDumpPath=./heapdump.hprof

我能否将整个 ec2 实例内存专用于 4GB 的 docker 容器,并将 JVM 也设置为 4GB?

我认为当 JVM 无法分配 Xmx 内存参数所说的任何内容时,它可能会崩溃。如果是这样,我可以为容器和 JVM 使用的最佳值是什么?

现在我为 Amazon linux 本身留了 1GB 的空间,为在容器中运行的 CentOS 留了 512MB。 1.5GBwasted。能不能做得更好?

【问题讨论】:

【参考方案1】:

真正的答案很大程度上取决于您的 Java 应用程序和使用情况。

从 3.5G 的 JVM 堆开始。 将容器最大值设置为 3.8G 以覆盖 javas 开销。 负载测试,反复。

Java

-Xmx-Xms 仅控制Java's heap size,因此您不能将所有可用内存分配给Java 的堆并期望Java 和系统的其余部分运行良好(或根本不运行)。

您还需要满足:

堆栈:-Xss * 线程数(Xss 在 64 位上默认为 1MB)

PermGen/Metaspace:-XX:MaxPermSize 默认为 64MB。元空间到 21MB,但这可以增长。

您的应用还可以使用大量共享内存、在堆外执行 JNI 操作、依赖大型 mmaped 文件来提高性能或 exec 外部二进制文件或堆外任何数量的其他怪事。在您选择的内存级别进行一些负载测试,然后在这些级别之上和之下进行一些负载测试,以确保您没有遇到或接近任何影响性能的内存问题。

容器

Centos 不会像这样在容器中“运行”,docker 只是提供一个文件系统映像供您的 JVM 进程参考。通常,您不会“运行”该容器中的java 进程。

当您在只有一个容器的专用主机上时,限制容器的最大内存并没有太大的好处,但它也没有什么坏处,以防本机 java 中的某些东西耗尽可用内存。

这里的内存开销需要满足上面提到的可能的本机 Java 使用以及将从容器映像(而不是主机)加载并缓存的 jre 的额外系统文件。当你达到容器内存限制时,你也不会得到一个好的堆栈或堆转储。

操作系统

一个普通的 Amazon AMI 只需要大约 50-60MB 的内存来运行,外加一些备用的文件缓存,所以说 256MB 来为操作系统提供一些余地。

【讨论】:

以上是关于AWS beanstalk 中 docker 容器中的 JVM 内存设置的主要内容,如果未能解决你的问题,请参考以下文章

AWS beanstalk 中 docker 容器中的 JVM 内存设置

使用 Dockerrun.aws.json 和 Elastic Beanstalk 命名 Docker 容器

AWS Elastic Beanstalk Docker 环境变量

AWS Elastic Beanstalk - 多容器 Docker

AWS Elastic Beanstalk 上的 Docker - 无法从容器访问环境变量

如何在 AWS Elastic Beanstalk Docker 容器中记录 PHP 错误