加速django中的第一页加载

时间:2009-11-09 17:38:17

标签: python django performance mod-wsgi pageload

当我更新我网站上的代码时,我(自然地)重启我的apache实例,以便更改生效。

不幸的是,每个apache实例提供的第一个页面都非常慢,而它第一次将所有内容加载到RAM中(此特定站点为5-7秒)。

后续请求只需0.5到1.5秒,所以我想为我的用户消除这种影响。

是否有更好的方法将所有内容加载到RAM而不是执行wget x次(其中x是我在http.conf中由ServerLimit定义的apache实例的数量)

编写一个重新启动apache并运行wget 5次的重启脚本对我来说似乎有些不好看。

谢谢!

2 个答案:

答案 0 :(得分:32)

Apache / mod_wsgi的默认设置是仅在第一次请求时将应用程序代码加载到需要该应用程序的进程。因此,第一步是配置mod_wsgi以在进程启动时预加载代码,而不仅仅是第一个请求。这可以使用WSGIImportScript指令在mod_wsgi 2.X中完成。

假设守护进程模式,无论如何这是更好的选择,这意味着你会有类似的东西:

# Define process group.

WSGIDaemonProcess django display-name=%{GROUP}

# Mount application.

WSGIScriptAlias / /usr/local/django/mysite/apache/django.wsgi

# Ensure application preloaded on process start. Must specify the
# process group and application group (Python interpreter) to use.

WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
  process-group=django application-group=%{GLOBAL}

<Directory /usr/local/django/mysite/apache>

    # Ensure application runs in same process group and application
    # group as was preloaded into on process start.

    WSGIProcessGroup django
    WSGIApplicationGroup %{GLOBAL}

    Order deny,allow
    Allow from all
</Directory>

当您更改代码时,不要触摸仅在下一个请求中检查的WSGI脚本文件,而是向守护进程组中的进程发送SIGINT信号。

使用WSGIDaemonProcess的'display-name'选项,您可以使用BSD样式'ps'程序识别哪些进程。将'display-name'设置为'%{GROUP}'时,'ps'输出应显示'(wsgi:django)'作为进程名称。确定进程ID并执行:

kill -SIGINT pid

使用实际进程ID交换'pid'。如果守护程序进程组中有多个进程,则向所有进程发送信号。

不确定是否可以使用'killall'一步完成此操作。我在MacOS X上执行此操作时遇到了问题。

在mod_wsgi 3.X中,配置可以更简单,也可以使用:

# Define process group.

WSGIDaemonProcess django display-name=%{GROUP}

# Mount application and designate which process group and
# application group (Python interpreter) to run it in. As
# process group and application group named, this will have
# side effect of preloading application on process start.

WSGIScriptAlias / /usr/local/django/mysite/apache/django.wsgi \
  process-group=django application-group=%{GLOBAL}

<Directory /usr/local/django/mysite/apache>
    Order deny,allow
    Allow from all
</Directory>

也就是说,不需要使用单独的WSGIImportScript指令,因为特定的进程组和应用程序组可以作为WSGIScriptAlias的参数,而不是副作用,它将预加载应用程序。

答案 1 :(得分:3)

你是如何运行Django的(mod_python vs mod_wsgi)?

如果您正在运行mod_wsgi(在守护程序模式下),则无需重新启动Apache即可重新加载应用程序。您需要做的就是更新wsgi脚本的mtime(使用touch可以轻松完成)。

mod_wsgi的文档对该过程有一个非常详尽的解释:

ReloadingSourceCode