1. Docker Compose 中的 depends_on 和健康检查有什么区别?
考察点:Docker Compose
参考答案:
depends_on 只保证容器按顺序启动,不保证服务真正可用。
services:
app:
depends_on:
- mysql # 只保证 mysql 容器先启动
因此会存在这样一个问题,比如说 MySQL 容器启动了,但数据库可能还没初始化完,另外一个需要连接 MySQL 的服务可能就会启动失败。
于是就需要做健康检查,这样才能保证服务真正可用:
services:
mysql:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
app:
depends_on:
mysql:
condition: service_healthy # 等 MySQL 健康检查通过才启动
换句话说,我们在启动工作流引擎服务的时候,会通过 depends_on 依赖 MySQL 和 MySQL,并通过健康检查确保 MySQL 和 Redis 已经准备好连接再启动 workflow 服务。
mysql:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot123"]
interval: 10s
timeout: 5s
retries: 10
core-workflow:
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
参考答案版本 2:
depends_on 解决的是启动顺序的问题。我们告诉 Docker 说后端服务依赖 MySQL,Docker 就会保证先启动 MySQL 容器,再启动后端容器。但这里有个坑就是:Docker 只保证容器"启动了",不保证容器"准备好了"。
也就是说,MySQL 容器启动需要时间,进程起来了不代表数据库就能接受连接了。可能 MySQL 还在初始化数据目录、执行启动脚本,这时候后端容器已经跑起来了,一连数据库发现连不上就报错了。depends_on 管不了这个,它只看容器进程有没有起来。
健康检查解决的是"服务真正可用"的问题。我们可以给 MySQL 容器配一个 healthcheck,比如每隔几秒执行一次 mysqladmin ping,能 ping 通说明数据库真的准备好了,这时候容器状态才会变成 healthy。
两者配合使用才是完美的解决方案。Compose 里可以这样写:
services:
mysql:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 10
backend:
depends_on:
mysql:
condition: service_healthy
关键是 condition: service_healthy 这个配置。加上它之后,Docker 不再是看 MySQL 容器起来就放行,而是要等 MySQL 的健康检查通过了才启动后端。这样后端起来的时候,数据库一定是能连上的。
真诚点赞 诚不我欺
回复