先看现象。批处理脚本从 4 个 worker 加到 16 个,吞吐一直卡在每分钟 60 条,CPU 只到 20%,每条请求耗时稳定 4 秒,日志里看不到排队。

原因不止一个,得分开看。全局锁把请求整段包住,实际只有一条在跑。另一种情况是HTTP 连接池上限还是 4。

另外,限流令牌桶按进程各算一份,瞬间被合并。

少数情况下是写结果用的是单线程串行落盘。

先打点看每条在等待还是执行

python -m cProfile -s cumtime batch.py 2>&1 | head -20

然后把连接池上限调到与并发匹配

limits = httpx.Limits(max_connections=32, max_keepalive_connections=16)

去掉请求外层的全局锁

with lock: pass  # 只保留写结果处的锁

末了用固定样本压测确认吞吐变化

python bench.py --workers 4,8,16 --items 500 --report bench.csv

这类改动我都写进变更记录,过两周再出问题时能对上号。

怎么算真的好了,看的是同一批现象。16 个 worker 时吞吐提到每分钟 200 条以上,CPU 利用率上来,单条耗时仍稳定在 4 秒左右。

提醒一点。加 worker 不加吞吐基本是串行点没拆掉,先用剖析看等待占比,再去动连接池和锁。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189