Ubuntu20.04下Apache2+mod_wsgi部署Flask多用户崩溃问题优化
这种单用户正常、一上并发就崩的情况我之前部署Flask应用时也踩过坑,大概率是mod_wsgi的Apache配置没跟上,或者应用本身有资源泄漏的问题,咱们一步步来排查解决:
第一步:检查mod_wsgi的Apache进程/线程配置(最常见诱因)
mod_wsgi在Apache下运行时,默认的进程数、线程数往往不足以支撑并发请求,一旦耗尽连接就会抛出503 Service Unavailable。
- 打开你的Flask应用虚拟主机配置文件(通常路径是
/etc/apache2/sites-available/your-flask-app.conf),找到WSGIDaemonProcess和WSGIProcessGroup配置段。 - 默认配置可能类似这样(资源分配过少):
可以根据服务器CPU核心数调整参数(比如4核服务器,进程数设为4,线程数设15-20):WSGIDaemonProcess flask-app user=www-data group=www-data threads=5 WSGIProcessGroup flask-appWSGIDaemonProcess flask-app user=www-data group=www-data processes=4 threads=15 display-name=%{GROUP} WSGIProcessGroup flask-app - 同时检查Apache全局连接配置,打开
/etc/apache2/apache2.conf,调整以下参数(以mpm_prefork模块为例,若用mpm_event/worker模块参数略有差异):KeepAlive On KeepAliveTimeout 5 MaxKeepAliveRequests 100 <IfModule mpm_prefork_module> StartServers 4 MinSpareServers 2 MaxSpareServers 8 MaxRequestWorkers 100 MaxConnectionsPerChild 1000 </IfModule> - 修改完成后重启Apache生效:
sudo systemctl restart apache2,再重新做负载测试验证。
第二步:排查Flask应用的资源泄漏问题
单用户正常、多用户崩溃,很可能是应用存在未释放的资源或线程不安全的代码:
- 数据库连接检查:如果用了SQLAlchemy等ORM,确保启用连接池,且请求结束后正确释放连接(比如调用
db.session.remove(),或依赖Flask-SQLAlchemy的自动会话管理)。 - 全局变量风险:避免使用全局的非线程安全对象(比如全局数据库连接、自定义缓存),这类对象在并发场景下会引发资源竞争导致崩溃,建议改用Flask的
g对象(线程本地存储)存储请求级别的数据。 - 文件/网络资源管理:检查代码中是否有打开文件/网络连接后未关闭的情况,推荐用
with语句自动管理资源:with open('data.txt', 'r') as f: content = f.read() - 内存泄漏排查:用
htop或ps aux观察负载测试时Apache/mod_wsgi进程的内存占用,若内存持续上涨不回落,可借助memory_profiler工具定位具体泄漏的函数。
第三步:查看更详细的错误日志
你提到的“Services Unavailable”是前端提示,Apache的错误日志里有更精准的故障信息:
- 实时查看错误日志:
sudo tail -f /var/log/apache2/error.log,同时运行负载测试,留意是否出现类似“server reached MaxRequestWorkers setting”、“WSGI daemon process died”的日志,这些能直接定位问题根源。 - 可开启mod_wsgi详细日志辅助排查,在虚拟主机配置中添加:
重启Apache后,日志会记录mod_wsgi的运行细节。WSGILogLevel info
第四步:确认使用mod_wsgi守护进程模式
如果你的配置中没有WSGIDaemonProcess,说明用的是Apache嵌入模式,这种模式下Flask请求由Apache主进程直接处理,稳定性极差。一定要切换到守护进程模式,让Flask运行在独立进程中,与Apache主进程隔离:
<VirtualHost *:80> ServerName your-domain.com WSGIDaemonProcess flask-app user=www-data group=www-data processes=4 threads=15 WSGIProcessGroup flask-app WSGIScriptAlias / /var/www/flask-app/wsgi.py <Directory /var/www/flask-app> Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/flask-app-error.log CustomLog ${APACHE_LOG_DIR}/flask-app-access.log combined </VirtualHost>
第五步:验证负载测试工具的正确性
有时候测试工具的配置也会导致异常,推荐用Apache自带的ab工具做基准测试,排除工具干扰:
ab -n 100 -c 5 http://your-domain.com/
其中-n是总请求数,-c是并发数,用这个工具测试看是否复现问题。
如果以上步骤都试过仍未解决,可以把error.log中的详细错误信息贴出来,能更精准地定位问题~
内容的提问来源于stack exchange,提问作者Ahmad Ahsan Saleem
相关产品推荐
相关产品推荐

