【免费下载链接】workbuddy2api-hub
WorkBuddy 国际国内多账号反代网关,支持 Codex / Claude Code / DSH与标准 OpenAI 客户端。
WorkBuddy2API-Hub 是一个把 WorkBuddy 国际版 / 国内版封装成标准 OpenAI 兼容接口的多账号反代网关。当你用 Codex、Claude Code 等客户端跑长对话时,网关要逐 token 转发流式响应,CPU 和系统调用开销会非常明显。这篇文章带你完整复盘项目里两次关键的性能优化:SSE 流式按块处理与用量数据分桶。实测数据是每请求 CPU 消耗降低 76%、系统调用降低 98%,数据看板查询从十几秒缩短到毫秒级——对新手运维和自托管用户来说,这些数字意味着同样的硬件能扛住更多并发。
一、先搞懂:网关的性能压力从哪里来 🤔
WorkBuddy2API-Hub 的角色是"中间人":客户端请求先进入网关,网关再转发给上游模型服务,流式回复则原路返回。它有两块天然的高负载场景:
- 流式转发:一轮 AI 回复动辄产生几千条 SSE(Server-Sent Events)事件,每条都要经过网关的读取、解析、写出;
- 用量看板:
usage/目录下的用量日志会越写越长(几万行很常见),面板每次刷新都要聚合这些流水。
优化正是围绕这两条链路展开的,对应的源码与测试都可以直接翻到:wb_proxy.py、tests/。
二、优化一:SSE 流式读取从"逐行"改成"按块" ⚡
问题定位:一行一次 read() 的隐形开销
早期实现里,网关读取上游流式响应的方式是"逐行迭代"——SSE 有多少行,就触发多少次read()系统调用。单看每次调用只有几十微秒,但一次流式回复就有几千条事件,更致命的是:每次系统调用都要释放并重新抢回 Python 的 GIL,几十个处理线程之间反复交接,CPU 大量时间浪费在"排队"而不是干活。
项目在 4 vCPU 真机上(v1.7.2 版本、15~20 req/s)做了 10 秒系统调用剖析,结果一目了然:
| 系统调用 | 耗时占比 | 调用次数 | 说明 |
|---|---|---|---|
| futex | 71.44% | 106,214 | 绝大多数是 GIL 交接 |
| poll | 20.31% | 396 | 等待网络 |
| read | 1.80% | 36,366 | 每行 SSE 一次 read |
| sendto | 0.54% | 5,043 | 每个 chunk 一次写出 |
解决方案:read1() 一次取回 64 KiB,内存里切行
新实现新增了 iter_sse_lines() 函数:通过read1()接口一次最多读回 64 KiB(SSE_READ_BLOCK)的底层数据,再在内存里按换行切分。效果是:
- 系统调用次数从"每行一次"降到"每个数据块一次",直接下降一到两个数量级;
- 延迟完全不变:
read1()一有字节就返回,完整的行立刻产出,首字延迟(TTFT)和输出字节流与原实现逐字节一致; - 写出侧同样批量化:利用
before_read钩子,在下一次可能阻塞的读取之前把攒下的事件合并写出,零散的sendall变成批量写入。
💡 关键设计原则:只改变系统调用的"次数",不改变调用方看到的任何一个字节。这个承诺由专门的测试套件逐字节钉住——tests/_test_sse_read_batching.py 覆盖了跨块断行、CRLF 换行、无尾换行等 9 类边界场景。
配套还做了一件小事:出站 TLS Context 进程级复用(tests/_test_shared_ssl_context.py),避免每次 HTTPS 建连都重复解析 121 张系统 CA 证书(每次约省 20ms),并完整保留 TLS Session Resumption。
实测收益
v1.7.3 版本发布时的实测结论(详见 docs/CHANGELOG.md):
- 每请求 CPU 消耗降低 76%
- 总系统调用次数降低 98%
三、优化二:用量看板从"整段扫描"改成"分桶" 📊
问题定位:查得越多,扫得越久
数据看板每次刷新/usage系列接口时,旧逻辑是把整个用量日志从头扫到尾再求和。真机 47k 行日志下,一次"最近 30 天"的查询要13,337ms;面板轮询一开,等于每隔十几秒白烧一遍全量扫描。
解决方案:日桶 + 小时桶 + 分钟环,三层分桶
优化的思路是"预聚合":日志写入时顺手把每一行折叠进对应的时间桶,查询窗口时直接相加现成的桶,不再碰原始日志。项目构建了三层结构(各层均有独立测试套件对拍,保证结果与逐行口径逐字节一致):
| 分桶层级 | 用途 | 对应测试 |
|---|---|---|
| 日桶 | range=today/week/month等整日窗口 | tests/_test_usage_day_buckets.py |
| 小时桶 | 面板"自定义"区间的整点窗口 | tests/_test_usage_hour_buckets.py |
| 分钟环 | 跨度 ≤ 6 小时的任意分钟窗口 | tests/_test_usage_series_minutes.py |
几个值得新手了解的设计细节:
- 封口机制:已经翻过去的小时/日期不再重新计算,桶对象原样复用,只有"今天"这个桶在持续生长;
- checkpoint 落盘:桶随状态文件持久化,重启后直接续用,冷启动也能秒开;
- 优雅降级:窗口起点没对齐格点、桶数据损坏等情况,自动退回整段扫描——宁可慢一点,绝不给错数。
实测收益
同样是真机日志规模下的前后对比:
| 查询场景 | 优化前 | 优化后 |
|---|---|---|
| 自定义区间"最近 30 天" | 13,337ms | 毫秒级 |
| 宽整点窗口(跨小时) | 782ms | 4.2ms |
| 数据看板 analytics 窗口 | 496ms | 2.9ms |
| 面板首屏(v1.7.4 修复误判废后) | 2~3s 全量重折 | 约 10ms 缓存秒开 |
这些桶还顺带省掉了大量重复的日志解码 CPU 开销——面板开着时不再周期性全量扫描,网关整体负载随之下降。保留窗口可以在面板"设置"页调节(日桶与小时桶保留天数),在磁盘体积和毫秒级求和跨度之间按需取舍。
四、如何验证与上手 👇
体验优化后的网关:按 README.md 的「快速启动」一节,Windows 双击start-wb-proxy.bat(默认端口 8788),macOS / Linux 执行./start-wb-proxy.sh;Docker 用户可用仓库里的 quick-deploy.sh 一键部署。
想亲眼看看性能测试怎么写的:仓库的测试都是零依赖脚本,直接运行即可,例如:
python tests/_test_sse_read_batching.py python tests/_test_usage_hour_buckets.py跑完会打印逐项 PASS/FAIL 与核心对比数字(如 2000 个事件下读取次数降低多少倍),非常适合新手理解"性能优化 + 回归测试"如何配套落地。
五、总结:两次优化的共同方法论
| 优化项 | 核心手法 | 实测收益 |
|---|---|---|
| SSE 按块处理(v1.7.3) | 减少系统调用次数,GIL 交接不再刷屏 | CPU ↓76%,syscall ↓98% |
| 出站 TLS 复用(v1.7.3) | 进程级共享 SSLContext | 每次建连省约 20ms |
| 用量分桶(v1.7.0~v1.7.4) | 预聚合 + checkpoint + 降级兜底 | 13s 级查询 → 毫秒级 |
对自托管用户的建议:升级即可获得全部收益,无需任何配置改动;分桶类优化保留了环境变量开关(如WB_USAGE_DAY_BUCKETS=0可整体退回旧口径),生产环境可以先观察再决定。完整的逐版本细节,欢迎翻 docs/CHANGELOG.md 里 v1.7.0 ~ v1.7.4 的段落,每条优化都写清了动机、口径与测试套件。
【免费下载链接】workbuddy2api-hub
WorkBuddy 国际国内多账号反代网关,支持 Codex / Claude Code / DSH与标准 OpenAI 客户端。
相关推荐
embedchain性能优化:如何实现90% token使用量降低
embedchain性能优化:如何实现90% token使用量降低 痛点:RAG应用的高成本挑战 还在为RAG(Retrieval Augmented Gene
人工智能Agent 记忆RAGCANN/asc-devkit:SIMT half精度转换
\_\_uint2half\_ru 产品支持情况 | 产品 | 是否支持 | | | | | Ascend 950PR/Ascend 950DT | √ | |
人工智能深度学习算子库CANNAscendFastfetch终极优化指南:5个简单技巧降低内存与CPU占用提升性能
Fastfetch终极优化指南:5个简单技巧降低内存与CPU占用提升性能 Fastfetch作为一款用C语言编写的系统信息展示工具,以其超越neofetch的运
CLI开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考