使用 Docker 和 Fig 避免容器之间的竞争

注:该文作者是 Chmouel,原文是 Avoiding race conditions between containers with docker and fig

该文我主要是意译,详细的看原文吧。

使用 Docker 和 Fig 的时候,当我们启动多个容器的时候,比如一个 web 服务和一个 DB 服务,就有可能遇到竞争问题。正常来说,应该是 DB 先与 Web 服务启动,但是因为 DB 没有时间配置它自己,然后 web 服务已经启动了,这样就会造成 web 连接数据库失败。

理想中,app 应该等待 DB 已经设置好并且启动后才开始连接 DB。但是这不是一件容易的事情。

docker 和 fig 的开发者已经注意到这个问题,并且在开发版已经有一些建议了:

https://github.com/docker/docker/issues/7445

这个主意就是 docker 必须等待暴露的端口已经打开了并且 listening 是可用的才告诉容器已经启动。这不是容易做到的,因为 Docker 将很难弄清楚该端口是开放的。

这有个内建的 Python 解决方案。代码如下:

function check_up() {
    service=$1
    host=$2
    port=$3

    max=13 # 1 minute

    counter=1
    while true;do
        python -c "import socket;s = socket.socket(socket.AF_INET, socket.SOCK_STREAM);s.connect(('$host', $port))" >/dev/null 2>/dev/null && break || echo "Waiting that $service on ${host}:${port} is started (sleeping for 5)"

        if [[ ${counter} == ${max} ]];then
            echo "Could not connect to ${service} after some time"
            echo "Investigate locally the logs with fig logs"
            exit 1
        fi

        sleep 5

        (( counter++ ))
    done
}

在我 app 服务的 start.sh 脚本中,在启动我的 web 服务之前,我像这样使用它:

check_up "DB Server" ${DB_PORT_3306_TCP_ADDR} 3306

该方法的优势是它能非常快速的知道端口是否打开。

    原文作者:yexiaobai
    原文地址: https://segmentfault.com/a/1190000000762322
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞