3. Docker Compose 编排:Compose 文件结构、服务定义与依赖、网络与卷的声明式配置

在微服务与缓存同步场景中,手动管理多个容器的启动顺序、网络互通与数据持久化几乎不可行。Docker Compose 通过声明式 YAML 文件,将多容器应用的定义、依赖、网络与卷统一编排,成为构建缓存一致性闭环的基础设施层。

3.1 Compose 文件结构:三级声明模型

Compose 文件遵循 版本 → 服务 → 基础设施 的三级结构。每个服务对应一个容器镜像及其运行时配置;顶层 networks 与 volumes 则定义共享网络与持久化存储。

层级 关键字 作用 缓存同步场景示例
版本声明 version 指定 Compose 文件格式版本(推荐 3.8+) version: "3.8"
服务定义 services 定义每个容器的镜像、端口、环境、依赖 redis-cache、app-server、sync-agent
基础设施 networks / volumes 声明自定义网络与持久化卷 cache-net、redis-data
关键原则:服务之间通过服务名(service name)进行 DNS 解析,无需硬编码 IP。这是实现缓存节点动态发现的前提。

3.2 服务定义与依赖控制

每个服务至少需要指定 image 或 build。在缓存一致性场景中,depends_on 控制启动顺序,healthcheck 确保上游服务就绪后再启动下游。

version: "3.8"

services:
  redis-cache:
    image: redis:7-alpine
    container_name: cache-primary
    ports:
      - "6379:6379"
    networks:
      - cache-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

  app-server:
    build: ./app
    container_name: app-node
    ports:
      - "8080:8080"
    depends_on:
      redis-cache:
        condition: service_healthy
    environment:
      - REDIS_HOST=redis-cache
      - REDIS_PORT=6379
    networks:
      - cache-net

  sync-agent:
    image: sync-agent:latest
    container_name: cache-sync
    depends_on:
      - redis-cache
    networks:
      - cache-net
    volumes:
      - sync-config:/etc/sync
依赖最佳实践:使用 condition: service_healthy 而非简单的 depends_on,避免因容器启动但服务未就绪导致的缓存连接失败。

3.3 网络声明式配置:隔离与互通

默认情况下,Compose 会为项目创建默认网络,所有服务加入同一网络。但在缓存同步场景中,通常需要 显式定义网络 以控制隔离粒度与子网规划。

networks:
  cache-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1

显式网络带来的三个核心能力:

  • 服务发现:服务名即主机名,Redis 客户端可通过 redis-cache:6379 访问。
  • 子网可控:避免与宿主机或其他项目 IP 冲突。
  • 多网络接入:一个服务可同时加入多个网络,实现缓存层与业务层分离。
Compose 网络拓扑:缓存服务依赖与网络隔离 cache-net (172.20.0.0/16) redis-cache 端口: 6379 健康检查: redis-cli ping app-server 端口: 8080 依赖: redis-cache (healthy) sync-agent 缓存同步代理 依赖: redis-cache ▶ 服务发现机制 app-server 通过服务名 redis-cache:6379 访问 Redis,无需硬编码 IP。 sync-agent 同样通过服务名订阅缓存变更事件,实现同步闭环。

3.4 卷的声明式配置:缓存持久化与配置共享

缓存数据需要持久化以防止重启丢失;同步代理的配置文件则需要挂载到多个服务。Compose 通过 volumes 顶层声明与服务内 volumes 挂载实现。

volumes:
  redis-data:
    driver: local
  sync-config:
    driver: local

services:
  redis-cache:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    command: ["redis-server", "--appendonly", "yes"]

  sync-agent:
    image: sync-agent:latest
    volumes:
      - sync-config:/etc/sync
      - ./sync-rules.yml:/etc/sync/rules.yml:ro
卷类型 声明位置 缓存场景用途 示例
命名卷 顶层 volumes Redis AOF/RDB 持久化 redis-data:/data
绑定挂载 服务内直接指定 配置文件热更新(同步规则) ./sync-rules.yml:/etc/sync/rules.yml:ro
匿名卷 仅服务内声明 临时缓存日志 /var/log/cache
卷权限陷阱:Redis 容器以 uid 999 运行,若绑定挂载的宿主机目录权限不足,会导致写入失败。建议使用命名卷或预先设置目录权限 chown 999:999 ./data。

3.5 完整编排示例:缓存同步闭环

将上述要素组合,形成可运行的缓存一致性闭环编排文件。该编排包含 Redis 主节点、业务应用与同步代理,三者通过同一网络通信,Redis 数据通过命名卷持久化。

version: "3.8"

services:
  redis-cache:
    image: redis:7-alpine
    container_name: cache-primary
    ports:
      - "6379:6379"
    networks:
      - cache-net
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3
    command: ["redis-server", "--appendonly", "yes", "--appendfsync", "everysec"]

  app-server:
    build: ./app
    container_name: app-node
    ports:
      - "8080:8080"
    depends_on:
      redis-cache:
        condition: service_healthy
    environment:
      - REDIS_HOST=redis-cache
      - REDIS_PORT=6379
      - CACHE_TTL=300
    networks:
      - cache-net

  sync-agent:
    image: sync-agent:latest
    container_name: cache-sync
    depends_on:
      - redis-cache
    networks:
      - cache-net
    volumes:
      - sync-config:/etc/sync
      - ./sync-rules.yml:/etc/sync/rules.yml:ro
    environment:
      - REDIS_SOURCE=redis-cache:6379
      - SYNC_INTERVAL=10

networks:
  cache-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

volumes:
  redis-data:
  sync-config:
声明式配置数据流:卷、网络与依赖关系 redis-cache 卷: redis-data → /data 网络: cache-net app-server 环境变量: REDIS_HOST 依赖: redis-cache (healthy) sync-agent 卷: sync-config → /etc/sync 绑定: sync-rules.yml redis-data 卷 AOF 持久化 sync-config 卷 同步规则 绑定挂载 sync-rules.yml ▶ 声明式配置优势 所有网络、卷、依赖关系在 YAML 中集中声明,启动时自动创建与挂载。 修改配置后执行 docker compose up -d 即可增量更新,无需手动管理容器生命周期。

3.6 调试与验证命令

编排文件编写完成后,使用以下命令验证结构与运行时状态:

# 验证 YAML 语法与结构
docker compose config

# 启动所有服务(后台模式)
docker compose up -d

# 查看服务启动顺序与健康状态
docker compose ps

# 进入容器验证网络连通性
docker compose exec app-server ping redis-cache

# 查看卷挂载情况
docker volume inspect cache_redis-data
调试要点:若服务启动失败,优先检查 docker compose logs <service-name>。常见问题包括:网络子网冲突、卷权限不足、健康检查超时导致依赖阻塞。