问题的产生
我使用docker-compose 编写了一个脚本,包括了mysql、redis、spring boot server。但是由于mysql 数据量大了后启动会变慢,导致sprong boot server 启动失败
即使使用了 depends_on 这个配置也无效,因为这个配置只能保证容器的启动顺序,但是在mysql容器启动了但是服务还未启动,因此出现了这个问题。
解决问题
你赶时间的话请直接采用我的最终解,将你的 docker-compose,中的镜像和命令修改一下
- image:一个包含了监听其他端口脚本的镜像
- entrypoint: 等待mysql与redis启动后 执行 -c 后的命令
my_server:
image: sunbrightness/jdk-wait_run:8
container_name: my_server
ports:
- 8080:8080
environment:
- LANG=C.UTF-8
- TZ=Asia/Shanghai
volumes:
# 配置文件
- ./server/:/home/java/
privileged: true
entrypoint: 'wait_run -d my_mysql:3306,my_redis:6379 -c "java -jar admin.jar"'
restart: always
depends_on:
- km_mysql
- km_redis
问题细节
编写一个sh 脚本
利用 linux 中的 netcat 工具监听端口,在端口启动后运行spring boot server
touch wait_run
chmod +x wait_run
vim wait_run
#!/bin/bash
#set -x
: ${SLEEP_SECOND:=2}
wait_for() {
echo Waiting for $1 to listen on $2...
while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
}
declare DEPENDS
declare CMD
while getopts "d:c:" arg
do
case $arg in
d)
DEPENDS=$OPTARG
;;
c)
CMD=$OPTARG
;;
?)
echo "unkonw argument"
exit 1
;;
esac
done
for var in ${DEPENDS//,/ }
do
host=${var%:*}
port=${var#*:}
wait_for $host $port
done
eval $CMD
这样你就可以通过如下命令,等待多个端口启动后再执行你的命令
/bin/bash wait_run -d 127.0.0.1:3306,127.0.0.1:6379 -c "java -jar admin.jar"
注意 jdk的docker容器不包含这个命令 nc
因此我们需要自定义一个Dockerfile 文件,让其安装好 netcat
# 基础镜像
FROM openjdk:8
# author
MAINTAINER sunbrightness
# 挂载目录
VOLUME /home/java
# 创建目录
RUN mkdir -p /home/java
# 指定路径
WORKDIR /home/java
# fix apt update error
RUN echo "deb https://mirrors.bfsu.edu.cn/debian/ bullseye main contrib non-free" > /etc/apt/sources.list
RUN apt-get update
# 安装netcat用于监听端口启动
RUN apt-get -y install netcat
# 将刚刚创建的nc命令移动到镜像中
COPY ./wait_run /bin
RUN chmod +x /bin/wait_run
这个便是我在最上文提到的sunbrightness/jdk-wait_run:8 镜像了。
花了好长时间才搞好的。也知道了java8的docker镜像是基于Debian 11 系统的