docker swarm支持自动摘除不健康服务实例并重调度,而compose仅限本地观察;swarm需通过docker service create部署并声明健康检查,异常实例会被实时移出负载均衡池。
健康检查本身不摘除服务,必须靠编排工具识别状态并执行动作。docker compose 和 swarm 都能感知 unhealthy 状态,但行为不同:compose 主要用于单机开发测试,swarm 才真正支持自动摘除+重调度。
Swarm 模式下实现自动摘除流量
Swarm 会把 unhealthy 容器从 ingress 网络和负载均衡池中自动剔除,新请求不再路由过去,已建立连接可保持(取决于代理配置)。关键前提是:
- 服务必须用
docker service create部署,不是docker run - 健康检查需在 service 创建时声明,例如:
docker service create --health-cmd="curl -f http://localhost:3000/health || exit 1" --health-interval=30s --health-retries=3 --health-start-period=40s --publish 3000:3000 myapp - Swarm 默认每 30 秒检查一次健康状态,连续失败 3 次后标记为
unhealthy,立即从服务发现列表中移除
Compose 中无法自动摘除,但可配合外部机制
Docker Compose 本身没有服务发现或流量调度能力,unhealthy 状态仅用于本地观察和重启触发。若需“摘除”效果,常见做法是:
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
- 前端反向代理(如 Nginx、Traefik)主动探活:配置
health_check或upstream check,只将请求转发给healthy容器实例 - Traefik v2+ 可直接读取 Docker API 获取容器健康状态,动态更新路由
- 自建脚本轮询
docker inspect --format='{{.State.Health.Status}}',发现unhealthy后调用docker-compose down或调整网络别名
依赖服务就绪才是摘除前提
下游服务启动前,必须确保上游 DB、Cache 已真正 healthy,否则一上来就连接失败,可能反复崩溃。正确写法是:
- 在
docker-compose.yml中用depends_on的condition: service_healthy(仅 Compose v2.3+ 支持) - DB 服务自身健康检查必须真实有效,比如 PostgreSQL 用
pg_isready -q,而不是只测端口通不通 - 避免用
restart: unless-stopped—— 它不响应健康状态变化,无法实现故障隔离
验证是否生效的实操方法
摘除不是黑盒行为,可通过三步快速验证:
- 手动让健康接口返回 500 或超时,等 2 分钟观察容器状态:
docker ps看 STATUS 列是否出现Unhealthy - 查 Swarm 服务任务列表:
docker service ps <service-name></service-name>,确认unhealthy实例状态变为Rejected或Shutdown - 发请求测试:用
curl多次访问服务入口,确认失败请求比例下降,且日志里不再出现刚被摘除容器的 IP










