字节流的博客

Tomcat Docker 容器自动重启问题排查

Tomcat

1. 问题

前两天发现 APP 刷新数据偶尔出现等半天没有响应的情况,感觉不像 APP 的问题,就查了下服务端的日志。
服务端用的是 Java,部署采用的 Docker 官方的 tomcat 镜像,并进行了基本的裁剪,Dockerfile 文件内容如下:

1
2
3
4
5
FROM tomcat:8.0.36-jre8
MAINTAINER blog.smoker.cc@gmail.com
RUN rm -rf /usr/local/tomcat/webapps && mkdir /usr/local/tomcat/webapps
RUN echo "Asia/shanghai" > /etc/timezone;
ADD build/libs/project-name.war /usr/local/tomcat/webapps/ROOT.war

2. 排查

通过 docker logs 命令查看容器日志,发现一直出现 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 13216 ms
相关日志,说明 Tomcat 经常不断的重启。

然后 docker ps 发现应用容器的 CREATEDSTATUS 时间对不上。说明是容器一直会出现重启现象,导致上面查看到日志误以为 Tomcat 不断重启。

之前因为 Java 应用占用太多的内存😢,在其 docker-compose 加了 mem_limit: 1G 1G 内存限制的配置,所以有可能是内存不够的原因才导致的容器不断重启。

执行 `docker inspect --format='{{.State.OOMKilled}}' container-name` 命令,返回 `true`,说明容器因为 OOM 的问题被 killed 掉过。而我们的 `docker-compose` 配置的 `restart: always` 又导致容器自动重启。所以,容器会不断的被 kill,然后又 restart。

3. 解决

既然清楚了容器不断重启是因为内存不够的原因,所以还是要限制内存。而在 docker-compose 文件中的内存限制,只是对容器的内存的限制,JVM 还是会一直吃内存,导致容器内存不够被 kill,所以还要加上对 JVM 内存的限制。

Dockerfile 中添加 ENV JAVA_OPTS="-Xmx512m" JVM 内存限制即可。完整的 Dockerfile 如下:

1
2
3
4
5
6
FROM tomcat:8.0.36-jre8
MAINTAINER blog.smoker.cc@gmail.com
ENV JAVA_OPTS="-Xmx512m
RUN rm -rf /usr/local/tomcat/webapps && mkdir /usr/local/tomcat/webapps
RUN echo "Asia/shanghai" > /etc/timezone;
ADD build/libs/project-name.war /usr/local/tomcat/webapps/ROOT.war

重新构建镜像,启动容器,查看日志:

1
INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Xmx512m

出现上述内容,说明添加 JVM 内存限制配置生效,Tomcat 容器自动重启问题解决。😓

Thanks! 😊