2. 测试环境搭建:Docker容器化部署、OpenAPI网关配置、缓存中间件(Redis/Memcached)初始化

缓存冒烟检查的可靠性高度依赖测试环境的真实性与可复现性。本章将指导你通过 Docker Compose 一键拉起包含 OpenAPI 网关、Redis 与 Memcached 的完整测试拓扑,并完成网关路由规则与缓存实例的初始化配置。所有操作均面向集成测试前置条件,不涉及业务逻辑。

2.1 环境拓扑总览

测试环境由四个核心容器组成,它们之间的调用关系如下图所示:

缓存冒烟测试环境容器拓扑 缓存冒烟测试环境容器拓扑 测试客户端 (JUnit/TestNG) OpenAPI 网关 (Kong/Gateway) 端口 8000 / 8443 Redis 7.x (缓存实例) 端口 6379 Memcached 1.6 (缓存实例) 端口 11211 说明:测试客户端通过网关统一入口访问缓存;网关负责路由鉴权与协议转换,缓存实例直连测试断言。
设计原则:网关前置模式确保所有缓存操作都经过 OpenAPI 规范校验,与生产环境流量路径一致。测试客户端不直连缓存端口,避免绕过网关的假通过。

2.2 Docker Compose 编排文件

使用以下 docker-compose.yml 定义四个服务。注意网络模式采用自定义桥接网络 cache-test-net,保证容器间通过服务名互访。

version: "3.9"

services:
  # ---------- OpenAPI 网关 ----------
  openapi-gateway:
    image: kong:3.5
    container_name: cache-gateway
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: "0.0.0.0:8001"
    ports:
      - "8000:8000"   # 代理端口
      - "8001:8001"   # 管理端口(仅测试环境暴露)
    volumes:
      - ./kong.yml:/etc/kong/kong.yml:ro
    networks:
      - cache-test-net
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ---------- Redis ----------
  redis:
    image: redis:7-alpine
    container_name: cache-redis
    ports:
      - "6379:6379"
    command: ["redis-server", "--requirepass", "testpass123", "--appendonly", "no"]
    networks:
      - cache-test-net
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "testpass123", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

  # ---------- Memcached ----------
  memcached:
    image: memcached:1.6-alpine
    container_name: cache-memcached
    ports:
      - "11211:11211"
    command: ["memcached", "-m", "64", "-c", "1024"]
    networks:
      - cache-test-net
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "11211"]
      interval: 10s
      timeout: 3s
      retries: 5

networks:
  cache-test-net:
    driver: bridge
安全提醒:Redis 设置了密码 testpass123,Memcached 无认证。生产环境必须为 Memcached 增加 SASL 认证或网络隔离。测试环境中的管理端口 8001 不应暴露到公网。

2.3 OpenAPI 网关声明式配置

Kong 以 DB-less 模式运行,路由规则由 kong.yml 声明式定义。以下配置为缓存操作创建两条路由:/cache/redis 和 /cache/memcached,分别指向后端缓存服务。

# kong.yml — 声明式网关配置
_format_version: "3.0"

services:
  - name: redis-cache-service
    url: http://redis:6379
    routes:
      - name: redis-route
        paths:
          - /cache/redis
        methods:
          - GET
          - POST
          - DELETE
        strip_path: true
        protocols:
          - http
          - https

  - name: memcached-cache-service
    url: http://memcached:11211
    routes:
      - name: memcached-route
        paths:
          - /cache/memcached
        methods:
          - GET
          - POST
          - DELETE
        strip_path: true
        protocols:
          - http
          - https

# 全局插件:请求日志与速率限制(冒烟检查用)
plugins:
  - name: rate-limiting
    config:
      minute: 100
      policy: local
  - name: file-log
    config:
      path: /var/log/kong/access.log
路由路径 后端服务 允许方法 strip_path 冒烟检查用途
/cache/redis redis:6379 GET, POST, DELETE true 验证 Redis SET/GET/DEL 操作
/cache/memcached memcached:11211 GET, POST, DELETE true 验证 Memcached set/get/delete 操作

2.4 缓存中间件初始化脚本

容器启动后,需要执行初始化操作:设置 Redis 密码验证、清空遗留数据、验证 Memcached 可达性。以下脚本在测试套件 @BeforeSuite 阶段执行。

// CacheInitializer.java — 测试前置初始化
public class CacheInitializer {

    private static final String REDIS_HOST = "localhost";
    private static final int REDIS_PORT = 6379;
    private static final String REDIS_PASSWORD = "testpass123";
    private static final String MEMCACHED_HOST = "localhost";
    private static final int MEMCACHED_PORT = 11211;

    public static void init() {
        // 1. 清空 Redis 所有数据(避免脏数据干扰)
        try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) {
            jedis.auth(REDIS_PASSWORD);
            jedis.flushAll();
            System.out.println("[INIT] Redis flushed, keys=" + jedis.dbSize());
        }

        // 2. 验证 Memcached 连接并清空
        try (MemcachedClient client = new MemcachedClient(
                new InetSocketAddress(MEMCACHED_HOST, MEMCACHED_PORT))) {
            client.flush();
            System.out.println("[INIT] Memcached flushed, stats=" + client.getStats());
        }

        // 3. 验证网关健康状态
        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:8001/status"))
                .GET()
                .build();
        try {
            HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() == 200) {
                System.out.println("[INIT] Gateway healthy: " + response.body());
            }
        } catch (Exception e) {
            throw new RuntimeException("Gateway not ready, abort test suite.", e);
        }
    }
}
初始化检查清单:
  • Redis 密码认证通过,flushAll 执行成功
  • Memcached flush 命令返回 true
  • 网关管理 API /status 返回 200
  • 两条路由 /cache/redis 和 /cache/memcached 可被 curl 访问

2.5 环境就绪验证步骤

执行以下命令序列,确认所有组件正常运行:

  1. 启动容器:docker compose up -d
  2. 检查容器状态:docker compose ps — 四个服务均为 Up 且健康检查通过
  3. 验证网关路由:curl -s http://localhost:8000/cache/redis/ping 应返回 +PONG
  4. 验证 Memcached 可达:echo -e "stats\r" | nc localhost 11211 应返回统计信息
  5. 运行初始化类:执行 CacheInitializer.init() 无异常抛出
环境就绪验证流程 环境就绪验证流程 docker compose up compose ps 检查 curl 网关路由 nc Memcached CacheInitializer.init() 全部通过 → 环境就绪

2.6 常见问题与排查

现象 可能原因 解决措施
网关路由返回 404 strip_path 配置错误或路由未加载 检查 kong.yml 格式;访问 localhost:8001/routes 确认路由列表
Redis 连接被拒绝 密码错误或容器未就绪 执行 docker logs cache-redis 查看认证日志;确认 requirepass 参数
Memcached 无响应 端口映射冲突或容器内存不足 检查 docker compose ps 端口映射;-m 64 是否被宿主机限制
健康检查超时 容器启动顺序依赖未处理 在测试代码中添加 await().atMost(30, SECONDS).until(() -> checkHealth());
最佳实践:将 docker compose 启动与初始化脚本封装为 Maven profile 或 Gradle task,通过 mvn test -Pcache-smoke 一键完成环境准备与测试执行,避免手动操作遗漏。