关于java:JDK11设置Docker容器资源感知

一、背景

对于Java8的一些较早的版本(8u131以前?),如果部署在docker容器中,因为JVM不能感知到docker容器的资源限度,会导致docker编排文件中设置的资源限度对JVM有效。轻则多个docker容器抢占资源导致性能降落,重则docker容器不稳固频频重启。

在Java8 8u131+和JDK9当前,JVM减少了感知容器资源的参数,解决了这个问题。

本文以JDK11为例,阐明如何设置java利用的容器感知参数,以及如何在docker编排文件中设置容器资源限度。

二、环境

  • java: AdoptOpenJDK 11.0.8+10
  • docker ce: 19.03.4
  • docker-compose: 1.24.0

三、Java利用相干设置

制作一个基于openjdk11的java利用镜像。

3.1 Java根底镜像

本文基于AdoptOpenJDK的openjdk11镜像 adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine制作了中国时区,反对中文的openjdk11镜像。

Dockerfile如下:

# 从dockerhub拉取根底镜像
FROM adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine

# 设置时区与语言环境变量
ENV TIME_ZONE=Asia/Shanghai \
        LANG=en_US.UTF-8 \
        LANGUAGE=en_US.UTF-8 \
        LC_ALL=en_US.UTF-8

# 执行以下命令设置时区
RUN apk add --no-cache tzdata \
  && echo "${TIME_ZONE}" > /etc/timezone \
  && ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime

在Dockerfile所在目录执行docker镜像编译命令:docker build -t <自定义镜像名>:<tag> ., 如:

docker build -t czhao/base-openjdk11:jdk-11.0.8_001 .

3.2 Java利用

当时筹备一个openjdk11开发的java利用,编译为jar,基于后面的Java根底镜像,编译java利用镜像。

Dockerfile如下:

FROM czhao/base-openjdk11:jdk-11.0.8_001

# JDK11反对: -XX:+UseContainerSupport 使JVM可能感知容器资源, -XX:InitialRAMPercentage 初期容器内存占比, -XX:MaxRAMPercentage 最大容器内存占比
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:InitialRAMPercentage=50 -XX:MaxRAMPercentage=80"

# 复制上下文目录下的target/*.jar 到容器里
ADD target/*.jar app.jar

# 指定容器启动程序及参数   <ENTRYPOINT> "<CMD>"
ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar
  1. -XX:+UseContainerSupport开启容器感知。
  2. -XX:InitialRAMPercentage-XX:MaxRAMPercentage用于设置JVM初始的容器内存占比和最大容器内存占比。
  3. 上述命令仅在java10当前无效,其余反对感知的版本的参数配置各不相同。
  4. 镜像编译命令不再赘述。

四、docker编排与启动

编排java利用的docker compose文件,启动,并查看资源占用。

4.1 docker编排文件

这里应用docker compose v3的编排规定,编排文件如下:

service.yaml:

version: '3'

...

services:
  <java利用名>:
    container_name: <java利用名>
    image: <java利用镜像名>:<java利用镜像标签>
    ...
    deploy:
      resources:
        limits:
          cpus: '1.00'
          memory: 1024M
        reservations:
          # cpus: '0.1'
          memory: 512M
  1. deploy原本是docker swarm的docker stack deploy命令才反对的属性,但能够在docker-compose up命令中通过增加--compatibility参数使之失效。但deploy.resources.reservations.cpus依然无奈失效。
  2. limits是资源下限,reservations是保留资源。
  3. cpus设置的数字是占用宿主机cpu的比例,1.00100%,代表齐全占用了宿主机CPU的一个process。留神,宿主机如果是多核机器的话,100%只是占用了一个process而已。例如一个8 core 16 process的宿主机,cpus实践上能够设置到16.00。但这里倡议一个容器的cpu占用不要超过1.00

4.2 启动docker容器并查看资源占用

应用以下命令启动:

docker-compose --compatibility -f service.yaml up -d

而后应用以下命令,查看docker容器的资源占用状况:

docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"

docker资源占用如下:

NAME                CPU %               MEM USAGE / LIMIT
<java利用名>         0.66%               418.5MiB / 1GiB

留神察看就能够发现,该容器占用CPU最高在100%左右,而内存则不会超过1G的限度。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理