加速Django中首页加载速度

22 投票
2 回答
5757 浏览
提问于 2025-04-15 15:49

当我更新我网站的代码时,我会(很自然地)重启我的apache实例,这样更改才能生效。

不幸的是,每个apache实例第一次提供的页面加载速度比较慢,因为它需要把所有东西都加载到内存里(对于这个特定的网站,大约需要5到7秒)。

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

有没有比用wget命令执行x次(这里的x是http.conf文件中ServerLimit定义的apache实例数量)更好的方法来让所有内容都加载到内存里呢?

我觉得写一个重启apache并运行wget 5次的脚本有点像是临时解决办法。

谢谢!

2 个回答

3

你是怎么运行Django的?是用mod_python还是mod_wsgi?

如果你是用mod_wsgi(在守护进程模式下),那么重启Apache服务器并不是必须的来重新加载你的应用程序。你只需要更新一下你的wsgi脚本的修改时间(这可以通过简单的touch命令来完成)。

mod_wsgi的文档里对这个过程有很详细的解释:

ReloadingSourceCode

32

Apache和mod_wsgi的默认设置是,只在第一次请求时加载应用程序代码,这样会导致应用程序的启动变得比较慢。所以,第一步是要配置mod_wsgi,让它在进程启动时就预加载你的代码,而不是等到第一次请求时再加载。这个可以在mod_wsgi 2.X版本中通过使用WSGIImportScript指令来实现。

假设你使用的是守护进程模式,这种方式更好,这样你就可以像下面这样设置:

# 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

把'pid'替换成实际的进程ID。如果守护进程组中有多个进程,就要给它们全部发送信号。

不太确定'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,这样的副作用就是它会预加载应用程序。

撰写回答