Locust 的 gevent 协程相比 JMeter 线程的优势在哪,适合什么协议场景

解读

国内面试问这道题,核心是想验证三件事:

  1. 你是否真的用 Locust 做过万级并发,还是只停留在“写脚本”层面;
  2. 能否把“协程 vs 线程”差异翻译成压测场景里的量化收益;
  3. 知不知道协议层哪些特征会放大协程优势,哪些场景反而必须用 JMeter 的线程模型。
    回答时先给结论,再用“单机并发数、内存、CPU、连接模型”三个指标量化,最后落到协议特征,基本就能拿到高分。

知识点

  1. 并发模型

    • gevent:单进程内协程,用户态调度,IO 阻塞时主动 yield,上下文切换 < 1 µs。
    • JMeter:OS 线程,1.3–2 MB 栈/线程,切换需内核参与,约 3–5 µs,并发 1 k 线程后调度开销陡增。
  2. 内存占用

    • Locust:1 万协程 ≈ 150 MB(Python 对象 + gevent hub)。
    • JMeter:1 万线程 ≈ 13–20 GB,需调大 Xmx 并开 64-bit 模式,否则直接 OOM。
  3. CPU 利用率

    • 协程模型下,CPU 空转少;线程模型在锁竞争、上下文切换时 sys 占用可达 30%+。
  4. 连接模型

    • HTTP/1.1 keep-alive:gevent 单 TCP 连接可复用到 1 万+ 协程,无锁。
    • HTTP/2 多路复用:gevent 原生支持 h2 的 stream,单连接即可跑满千兆。
    • 长连接推送(WebSocket、MQTT、TCP 自定义):协程可维持 50 万连接/8 GB 内存;JMeter 需大量线程+连接池,基本不可行。
  5. 短板

    • gevent 遇到 CPU 密集型任务会阻塞 hub,导致 RPS 雪崩;
    • JMeter 的 GUI 调试、插件生态、事务控制器、IP 欺骗等对企业存量系统更友好。

答案

“Locust 用 gevent 协程,最大优势是单机可低成本模拟 5–10 万并发长连接,内存只有 JMeter 的 1/100,上下文切换开销低一个数量级。
量化来看,在 8C16G 的阿里云 ECS 上,Locust 跑出 5 万 WebSocket 长连接只占用 800 MB 内存,CPU sys 低于 5%;同规格机器 JMeter 线程数到 8 k 就触发 90%+ sys,进程被内核频繁抢占,结果失真。
因此它最适合:

  1. HTTP/1.1 keep-alive 高并发短事务,单机能压到 3–5 万 RPS;
  2. HTTP/2 多路复用场景,单连接即可打满带宽;
  3. 长连接推送类协议——WebSocket、MQTT、TCP 私有协议,需要 10 万+ 并发连接;
  4. 自定义业务逻辑复杂、需 Python 直接调用 SDK 的流式接口。
    反之,如果脚本里包含大量加解密、图片压缩等 CPU 密集逻辑,或者必须用 JMeter 的 150+ 插件做报文拼装、IP 欺骗,那就回到 JMeter 线程模型更合适。”

拓展思考

  1. 混合模型:线上压测可把 Locust 当“长连接发生器”负责 80% 连接,JMeter 通过 slave 模式跑剩余 20% 的短连接并做精细事务采样,两边结果用 Prometheus 统一聚合,兼顾并发量级与报表精度。
  2. 内核调优:当 gevent 并发过 30 万时,Linux 默认 somaxconn、file-max 会率先成为瓶颈,需提前调优并开 reuseport,否则协程优势发挥不出来。
  3. 代码审查:协程代码里一旦写出 requests 同步库或 time.sleep(),就会阻塞整个 hub,面试时可主动说“我们内部强制用 geventhttpclient + grequests 并做 CR 扫描”,体现工程化思维。