起因:因为cpu利用率低导致我去缩容,虽然缩容之后cpu利用率上升维持在60%左右,但是程序响应耗时增加了。
解释:因为cpu干这件活本身不累,但在干这件活的时候不能去干其他事情,导致并发的请求不能及时响应,导致耗时增加。
比如,sleep1s,此时cpu利用率为0,但是cpu却做不了其他的处理。其他任务就被阻塞。
解法:增加cpu的线程数。
https://blog.csdn.net/weixin_38553042/article/details/120066188
但我任务的配置其实是协程,而不是多线程。
gunicorn当worker_class = 'gevent’时,如何增加程序的并发能力?
在 Gunicorn 中使用 worker_class = 'gevent'
(基于协程的异步 Worker)时,提升并发能力的关键在于 合理配置协程并发数 和 优化资源分配。以下是具体方法和步骤:
一、gevent
的并发原理
gevent
通过 协程(Coroutine) 和 事件循环(Event Loop) 实现高并发,每个请求由协程处理而非线程或进程。协程的切换成本极低,因此适用于 I/O 密集型 场景(如 HTTP API、数据库查询、外部服务调用等)。
二、提升并发能力的核心参数
1. Worker 进程数 (--workers
/workers
)
- 作用:指定启动的 Worker 进程数量。每个 Worker 是一个独立进程,内部通过协程处理并发。
- 建议值:通常设置为
CPU 核心数 × 2 + 1
。例如 4 核 CPU 可设workers = 9
。 - 示例:
gunicorn --workers=9 --worker-class=gevent app:app
2. 每个 Worker 的并发连接数 (--worker-connections
/worker_connections
)
- 作用:单个 Worker 进程能处理的最大并发连接数。此参数直接影响协程池大小。
- 建议值:默认
1000
,可调整为1000~5000
(需根据内存和负载测试调整)。 - 示例:
gunicorn --workers=9 --worker-class=gevent --worker-connections=2000 app:app
3. 超时时间 (--timeout
/timeout
)
- 作用:防止单个请求长时间阻塞协程。
- 建议值:根据接口响应时间设定(如
--timeout=30
表示 30 秒超时)。
三、完整配置示例
1. 通过命令行启动
gunicorn \
--workers=9 \ # Worker 进程数 = CPU核心数 × 2 + 1
--worker-class=gevent \ # 使用 gevent Worker
--worker-connections=2000 \ # 每个 Worker 的协程并发数
--timeout=30 \ # 请求超时时间
--bind=0.0.0.0:8000 \ # 绑定端口
app:app # 应用入口
2. 通过配置文件 (gunicorn.conf.py
)
# gunicorn.conf.py
workers = 9
worker_class = "gevent"
worker_connections = 2000
timeout = 30
bind = "0.0.0.0:8000"
启动命令:
gunicorn -c gunicorn.conf.py app:app
四、关键优化点
1. 内存限制
- 每个 Worker 的协程数 (
worker_connections
) 受内存限制。协程越多,内存占用越高。 - 监控内存:使用
top
或htop
观察进程内存,避免触发 OOM(内存不足)。
2. I/O 密集型 vs CPU 密集型
- I/O 密集型(如 HTTP API、数据库查询):优先增加
worker_connections
。 - CPU 密集型(如图像处理、复杂计算):协程无法提升性能,需改用多进程(如
gthread
Worker)。
3. 数据库连接池
- 协程并发高时,需确保数据库连接池足够大(如 SQLAlchemy 的
pool_size
)。
4. 依赖库兼容性
- 确保所有代码和第三方库兼容
gevent
(可能需要monkey.patch_all()
)。 - 启动前添加补丁:
# app.py 入口文件顶部 from gevent import monkey monkey.patch_all()