2. 压测场景库设计原则

构建一个高质量的 Outbox 表压测场景库,不能仅靠零散脚本的堆砌。必须遵循一套明确的设计原则,确保场景库能够真实反映生产负载、支撑长期性能演进,并降低维护成本。本章围绕构建目标、模块化设计、可复用性与可扩展性三大核心原则展开。

2.1 压测场景库的构建目标

场景库的终极目标是模拟真实、量化瓶颈、驱动优化。具体拆解为以下四个子目标:

目标维度 说明 Outbox 场景示例
负载真实性 模拟生产环境的流量特征(并发、数据量、峰值) 订单创建高峰时 Outbox 表每秒写入 5000 条记录
瓶颈可复现 稳定触发已知或潜在的性能瓶颈 Outbox 表主键争用、死锁、Binlog 堆积
指标可量化 输出明确的性能指标(TPS、P99 延迟、资源消耗) 数据传输优化前后 P99 延迟从 120ms 降至 45ms
优化可验证 为每一次架构或代码变更提供 A/B 对比依据 批量写入 vs 单条写入的吞吐量对比
实践要点:每个场景必须绑定一个明确的“压测通过标准”。例如:“在 1000 并发下,Outbox 表写入 TPS ≥ 8000,且无死锁报错。” 没有通过标准的场景,无法驱动优化决策。

2.2 模块化设计

模块化是场景库可维护性的基石。将压测场景拆解为数据层、事务层、传输层、监控层四个独立模块,每个模块可单独替换或升级。

Outbox 压测场景库模块化架构 数据层 数据生成器 / 数据模板 事务层 事务编排 / 回滚策略 传输层 拉取 / 推送 / 批量策略 监控层 指标采集 / 告警规则 SQL 模板引擎 事务边界控制 连接池管理 指标上报器 模块化设计收益 • 数据层替换:切换不同数据规模(100万/1000万/1亿条 Outbox 记录) • 传输层替换:对比“定时批量拉取”与“实时 CDC 推送”的性能差异 • 监控层替换:从 Prometheus 切换到阿里云 SLS,不改动压测主逻辑 • 事务层替换:从本地事务切换到 Seata TCC 模式,验证分布式事务开销

2.3 可复用性要求

场景库中的组件应具备一次编写、多处运行的能力。避免为每个测试目标重复造轮子。可复用性体现在以下三个层面:

  • 数据模板复用:定义通用的 Outbox 记录结构(event_id, aggregate_type, payload, status, created_at),通过参数化注入不同的业务语义。
  • 压测脚本复用:将“写入 Outbox”、“拉取未发送记录”、“标记已发送”封装为独立函数,通过 YAML/JSON 配置驱动不同场景。
  • 监控面板复用:设计通用的 Grafana 看板模板,涵盖 Outbox 表写入 TPS、传输延迟、死锁次数、Binlog 积压量等核心指标。
代码示例:可复用的 Outbox 写入函数(Java + JMeter 插件)
// 可复用的 Outbox 写入器
public class OutboxWriter {
    private final DataSource dataSource;
    private final String insertSql;

    public OutboxWriter(DataSource dataSource, String tableName) {
        this.dataSource = dataSource;
        this.insertSql = String.format(
            "INSERT INTO %s (event_id, aggregate_type, payload, status, created_at) VALUES (?, ?, ?, 'PENDING', NOW())",
            tableName
        );
    }

    public void write(String eventId, String aggregateType, String payload) {
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement(insertSql)) {
            ps.setString(1, eventId);
            ps.setString(2, aggregateType);
            ps.setString(3, payload);
            ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("Outbox 写入失败", e);
        }
    }
}

2.4 可扩展性要求

压测场景库必须能够平滑适应业务增长和架构演进。可扩展性设计遵循以下原则:

扩展维度 设计要求 Outbox 场景示例
数据规模扩展 支持从单表到分库分表的无缝切换 Outbox 表从单表扩展到 16 个分片
传输协议扩展 支持新增传输通道(Kafka / RocketMQ / Pulsar) 从 Kafka 切换到 RocketMQ,不改动压测主流程
并发模型扩展 支持从单线程到协程/线程池的灵活配置 压测配置中调整 concurrency=200,自动分配线程
监控集成扩展 支持对接不同监控系统(Prometheus / Datadog / SkyWalking) 通过 SPI 机制加载不同的监控上报实现
常见陷阱:不要将压测场景与具体中间件版本强绑定。例如,不要在脚本中硬编码 Kafka 2.8 的 API 调用,而应使用通用客户端抽象层。否则,升级 Kafka 到 3.0 时,整个场景库可能面临重写。

2.5 设计原则总结

将上述原则归纳为一张决策检查表,供场景库设计时逐项核对:

压测场景库设计原则检查表 构建目标 真实·量化·可验证 模块化设计 数据·事务·传输·监控 可复用性 模板·脚本·看板复用 可扩展性 规模·协议·并发·监控 设计原则优先级 1. 构建目标决定场景库的“存在价值”——没有明确目标,场景库就是脚本垃圾堆。 2. 模块化设计是“骨架”——决定场景库能否长期维护。 3. 可复用性与可扩展性是“肌肉”——决定场景库能否应对业务变化。