第4章 网络配置与依赖管理:自定义网络、依赖启动顺序(depends_on)、健康检查(healthcheck)
4.1 原理概述
在 Compose 编排中,服务之间的网络连通性、启动顺序以及运行状态监测是决定测试环境稳定性的关键因素。自定义网络(Custom Network)让同组服务在隔离的虚拟子网中通信;depends_on 控制服务间的启动先后;健康检查(healthcheck)则确保上游服务在实际就绪后才被下游依赖。
- 自定义网络:Docker 创建独立 bridge 网络,服务通过容器名直接解析,无需依赖
links。 - depends_on:定义容器之间的依赖顺序,支持
condition: service_started(默认)、service_healthy、service_completed_successfully。 - healthcheck:在
docker-compose.yml中通过test、interval、timeout、retries等字段定义容器健康检测逻辑。
核心要点:仅使用
depends_on 而不配合健康检查,容器可能在进程启动但端口未就绪时就被下游连接,导致连接失败。推荐组合使用 depends_on: condition: service_healthy 与对应服务的健康检查。
4.2 依赖关系与流程
下图展示典型三层测试环境中的网络、启动顺序与健康检查关系:API 服务等待数据库健康,Web 前端等待 API 健康,服务通过两个自定义网络通信。
4.3 实现流程与配置
4.3.1 自定义网络配置
在 docker-compose.yml 的 networks 顶级键下定义,然后在每个 service 的 networks 字段引用。
version: '3.8'
networks:
net-front:
driver: bridge
net-backend:
driver: bridge
net-db:
driver: bridge
4.3.2 依赖启动顺序与健康检查组合
以下配置演示数据库、API、前端三层服务的完整依赖与健康检查设置:
services:
db:
image: postgres:15-alpine
networks:
- net-db
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
api:
image: my-api:latest
depends_on:
db:
condition: service_healthy
networks:
- net-backend
- net-db
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 15s
timeout: 3s
retries: 3
web:
image: my-web:latest
depends_on:
api:
condition: service_healthy
networks:
- net-front
- net-backend
ports:
- "80:80"
注意:
depends_on 只是容器启动顺序,不是服务就绪顺序。必须配合 healthcheck 的 condition: service_healthy 才能实际等待端口可用。另外,自定义网络名称不要与系统预留网络名(如 host、none、default)冲突。
4.4 调试与验证
4.4.1 检查网络与容器连接
使用以下命令验证自定义网络和容器连通性:
# 列出所有网络
docker network ls
# 检查某个网络下连接的容器
docker network inspect net-backend
# 进入容器测试解析
docker exec -it api-container ping db-container
# 查看容器健康状态
docker inspect --format='{{.State.Health.Status}}' api-container
4.4.2 查看启动日志中的依赖等待
Compose 在启动时会输出类似以下日志,说明等待上游服务健康:
api | Waiting for db to be healthy (condition: service_healthy)...
db | PostgreSQL init process complete; ready for start up.
api | db is healthy. Starting service...
web | Waiting for api to be healthy...
api | Healthcheck succeeded: HTTP 200 /health
web | api is healthy. Starting nginx...
4.5 常见错误及解决
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
| 服务启动后下游立即连接失败 | 仅使用 depends_on 未加健康条件 |
改为 condition: service_healthy 并定义 healthcheck |
| 健康检查一直失败,服务卡住 | 健康检查命令错误或端口不对 | 在容器内手动执行 pg_isready 或 curl 验证命令 |
| 容器之间无法通过服务名访问 | 未加入同一自定义网络 | 检查 service 的 networks 列表,确保依赖双方在同一网络 |
| 网络重叠导致 DNS 解析混乱 | 多个网络中有同名服务 | 使用唯一服务名,或借助别名 aliases 区分 |
4.6 性能与稳定性优化建议
- 合理设置健康检查间隔:
interval不宜过短(<10s),避免占用过多 CPU;数据库类服务可适当延长至 15-30s。 - 使用
restart: unless-stopped:配合健康检查,当容器不健康但未退出时,Docker 不会自动重启,需结合restart策略确保服务恢复。 - 网络细化隔离:仅将必要服务加入同一网络,减少广播域和安全风险。
- 避免循环依赖:
depends_on不能形成环,Compose 会报错启动失败。 - 利用
start_period:在 healthcheck 中设置start_period: 30s,给容器初始化时间,避免启动初期的误判。
生产实践建议:在测试环境配置中,建议将健康检查与
condition: service_healthy 作为标准写法,避免偶发性连接失败导致测试不稳定。同时,在 CI/CD 中可通过 docker compose up --wait(需 Compose v2)等待所有服务达到健康状态后再执行测试用例。