宁语之溪
寻寻觅觅,冷冷清清,凄凄惨惨戚戚。 (宋·李清照·声声慢)
自豪地使用 Typecho 建站搭配使用 🌻Sunny 主题博主 昨天 13:54 在线 · 当前 40 人活跃
文章

Docker Compose 如何编排一套微服务系统

语之溪

·

容器与部署

·

⚠️ 本文最后更新于2026年02月28日,已经过了177天没有更新,若内容或图片失效,请留言反馈

一套微服务系统不只有业务服务,还包括数据库、缓存、注册中心、对象存储、消息队列和监控组件。手工逐个启动容易遗漏配置,也很难保证其他环境按照同样方式复现。

在 HAOVP 的开发和单机部署中,我使用 Docker Compose 描述服务、网络、数据卷、环境变量和启动依赖。Compose 的价值是让一组容器可以统一启动和管理,但单机编排本身不等于高可用集群。

Compose 文件描述什么

一个 Compose 文件通常包含:

services
networks
volumes
configs 或 secrets(按实际环境)

services 定义容器;networks 定义容器间通信;volumes 保存持久化数据;配置和秘密则需要通过受控方式提供。

一个简化示例:

services:
  gateway:
    image: example/gateway:latest
    env_file:
      - .env
    networks:
      - app-network
    depends_on:
      registry:
        condition: service_healthy

networks:
  app-network:
    driver: bridge

镜像名、文件名和服务名均为通用示例,不对应真实部署配置。

先区分基础设施和业务服务

我会把服务按职责整理:

  • 数据库和缓存;
  • 注册中心与配置中心;
  • 对象存储和消息队列;
  • 网关;
  • 认证、用户、内容、评论、推荐和管理服务;
  • 用户端与管理端;
  • 监控和日志组件。

分组不一定要拆成多个文件,但需要看清依赖关系。基础设施没有就绪时,业务服务即使进程启动,也可能立即连接失败。

depends_on 不保证业务可用

Compose 的 depends_on 可以控制启动顺序,配合健康检查等待依赖达到健康状态。

healthcheck:
  test: ["CMD", "sh", "-c", "check-command"]
  interval: 10s
  timeout: 5s
  retries: 10

这是结构示例。健康检查命令应针对实际组件设计,不公开真实账号和地址。

容器状态为 running 不等于服务可用;健康检查通过也不等于完整业务链路可用。业务服务仍需要重试、超时和明确的启动失败日志。

容器间通过服务名通信

同一 Compose 网络中的服务可以使用服务名访问彼此,不需要写死容器 IP。

业务服务 -> mysql-service
业务服务 -> redis-service
Gateway -> registry-service

容器 IP 可能随重建变化,服务名更稳定。对外暴露端口与容器内部端口也要区分:容器间通信通常使用内部端口,只有真正需要从宿主机访问的服务才映射端口。

公开文档不应包含真实宿主机地址、内部域名和生产端口表。

环境变量和秘密分开处理

Compose 文件可以引用环境变量,但不能把密码和密钥直接提交到仓库。

environment:
  DB_HOST: ${DB_HOST}
  DB_NAME: ${DB_NAME}
  DB_PASSWORD: ${DB_PASSWORD}

变量名称可以进入文档,真实值不能进入公开文件、镜像层和启动日志。

我会检查:

  • .env 是否被版本控制忽略;
  • 示例文件是否只包含占位值;
  • 容器日志是否打印完整环境;
  • 默认密码是否已替换;
  • 不同环境是否使用独立配置;
  • Secret 更新后如何重启和验证。

数据卷决定数据是否保留

数据库、Redis 持久化、Nacos 数据和 MinIO 对象不能只依赖容器可写层。容器删除后,可写层也会消失。

volumes:
  mysql-data:
  object-data:

数据卷还需要考虑:

  • 备份与恢复;
  • 权限;
  • 磁盘容量;
  • 升级兼容性;
  • 错误挂载;
  • 删除 Compose 项目时是否保留。

docker compose down -v 会删除声明的数据卷,不能在不确认数据范围时执行。

镜像要可追踪

长期使用 latest 会让同一 Compose 文件在不同时间拉到不同镜像,不利于复现。

更稳妥的方式是使用明确版本或镜像摘要,并记录:

  • 源代码版本;
  • 构建时间;
  • 镜像标签;
  • 配置版本;
  • 数据库迁移版本。

业务服务升级时,先确认数据库和接口兼容,再决定启动顺序和回滚方式。

服务启动顺序

一套简化顺序可以是:

网络与数据卷
    -> 数据库、缓存、对象存储、消息队列
    -> 注册与配置中心
    -> 业务服务
    -> 网关
    -> 前端与监控

实际启动可以并行,但依赖必须具备重试和健康检查。某个服务首次连接失败后直接退出,会让整个启动过程变得脆弱。

日志和可观测性

Compose 可以统一查看日志:

docker compose logs -f --tail=200 gateway

命令中的服务名是示例。

我会关注:

  • 日志是否带服务名和请求标识;
  • 是否限制日志大小和保留时间;
  • 错误日志能否定位依赖;
  • 是否泄露 Token、密码和连接信息;
  • 健康检查和应用指标是否可观察;
  • 宿主机磁盘是否会被日志占满。

只看到所有容器为绿色,不足以证明系统链路正常。

启动后的验证顺序

容器是否运行
    -> 健康检查是否通过
    -> 注册中心是否看到服务
    -> 网关路由是否可达
    -> 认证接口是否正常
    -> 核心业务链路是否能走通
    -> 异常与重启场景是否可恢复

我会使用脱敏测试账号和数据验证,不把真实凭据写进脚本或文档。

重启和故障场景

Compose 允许设置重启策略,但自动重启不等于问题已经解决。

需要测试:

  • 数据库晚于业务服务启动;
  • 单个服务重启;
  • 注册中心短暂不可用;
  • 对象存储或消息队列异常;
  • 宿主机重启;
  • 配置变更后重新创建容器;
  • 数据卷是否正确恢复。

重启策略如果配置不当,还可能让持续失败的容器进入快速重启循环,掩盖真正错误。

为什么单机 Compose 不是高可用集群

即使每个服务都在独立容器中,它们仍然运行在同一台宿主机上。宿主机、磁盘或网络出现问题时,所有容器可能同时不可用。

单机 Compose 能提供:

  • 环境一致性;
  • 服务隔离;
  • 统一启停;
  • 依赖编排;
  • 本地与演示部署便利性。

它不能自动提供:

  • 跨主机容灾;
  • 调度与自动迁移;
  • 真正的多副本负载均衡;
  • 存储高可用;
  • 自动故障切换。

要验证高可用,还需要多节点部署、外部负载入口、数据复制、监控和故障演练。

Docker Compose 编排微服务系统的核心,是把服务、网络、配置、数据卷和健康检查变成可复现的声明。它非常适合开发、联调和单机部署,但边界必须说清楚:容器化解决环境与编排问题,高可用仍然需要跨节点和数据层面的实际验证。

现在已有 8 次阅读,0 条评论,0 人点赞
评论:共0条
发表
搜索 消息 足迹 排行
你还不曾留言过..
你还不曾留下足迹..
博主 不再显示
博主
未知作品 歌曲封面
立即安装