TinyID /id/nextId 接口 WRK 压测报告(混合场景)

41 阅读5分钟

TinyID /id/nextId 接口 WRK 压测报告(混合场景)

1. 测试背景与目标

验证 TinyId 在 常用场景(在线服务 + 定时任务 job) 下的性能与稳定性,使用 wrk 对 TinyId HTTP 服务 /id/nextId 接口进行压测。

本轮压测的目标:

  1. 1. 评估单实例 tinyid-server 在混合业务访问模式下的极限 QPS 与典型延迟。
  2. 2. 观察在约 4 vCPU 满载情况下的资源使用情况(CPU / 内存 / I/O)。

2. 被测系统与环境

2.1 被测服务

  • • 服务名称:tinyid-server
  • • 提供接口:
    • GET /id/nextId?bizType={bizType}&token={TOKEN}
  • • ID 生成实现:
    • • HTTP 层:Spring Boot 服务,对外提供 /id/nextId HTTP 接口。
    • • ID 生成:通过 TinyId 客户端根据 bizType 调用 TinyId 号段服务,号段在内存中用 AtomicLong 递增发号。

2.2 运行环境

docker stats 观测当前运行情况:

CONTAINER ID   NAME                     CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
a66ade7f190e   tinyid-tinyid-server-1   402.53%   1.714GiB / 15.56GiB   11.02%    14.7GB / 19.3GB   5.24GB / 11.2GB   77

解释:

  • CPU ~ 402%:说明该容器约 4 个 vCPU 已基本打满
  • • 内存占用 1.7 GiB / 15.56 GiB:内存压力很小,不是瓶颈;
  • • NET / BLOCK I/O:为容器启动以来的累计值,包含网络流量和内存使用情况;
  • • PIDS = 77:包含 JVM 自身工作线程 + Netty/HTTP 线程等;

可以认为本轮压测,CPU 资源是当前极限 QPS 的主要限制因素。

3. 压测工具与脚本说明

3.1 压测工具

  • • 工具:wrk
  • • 命令行示例:
BASE_BIZTYPE=test \
SERVICE_MAX=11 \
ONLINE_SERVICE_MAX=1 \
JOB_RATIO=0.3 \
TOKEN=0f673adf80504e2eaa552f5d791b642c \
wrk -t4 -c40 -d1800s \
    -s tinyid_wrk_mix.lua \
    http://localhost:9999 \
    -- 1          # tenantId = 1

说明:

  • -t4:4 个 wrk 工作线程;
  • -c40:40 个并发连接;
  • -d1800s:压测时长 1800 秒(30 分钟)。
    短时间验证可使用 -d60s
  • -s tinyid_wrk_mix.lua:使用自定义 Lua 脚本构造请求。
  • -- 1-- 后面的参数传给 Lua 的 init(args),表示 tenantId=1

3.2 业务混合脚本 tinyid_wrk_mix.lua 说明

脚本核心逻辑:

  1. 1. BizType 规则``` 在线服务:{BASE_BIZTYPE}_t{tenant}_svc{serviceId} Job    :{BASE_BIZTYPE}_t{tenant}_job{serviceId}
    *   • 在线服务:`test_t1_svc1`(对应一个 ERP / Web / 订单服务)
    *   • Job:`test_t1_job2` ~ `test_t1_job11`(对应 10 个同步任务、对账任务等)
    
  2. 2. 请求分流逻辑``` local isJob = false if #jobServices > 0 and math.random() < jobRatio then   isJob = true        -- 按 JOB_RATIO 概率走 job end
    *   • `JOB_RATIO = 0.3`:约 30% 请求为 job,70% 请求为在线服务,使用了JOB\_RATIO与随机数来对请求进行分流
    
  3. 3. 最终请求路径``` local bizType = string.format("%s_t%d_%s%d", baseBizType, tenantId, kind, serviceId) local path = string.format("/id/nextId?bizType=%s&token=%s", bizType, token) return wrk.format(nil, path)
    *   • 构造HTTP请求参数
    

4. 压测结果

以下指标来自一轮 1 分钟(可能存在JVM JIT没有被充分的热身优化,导致CPU执行函数成本较高)、-t4 -c40 的典型跑数(同一接口形态),可作为本次混合脚本的性能参考基线:

Running 1m test @ http://localhost:9999
  4 threads and 40 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     5.30ms    4.38ms   62.44ms   85.79%
    Req/Sec     2.13k   284.69     3.00k    80.02%
  512391 requests in 0.96m, 85.12MB read
  Socket errors: connect 0, read 0, write 0, timeout 159
Requests/sec:   8894.89
Transfer/sec:      1.48MB

QPS = 512391/(0.96*50)

约 85% 的请求在一个标准差以内

以下指标来自一轮 30 分钟(长期压测可能有GC等情况,出现了906.22ms的最坏成绩)、-t4 -c40 的典型跑数(同一接口形态),可作为本次混合脚本的性能参考基线:

Running 30m test @ http://localhost:9999
  4 threads and 40 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.92ms   11.04ms 906.22ms   98.61%
    Req/Sec     3.26k   795.24    28.10k    95.87%
  23293153 requests in 28.75m, 3.78GB read
  Socket errors: connect 0, read 0, write 0, timeout 4737
Requests/sec:  13502.98
Transfer/sec:      2.24MB

QPS=23293153 / (28.75 * 60)

在 13.5k QPS 的高压 + 30 分钟长时间下,TinyID 的平均延迟仍然控制在 5ms 以内

主流延迟非常好看,平均只有 3~4ms;

5. 性能分析与结论

综合 docker stats 与 wrk 指标:

  1. 1. CPU 明确是当前瓶颈,
    • • 容器 CPU 稳定在 ~400%,约 4 vCPU 满负载;
    • • 内存使用在 1.7 GiB 左右,远低于限制,不是瓶颈;
  2. 2. 吞吐量与 CPU 使用基本线性对应
    • • 估算每个请求的 CPU 耗时约为 0.40.5 ms;
    • • 说明 TinyId 号段逻辑 + HTTP 层实现整体性能稳定、可预期。

6. TinyId如果需要二开,可以调整的地方

  1. 1. 代码路径微优化
  • • 减少热点路径日志输出与对象分配(DAO 查询与字符串拼接)。
  • • 提前预分配响应缓冲,降低 StringBuilder 扩容
  1. 2. 数据库与连接池
  • • 切换至 HikariCP 并调优池参数,降低连接建立延迟。
  • • MySQL 服务器层参数优化,提高写吞吐。
  1. 3. HTTP 层开销优化
  • • 对于接口生成id号段,使用 纯文本替换 JSON ;减少id生成过程中对象的装箱和拆箱;
  • • 调整嵌入式容器:从默认的web容器Tomcat 改用 Undertow(NIO)提升吞吐,或者调整 Tomcat 的基础配置。
  1. 4. 配置管理
  • • 从本地硬编码读取配置文件,切换为使用 nacos 统一进行配置管理
  1. 5. 升级springboot框架、JDBC连接器
  • • 默认采用1.X的 springboot,可以升级为项目相同版本
  • • 数据默认建表语句时间处理没使用 Datatime , 并且不兼容Mysql8.0

需要*.lua脚本联系 big.lu@foxmail.com

本文使用 文章同步助手 同步