docker compose保证服务依赖服务启动
最近在开发一款小型游戏的服务端,目前基本完成开发了,就打算把它们部署到服务器上面。最终选择的方案是使用docker来完成,这个这过程中对我这个docker新人来说遇到了很多问题,当然也学习和成长了很多。今天来说的如何来保证docker中服务的启动顺序问题。
Issue
例如我现在有个和数据交互的db服务,依赖数据服务mysql_db。我使用docker工具是docker-compose,使用其中的depends_on来想解决问题。
db:
build: ./db
volumes:
- /host/path/:/data/log/
command: /cmd
depends_on:
- mysql_db
expose:
- "10050"
是的,这样的配置可以保证db服务会在mysql_db服务启动以后再启动,一定程度来说如果mysql_db能立马完成启动,并准备好对外服务,那么就没有什么问题了。可是不得不面对的一个问题是,mysql_db启动是一个比较耗时的服务,当db服务启动时mysql_db其实还是在服务的启动过程中,并没有准备好来接受db的数据库连接,这样一来就导致了db服务的异常,进而导致所有依赖db服务都会异常。
Solution
docker-compose目前貌似并没有相应的配置参数来解决类似的问题,在google中找到了一个局限性的替代方案,使用entrypoint.sh脚本。在脚本中增加判断依赖服务是否已经准备完毕的判断,如果没有启动就一直等待,直到依赖服务启动以后,再启动脚本。他这里使用nc命令,对于没有nc命令的镜像就需要自己想办法来解决了。例如可以使用golang中的net.Dial来写个尝试连接的工具,当然其他语言类似的库也可以。
#!/bin/sh
#set -x
: ${SLEEP_SECOND:=1}
# 等待服务启动
wait_for() {
echo Waiting for $1 to listen on $2...
while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
}
wait_for mysql_db 3306
/go/bin/db --config /data/etc/config.json
Dockerfile修改
...
ADD entrypoint.sh /data/script/entrypoint.sh
...
docker-compose.yml修改
db:
build: ./db
volumes:
...
command: /data/script/entrypoint.sh
depends_on:
- mysql_db
expose:
- "10050"
至此就可以明确保证我们db服务会在mysql_db准备好以后再来进行启动。
近期评论