3. 环境搭建:数据库与缓存的本地测试环境配置

在契约测试驱动数据校验方案中,本地环境的可复现性与隔离性是保障回归冒烟可信度的基础。本章将指导你完成 MySQL / PostgreSQL 与 Redis / Memcached 的本地测试环境配置,确保数据库与缓存服务能够在隔离的容器或进程中稳定运行,并支持后续的契约校验与数据快照比对。

环境选型建议: 若团队以关系型强一致性校验为主,推荐 PostgreSQL + Redis;若更关注高吞吐写入与简单 KV 校验,MySQL + Memcached 组合更轻量。本课程两种组合均覆盖,你可按需选择。

3.1 数据库本地环境配置

数据库是契约校验的“数据锚点”,本地配置需满足:端口固定、数据可重置、字符集统一、时区对齐。以下分别给出 MySQL 与 PostgreSQL 的 Docker Compose 配置与关键参数说明。

3.1.1 MySQL 配置(Docker Compose)

version: '3.8'
services:
  mysql-contract:
    image: mysql:8.0
    container_name: mysql-contract-test
    environment:
      MYSQL_ROOT_PASSWORD: contract_pass
      MYSQL_DATABASE: contract_db
      MYSQL_USER: contract_user
      MYSQL_PASSWORD: contract_pass
    ports:
      - "3307:3306"
    volumes:
      - ./mysql-init:/docker-entrypoint-initdb.d
      - mysql-data:/var/lib/mysql
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --default-time-zone='+00:00'
      --max_connections=200
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mysql-data:
参数 说明 契约测试推荐值
MYSQL_ROOT_PASSWORD root 密码,仅用于管理 contract_pass
MYSQL_DATABASE 初始数据库名 contract_db
MYSQL_USER / PASSWORD 应用专用账号,避免使用 root contract_user / contract_pass
--character-set-server 字符集,防止中文乱码 utf8mb4
--default-time-zone 时区统一为 UTC,避免时间偏移 '+00:00'
ports 宿主机映射端口,避免与本地 MySQL 冲突 3307:3306

3.1.2 PostgreSQL 配置(Docker Compose)

version: '3.8'
services:
  pg-contract:
    image: postgres:15
    container_name: pg-contract-test
    environment:
      POSTGRES_DB: contract_db
      POSTGRES_USER: contract_user
      POSTGRES_PASSWORD: contract_pass
    ports:
      - "5433:5432"
    volumes:
      - ./pg-init:/docker-entrypoint-initdb.d
      - pg-data:/var/lib/postgresql/data
    command: >
      -c 'max_connections=200'
      -c 'timezone=UTC'
      -c 'client_encoding=UTF8'
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U contract_user -d contract_db"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pg-data:
关键差异对比: PostgreSQL 使用 pg_isready 做健康检查,MySQL 使用 mysqladmin ping。PostgreSQL 的时区与编码通过 command 参数传递,而 MySQL 通过 --default-time-zone 设置。两者均建议将初始化 SQL 脚本挂载到 docker-entrypoint-initdb.d 目录,首次启动时自动执行。

3.2 缓存本地环境配置

缓存服务在契约测试中承担数据快照暂存与状态校验角色。Redis 与 Memcached 的配置重点在于:内存上限、淘汰策略、连接数与持久化策略(仅 Redis)。

3.2.1 Redis 配置(Docker Compose)

version: '3.8'
services:
  redis-contract:
    image: redis:7-alpine
    container_name: redis-contract-test
    ports:
      - "6380:6379"
    volumes:
      - ./redis.conf:/usr/local/etc/redis/redis.conf
      - redis-data:/data
    command: redis-server /usr/local/etc/redis/redis.conf
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  redis-data:

redis.conf 关键配置(契约测试专用):

# 内存限制 256MB,防止测试数据膨胀
maxmemory 256mb
# 淘汰策略:allkeys-lru,确保缓存空间可控
maxmemory-policy allkeys-lru
# 关闭持久化,测试环境无需 RDB/AOF
save ""
appendonly no
# 连接数限制
maxclients 100
# 超时设置
timeout 300

3.2.2 Memcached 配置(Docker Compose)

version: '3.8'
services:
  memcached-contract:
    image: memcached:1.6-alpine
    container_name: memcached-contract-test
    ports:
      - "11212:11211"
    command: >
      memcached
      -m 128
      -c 200
      -t 4
      -l 0.0.0.0
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "11211"]
      interval: 10s
      timeout: 5s
      retries: 5
参数 Memcached 说明 契约测试推荐值
-m 最大内存(MB) 128
-c 最大并发连接数 200
-t 线程数 4
-l 监听地址 0.0.0.0
避坑提醒: Memcached 默认端口 11211 常被系统服务占用,建议映射到 11212。Redis 默认端口 6379 也建议映射到 6380,避免与本地开发环境冲突。所有缓存服务均关闭持久化,因为契约测试的数据快照由测试框架管理,缓存仅作临时存储。

3.3 整体环境架构图

下图展示了数据库与缓存服务在本地测试环境中的部署关系,以及契约测试框架如何通过固定端口与健康检查机制进行服务发现。

本地契约测试环境架构 契约测试框架 数据库层 MySQL:3307 PostgreSQL:5433 健康检查: mysqladmin / pg_isready 缓存层 Redis:6380 Memcached:11212 健康检查: redis-cli / nc 数据初始化与持久化卷 MySQL: ./mysql-init + mysql-data 卷 PostgreSQL: ./pg-init + pg-data 卷 Redis: ./redis.conf + redis-data 卷

3.4 环境验证清单

完成配置后,执行以下验证步骤,确保所有服务可被契约测试框架正常调用:

  1. 端口连通性:使用 telnet 127.0.0.1 3307 验证 MySQL,telnet 127.0.0.1 5433 验证 PostgreSQL,telnet 127.0.0.1 6380 验证 Redis,telnet 127.0.0.1 11212 验证 Memcached。
  2. 数据库初始化:连接 MySQL 执行 SHOW DATABASES; 应看到 contract_db;连接 PostgreSQL 执行 \l 应列出 contract_db。
  3. 缓存写入/读取:Redis 执行 SET contract:key "hello" 后 GET contract:key 应返回 "hello";Memcached 执行 set contract:key 0 60 5 后 get contract:key 应返回存储值。
  4. 健康检查状态:执行 docker ps 查看所有容器 STATUS 列应为 (healthy)。
自动化验证脚本建议: 将上述验证步骤写入 verify-env.sh,集成到 CI 流水线的前置检查阶段。一旦任一服务健康检查失败,立即中止后续契约测试,避免因环境问题导致误报。

3.5 常见问题与解决方案

问题现象 可能原因 解决方案
MySQL 容器启动后立即退出 端口 3307 被占用或数据卷权限不足 执行 lsof -i :3307 查找占用进程;检查 ./mysql-init 目录权限为 755
PostgreSQL 连接提示 role does not exist 环境变量 POSTGRES_USER 未正确传递 确认 docker-compose 中 POSTGRES_USER 拼写正确,重启容器
Redis 无法执行 SET 命令 配置文件 redis.conf 中 protected-mode 为 yes 在 redis.conf 中添加 protected-mode no 或绑定 bind 0.0.0.0
Memcached 连接超时 防火墙或 Docker 网络未正确映射端口 检查 docker-compose ps 确认端口映射状态;尝试 docker exec 进入容器内测试

完成以上配置与验证后,你的本地环境已具备运行数据库缓存契约测试的基础条件。下一阶段将基于此环境搭建数据快照与契约校验管道。