容器生命周期是受内核驱动的动态状态流转系统,核心锚点为PID 1进程;需用exec启动主进程或tini,健康检查应验证PID 1是否存活及业务就绪,depends_on须配合service_healthy,网络就绪需重试机制。
核心在于理解容器生命周期不是静态开关,而是一套受内核机制驱动的动态状态流转系统。docker 容器本质是被 namespace 隔离、被 cgroups 限制的特殊进程,其“运行中”“已退出”“重启中”等状态并非 docker 引擎主观标记,而是对底层 linux 进程状态(如 pid 1 是否存活、cgroup 中任务是否被冻结)的实时映射。
抓住 PID 1 进程这个状态锚点
每个容器内 PID 1 进程是整个容器生命周期的守门人。它一旦异常终止,内核会直接回收该 Namespace 下所有进程,容器随即进入 exited 状态——这和传统虚拟机或服务进程完全不同。
- 避免在容器中用 shell 脚本作为入口,shell 往往不是真正的 PID 1,容易因子进程退出而误判容器健康
- 推荐使用 exec 形式启动主进程,例如
exec node server.js或使用 tini 作为 init 进程,接管信号与僵尸进程 - 在健康检查中,不要只查端口是否通,要确认 PID 1 进程是否仍在运行且未卡死
用状态机视角重读 depends_on 和健康检查
Docker Compose 的 depends_on 默认只检查容器是否“已创建并启动”,并不等待应用就绪。这在高并发场景下极易引发雪崩:Web 容器刚启动就去连尚未初始化完成的数据库,连接失败后反复重试打垮下游。
-
depends_on应配合condition: service_healthy使用,强制等待目标服务通过自定义健康检查 - 健康检查命令需真实反映业务就绪态,例如对数据库执行
pg_isready -U postgres -d myapp,而非仅curl -f http://db:5432 - 为关键服务设置合理的
start_period和retries,避免冷启动阶段误判为故障
基于状态反馈做弹性编排决策
高并发系统不能只依赖预设拓扑,而应让编排逻辑感知容器真实状态变化,并触发对应动作。
- 利用 Docker Events 或 Swarm/K8s 的 Watch API 监听
container die、container health_status: unhealthy等事件 - 当检测到某类服务(如 LangGraph Agent)连续 3 次在 30 秒内重启,自动触发降级策略:将流量切至缓存层或返回兜底响应
- 结合 cgroups 实时指标(如
memory.usage_in_bytes、cpu.stat),在容器进入throttled状态前主动扩容副本,而非等 OOM Killer 杀死进程
网络就绪也是状态机的一环
容器启动成功 ≠ 网络可通信。bridge 网络中 DNS 解析、ARP 表填充、iptables 规则生效都有微小延迟,尤其在多容器密集启动时。
- 不要假设容器启动后立刻能通过服务名 ping 通;在应用代码中实现带退避的连接重试(如指数退避)
- 使用自定义 bridge 网络时,可通过
docker network inspect查看容器是否已加入网络并分配 IP,作为“网络就绪”的判断依据 - 对强依赖链(如 frontend → backend → db),可在 backend 启动脚本中循环检查 db 服务名解析是否成功,再启动服务进程


















