AWS EC2 Nginx+Django+PostgreSQL栈低并发CPU满负载问题咨询
高并发下CPU占满的问题排查与整改
现有配置存在的明确问题
- 进程数量配置远超硬件承载的最优值,引发大规模上下文切换
你当前分别给Nginx设置了128个worker_processes、给Gunicorn设置了128个工作进程,两类反向代理+应用服务的常驻进程总数达到256个,远高于实例的72vCPU调度能力。内核调度器需要频繁在这些进程间轮询切换,仅上下文保存、TLB刷新的无意义CPU开销就会占据算力的30%以上,根本扛不住日常业务请求。 - 共享内存参数与数据库配置严重不匹配,导致数据库效率暴跌
你在内核配置里把kernel.shmmax设为约1GB,但PostgreSQL的shared_buffers开了近50GB,完全超出了单块共享内存的申请上限。PostgreSQL无法正常申请连续的大块共享内存,只能退化成零散的私有内存分配模式,数据读写的CPU开销会数倍于正常状态,甚至会触发大量不必要的磁盘IO逻辑,进一步挤占CPU资源。 - 系统资源上限设置偏低,触发无效重试逻辑
当前fs.file-max=90000的句柄上限,完全匹配不了128个Nginx进程、800个PostgreSQL连接、128个Gunicorn进程的实际句柄消耗。一旦达到句柄上限,应用会反复发起申请、重试请求,整个过程没有实际业务产出,却会持续消耗CPU算力。 - PostgreSQL连接数设置过高,引发数据库端资源争抢
单实例PostgreSQL设置800个max_connections,每个连接都需要独立的内存分配、调度上下文,连接数过高时会出现大量的锁等待、连接上下文切换,仅数据库端的调度开销就会吃掉近半CPU,不需要这么高的连接配置。
快速定位调试步骤
- 执行
top -H命令,按CPU占用排序,区分清楚算力消耗来自Nginx、Gunicorn还是PostgreSQL进程。 - 执行
vmstat 1观察输出的cs(上下文切换频率)字段,如果单秒上下文切换数超过10万,即可验证进程过多引发调度开销的判断。 - 执行
ipcs -m查看当前系统的共享内存分配状态,确认PostgreSQL有没有成功申请到对应规格的共享内存段。 - 执行
ss -s查看当前系统的连接数、文件句柄实际使用量,确认是不是触发了资源上限导致的重试开销。
可直接落地的配置修正参考
- Gunicorn参数调整:将
NUM_WORKERS设置为145(基于72vCPU的2*CPU核数 +1通用最优经验值),如果业务为IO密集型可适当上调到180,不建议超过200;同时追加--max-requests 1000参数,避免长时间运行的worker出现内存泄漏。 - Nginx参数调整:将
worker_processes修改为auto(自动匹配vCPU核数),events块内的worker_connections调整为2048即可满足需求,将worker_rlimit_nofile上调为65535。 - 内核参数调整:将
kernel.shmmax调整为68719476736(约64GB),匹配144GiB内存实例的共享内存申请需求;将fs.file-max上调为1048576,覆盖高并发场景的句柄消耗。 - PostgreSQL参数调整:将
max_connections下调到200-300区间,将shared_buffers设置为总内存的25%也就是36GB左右,预留足够内存给系统缓存、连接使用,不需要设置到50000MB这么高。
内容的提问来源于stack exchange,提问作者Prashant Pandey
相关产品推荐
相关产品推荐

