运维开发网

理解docker部署springboot-容器内存优化的反思(五)

运维开发网 https://www.qedev.com 2020-05-07 10:42 出处:网络 作者:运维开发网整理
写这篇博客的目的可能反思多一些,前些日子一直想做docker内存的优化,没有做成,一直困在这地方。经过大致这样,我把jar和jdk做成一个镜像之后,一个镜像占用内存大概181.8M,我虚机是2G的内存,除了其他程序占用的之外,我就只能启动5个镜像,然后内存就没了,但是我们在大部分讲docker优点(原文)的地方都可以看到这个表格 特性 容器 虚拟机 启动 秒级 分钟级 硬盘使用 一般为 MB 一般
写这篇博客的目的可能反思多一些,前些日子一直想做docker内存的优化,没有做成,一直困在这地方。经过大致这样,我把jar和jdk做成一个镜像之后,一个镜像占用内存大概181.8M,我虚机是2G的内存,除了其他程序占用的之外,我就只能启动5个镜像,然后内存就没了,但是我们在大部分讲docker优点(原文)的地方都可以看到这个表格

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个
其中最后一项说项目部署由虚机的几十个变成容器的近千个,但是根据我实践的情况来讲这完全不可能啊,so,我的思路是我这个做镜像的方式存在问题,不应该把内存占用超过167M的jdk(我用的是网易蜂巢)打包到每一个镜像中,而应该拆出来,然后就开始了我的花费大量实践的探索之路。虽然现在看来这种思路可能有问题,但是这个过程还是要记录一下的,首先用top去分析内存:

[root@iZwz9cps5bpzjurg8m4ax0Z springboot-docker-test]# top -c
top - 16:08:02 up 27 days, 6 min,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 142 total,   3 running, 130 sleeping,   2 stopped,   7 zombie
Cpu(s):  0.7%us,  0.0%sy,  0.0%ni, 99.0%id,  0.3%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2054828k total,  1988716k used,    66112k free,    11800k buffers
Swap:        0k total,        0k used,        0k free,   338960k cached
再看看占用大户都有谁,发现大部分都被jdk吃了

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 5418 root      20   0  100m 4468 3448 S  0.3  0.2   0:00.79 sshd
 8619 root      20   0 2501m 173m 5516 S  0.3  8.7  23:59.20 java
16133 root      20   0  136m 7664 2820 S  0.3  0.4  14:33.93 AliYunDun
27526 root      20   0  920m  35m 7860 S  0.3  1.8   0:56.58 docker
30089 root      20   0 2397m 152m 7048 S  0.3  7.6   1:30.27 java
30318 root      20   0 2396m 145m 6804 S  0.3  7.3   1:29.71 java
下边是运行容器的情况

[root@iZwz9cps5bpzjurg8m4ax0Z ~]# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                    NAMES
c9a5e263b5e7        txxs/springbootdocker:1.1   "java -jar /app.jar"     7 days ago          Up 7 days           0.0.0.0:8087->8080/tcp   cranky_kalam
1b962162184d        centos                      "/bin/bash"              7 days ago          Up 7 days                                    logs
b4697ffe4dc2        txxs/springbootdocker:1.1   "java -jar /app.jar"     7 days ago          Up 7 days           0.0.0.0:8085->8080/tcp   nostalgic_mcnulty
91f942bad2a3        txxs/springbootdocker:1.1   "java -jar /app.jar"     7 days ago          Up 7 days           0.0.0.0:8084->8080/tcp   loving_sinoussi
c55e17c2a024        txxs/springbootdocker:1.0   "java -jar /app.jar"     7 days ago          Up 7 days           0.0.0.0:8083->8080/tcp   evil_bhabha
91f92f6b3545        txxs/springbootdocker:1.0   "java -jar /app.jar"     7 days ago          Up 7 days           0.0.0.0:8082->8080/tcp   insane_mahavira
14a8a7b0df84        txxs/springbootdocker:1.0   "java -jar /app.jar"     7 days ago          Up 7 days           0.0.0.0:8081->8080/tcp   sleepy_liskov
812b841b5422        daocloud.io/mysql           "docker-entrypoint.sh"   4 weeks ago         Up 7 days           0.0.0.0:3308->3306/tcp   mysql-slave
33225198ecc3        daocloud.io/mysql           "docker-entrypoint.sh"   4 weeks ago         Up 7 days           0.0.0.0:3307->3306/tcp   mysql-master
将所有的springboot的Java项目删除完之后的内存占用情况为45.1%,说明6个springboot的应用占了51.7%的内存

[root@iZwz9cps5bpzjurg8m4ax0Z /]# top -c
top - 16:14:08 up 33 days, 12 min,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 105 total,   3 running,  95 sleeping,   0 stopped,   7 zombie
Cpu(s):  0.3%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2054828k total,   926004k used,  1128824k free,    54224k buffers
Swap:        0k total,        0k used,        0k free,   129484k cached
顺着这个思路下去自然就会想到把jdk拿出来做共享的jdk,而不是每个里边都有一个,这样应该会节省大量内存,毕竟一个项目的jar才不到20M。

第一种方式:共享虚机环境内自身的jdk,以busybox作为基础镜像,毕竟busybox1.2也才不到两M,jar+busybox一共也就22M多,先看dockerfile:

FROM busybox:latest
RUN mkdir /share
RUN mkdir /share/jdk
ENV JAVA_HOME /share/jdk
ENV PATH $JAVA_HOME/bin:$PATH
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ADD syway-0.0.1-SNAPSHOT.jar app.jar
CMD ["java","-jar","/app.jar"]
构建启动执行以下命令:

docker build -t txxs/springbootdocker:1.2 .
docker run -d -v /jcommon/compile/jdk8/jdk1.8.0_131/:/share/jdk -p 8081:8080  txxs/springbootdocker:1.2  
镜像构建完成之后可以通过docker inspect imageID 查看images内的环境变量

        "Env": [
            "PATH=/share/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "JAVA_HOME=/share/jdk",
            "CLASSPATH=.:/share/jdk/lib/dt.jar:/share/jdk/lib/tools.jar"
        ],
启动容器失败,为啥呢,没法执行Java命令,想想也是做的镜像只有一个jar和busybox,不知道Java命令是啥,那就

第二种方式:

第二种方式,这是在 Stackoverflow 上看到了方案。首先看下边的镜像文件,我去,竟然用了Linux作为环境,这当然可以运行Java环境了,但是比网易蜂巢的jdk还要大,还怎么优化,试了试放弃了

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-Linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
  && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
  && grep " node-v$NODE_VERSION-Linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
  && tar -xJf "node-v$NODE_VERSION-Linux-x64.tar.xz" -C /usr/local --strip-components=1 \
  && rm "node-v$NODE_VERSION-Linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
  && ln -s /usr/local/bin/node /usr/local/bin/nodejs
还试了一些其他方案,但是都没有成功,在Google、bing、百度各种找也没找着现成的方式,我觉得应该还是还是可以解决的,我也没有深入研究这块,如果有哪位大神知道可以提供一下方案。但是这个思路是对的吗,直到我到下边这两个图

理解docker部署springboot-容器内存优化的反思(五)

左图是老的方式,新图是新的方式,豁然开朗,jdk就是libraries,如何共享,显然在新的方式是不可以的,如果这么做了一致的运行环境,持续的部署和更轻松的迁移恐怕都没有办法做到,这可能就是固化思维吧,有时候解决不了的问题可以清空一下脑袋,换个方式去想问题没准就会有不同的天地吧。但是既然这种方式不可以,那么怎么去解决内存占用问题,我觉得还是应该有方案的,还是当行太浅啊,有知道的大神一定在评论里提供一下
0

精彩评论

暂无评论...
验证码 换一张
取 消