启用在第一次请求之前初始化其他 python 模块 (Django + mod_wsgi + apache)

enable to initialize other python module before first request (Django + mod_wsgi + apache)

我是 Web 应用程序的新手,最近使用 Django + mod_wsgi 开发了一个简单的演示系统。 该项目如下所示:

django/
    |- manage.py
    |- mysite/
    |    |- url.py
    |    |- setting.py
    |    |- wsgi.py
    |- myapp/
         |- views.py
         |- taggers.py
         |- ...

这里是 myapp.conf 配置

WSGIDaemonProcess init python-home=/usr/local/.../3.5.0 python-path=/usr/local/.../django
WSGIProcessGroup init
WSGIImportScript /usr/local/.../django/mysite/wsgi.py process-group=init application-group=%{GLOBAL}
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias /myapp /usr/local/.../django/mysite/wsgi.py
<Directory /usr/local/.../django/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

这个demo做的事情很简单。给定一个输入,按下 'compute' 按钮,使用预加载的机器学习模型计算结果,该模型在 views.py 开始时加载。加载机器学习模型将涉及其他 python 模块,例如 sklearn 以及位于同一目录中的一些自制模块,例如 tagger.py。当我使用 'python3 manage.py runserver' 测试此演示时,一切正常。 Django先将机器学习模型加载到RAM中,比较耗时,等待传入的请求再计算。

但是当我使用 mod_wsgi + apache 时,我注意到当我启动 apache 时,只有 wsgi.py 被执行。直到第一次通过浏览器访问该演示系统时,才会加载机器学习模型(这意味着 views.py 尚未导入)。尽管第一次请求后一切看起来都很好,我的意思是不需要每次计算都加载机器学习模型,我仍然希望在 apache 启动后立即自动加载机器学习模型。 我看到有人在谈论伪造第一个请求,但我真的很想知道是否有其他解决方案,例如修改 wsgi.py.

总结一下我的问题。

  1. 我应该如何修改默认的wsgi.py以导入views.py以便预加载机器学习模型(直接导入views.py in wsgi.py 会导致错误,比如 'apps not installed' )

  2. 如果我别无选择,只能伪造请求,我应该在哪里以及如何写。

非常感谢。

按照 Daniel 在评论中所说的那样做,将预加载任何数据的代码移动到一个单独的模块中,并在加载时从 wsgi.py 脚本文件中的全局范围调用它。

您正在使用的配置将在进程启动时预加载 wsgi.py。您可以将配置简化为:

WSGIDaemonProcess init python-home=/usr/local/.../3.5.0 python-path=/usr/local/.../django
WSGIScriptAlias /myapp /usr/local/.../django/mysite/wsgi.py process-group=init application-group=%{GLOBAL}
<Directory /usr/local/.../django/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

WSGIScriptAlias 指令中同时使用 process-groupapplication-group 选项也会在进程启动时触发强制预加载 wsgi.py 脚本文件,而您不需要不需要单独的 WSGIImportScript.