Python 与流程工人一起关闭uwsgi/gunicorn时,可用内存(可用)急剧下降,CPU峰值增大 主旨
当我开始使用写时拷贝来启动一群wsgi工作人员时,每当我需要重新启动主进程时,他们就会发疯并使用大量的CPU和内存。这会导致OOM错误,我希望避免它。我在uwsgi和gunicorn进行了测试,我看到了同样的行为 问题 我有一个Web应用程序,它有一些内存密集的基于进程的工作程序,因此我在gunicorn中使用了Python 与流程工人一起关闭uwsgi/gunicorn时,可用内存(可用)急剧下降,CPU峰值增大 主旨,python,linux,gunicorn,uwsgi,copy-on-write,Python,Linux,Gunicorn,Uwsgi,Copy On Write,当我开始使用写时拷贝来启动一群wsgi工作人员时,每当我需要重新启动主进程时,他们就会发疯并使用大量的CPU和内存。这会导致OOM错误,我希望避免它。我在uwsgi和gunicorn进行了测试,我看到了同样的行为 问题 我有一个Web应用程序,它有一些内存密集的基于进程的工作程序,因此我在gunicorn中使用了--preload,在uwsgi中使用了默认行为,以便在分叉之前完全加载应用程序,以便在进程之间启用写时拷贝,从而节省内存使用量 当我关闭主进程(例如通过SIGINT或SIGTERM)时
--preload
,在uwsgi中使用了默认行为,以便在分叉之前完全加载应用程序,以便在进程之间启用写时拷贝,从而节省内存使用量
当我关闭主进程(例如通过SIGINT或SIGTERM)时,所有工作进程的CPU使用率都会急剧上升,我的机器(Ubuntu 16.04,但也在Debian 10上测试过)会丢失大量可用内存。这通常会导致OOM错误。我看不到每个worker的RES有任何增加,但可用mem的下降大致与我所期望的相符,如果每个worker的所有内存都被完全复制,然后在其关闭期间立即取消分配。我希望避免内存使用突然激增,并充分享受写时拷贝的好处
测试环境
我有一个非常简单的烧瓶应用程序,您可以使用它来测试:
from flask import Flask
application = Flask(__name__)
my_data = {"data{0}".format(i): "value{0}".format(i) for i in range(2000000)}
@application.route("/")
def index():
return "I have {0} data items totalling {1} characters".format(
len(my_data), sum(len(k) + len(v) for k, v in my_data.items()))
您可以使用以下任一命令启动应用程序:
$ gunicorn --workers=16 --preload app:application
$ uwsgi --http :8080 --processes=16 --wsgi-file app.py
当我在终端的主进程上执行^C并跟踪top报告的“空闲”KiB Mem时,我会看到可用内存的大幅下降和CPU使用率的急剧上升。请注意,报告的每个工作进程的内存使用情况没有变化。有没有办法安全地重新启动uwsgi/gunicorn,这样就不会出现内存和CPU峰值
复制步骤:
- 启动前,在我的机器上免费安装5.7GB
- 启动后在我的机器上免费使用5.3GB
- 进程关闭时可用1.3GB(以及CPU使用率峰值)
- 所有进程实际关闭后(2-5秒后)5.7GB可用空间
你可以试试SIGTERM(
kill-15yourpidhere
),这是一种更温和的关机方式,我尝试了一下,得到了同样的内存密集型关机行为。