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 冲突。
- 多网络接入:一个服务可同时加入多个网络,实现缓存层与业务层分离。
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:
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>。常见问题包括:网络子网冲突、卷权限不足、健康检查超时导致依赖阻塞。