TinyID /id/nextId 接口 WRK 压测报告(混合场景)
1. 测试背景与目标
验证 TinyId 在 常用场景(在线服务 + 定时任务 job) 下的性能与稳定性,使用 wrk 对 TinyId HTTP 服务 /id/nextId 接口进行压测。
本轮压测的目标:
- 1. 评估单实例
tinyid-server在混合业务访问模式下的极限 QPS 与典型延迟。 - 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. 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. 请求分流逻辑```
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. 最终请求路径```
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. CPU 明确是当前瓶颈,
- • 容器 CPU 稳定在 ~400%,约 4 vCPU 满负载;
- • 内存使用在 1.7 GiB 左右,远低于限制,不是瓶颈;
- 2. 吞吐量与 CPU 使用基本线性对应
- • 估算每个请求的 CPU 耗时约为 0.40.5 ms;
- • 说明 TinyId 号段逻辑 + HTTP 层实现整体性能稳定、可预期。
6. TinyId如果需要二开,可以调整的地方
- 1. 代码路径微优化
- • 减少热点路径日志输出与对象分配(DAO 查询与字符串拼接)。
- • 提前预分配响应缓冲,降低 StringBuilder 扩容
- 2. 数据库与连接池
- • 切换至 HikariCP 并调优池参数,降低连接建立延迟。
- • MySQL 服务器层参数优化,提高写吞吐。
- 3. HTTP 层开销优化
- • 对于接口生成id号段,使用 纯文本替换 JSON ;减少id生成过程中对象的装箱和拆箱;
- • 调整嵌入式容器:从默认的web容器Tomcat 改用 Undertow(NIO)提升吞吐,或者调整 Tomcat 的基础配置。
- 4. 配置管理
- • 从本地硬编码读取配置文件,切换为使用 nacos 统一进行配置管理
- 5. 升级springboot框架、JDBC连接器
- • 默认采用1.X的 springboot,可以升级为项目相同版本
- • 数据默认建表语句时间处理没使用 Datatime , 并且不兼容Mysql8.0
需要*.lua脚本联系 big.lu@foxmail.com
本文使用 文章同步助手 同步