
类型:虚拟化技术
简介:基于操作系统层级的虚拟化技术,将软件与其依赖项打包为容器。
多容器应用最常见的问题之一,是应用容器启动太快,而数据库、缓存或消息队列还没准备好。容器进程已经运行,不代表服务已经可以连接。Docker 中管理启动顺序,不能只看容器是否启动,还要关注服务是否真正就绪。
一、启动顺序和服务就绪不是一回事
depends_on 可以声明服务之间的依赖关系,但它并不等于业务服务已经准备好。例如数据库容器进程启动后,还需要初始化、加载数据和开放连接端口。
常见现象:
- Web 容器先启动,连接数据库失败。
- Redis 容器运行中,但应用仍报连接超时。
- 初始化脚本未完成,业务服务就开始访问。
- 重启后偶发失败,手动再启动又正常。
这些问题通常和服务就绪判断有关。
二、使用 depends_on 管理基础顺序
Compose 中可以这样写:
services: web: image: example-web depends_on: - db db: image: mysql:8
这能保证 db 先于 web 启动,但不能保证 MySQL 已经可以接受连接。简单应用可以使用,复杂应用还需要健康检查或等待脚本。
三、加入健康检查
健康检查可以让容器状态更接近真实可用状态。
示例:
services: db: image: mysql:8 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5
健康检查应使用能证明服务可用的命令,而不是只检查进程是否存在。
四、使用等待脚本处理应用启动
应用容器可以在启动前等待依赖服务端口或接口可用。
示例思路:
#!/bin/sh until nc -z db 3306; do echo "waiting for database..." sleep 2 done exec npm start
等待脚本适合处理数据库、缓存、消息队列等依赖。注意不要无限等待,生产环境应设置超时或失败退出。
五、排查启动失败
排查顺序:
- 查看容器启动日志。
- 检查依赖服务是否运行。
- 检查端口是否可连接。
- 检查账号、密码、数据库名是否正确。
- 检查健康检查是否持续失败。
- 检查应用是否过早退出。
常用命令:
docker compose ps docker compose logs web docker compose logs db
FAQ
问:depends_on 能保证数据库就绪吗?
不能。它主要控制启动顺序,不保证数据库已经可以连接。
问:健康检查应该检查什么?
应检查服务真实可用状态,例如数据库 ping、HTTP 接口返回或端口连接。
问:等待脚本要不要设置超时?
建议设置,避免依赖服务异常时应用容器无限等待。

