gunicorn 的 sync、gthread、gevent 到底怎么选?等待型与轻量请求的差别有多大?为什么 sync worker 前面一定要有反向代理?这篇在同样的槽位数下把三种类型的并发、内存与慢客户端的表现对照出来。
sync × 4 空闲内存 165 MB(5 个进程) | /hello 32 并发 3295 请求/秒 | /wait 0.5 秒 × 128 个、64 并发: 8 请求/秒(理想 128)| keep-alive 请求数 0 gthread × 2 个 worker × 8 线程 空闲内存 98 MB(3 个进程) | /hello 32 并发 3147 请求/秒 | /wait 0.5 秒 × 128 个、64 并发: 19 请求/秒(理想 128)| keep-alive 请求数 4000 gevent × 2 个 worker 空闲内存 116 MB(3 个进程) | /hello 32 并发 3032 请求/秒 | /wait 0.5 秒 × 128 个、64 并发: 83 请求/秒(理想 128)| keep-alive 请求数 4000
上一篇:Thread Local 与请求隔离;下一篇:多进程下的全局变量。
压测用系统自带的 ApacheBench,与被测服务同机运行,每个数字只测一次,只看相对关系。进程数包含 master 进程。
sync × 1 一个连接卡着没发完请求头时,另一个正常请求 → TimeoutError(等了 10003 ms) gthread × 1 个 worker × 8 线程 一个连接卡着没发完请求头时,另一个正常请求 → 200,用时 9 ms gevent × 1 个 worker 一个连接卡着没发完请求头时,另一个正常请求 → 200,用时 8 ms