入门
你已经部署Django到你的Droplet和生活是好的。你碰到了一些性能问题,网站的流量增长,但你
发现的瓶颈和固定它。不过,您的网站流量持续增长。不知何故你需要更多的性能...你能做什么? 让我们深入了解我们的应用程序和服务器配置的内容。本文是基于您使用Ubuntu 12.04的假设编写的,但这些原则适用于任何版本的Linux。 如果你使用Apache,那么你应该遵循这些指令
优化你的网络服务器 。如果你使用Nginx,这些提示也会为你工作。
缓存一切
如果您已经创建了一个CMS来管理您的网站,那么您可能容忍非常积极的缓存。在这种情况下,我最喜欢的工具是Varnish,一个位于Apache或Nginx前端的前端缓存。在这种情况下,看看这个现有 和本
教程Nginx的 (是的,关于PHP Nginx的文章会谈,但它会为Django的工作太)。 缺点是,Varnish,除非你仔细配置,将缓存您的整个网站。如果你有动态内容,例如如果你的网站更多的是一个应用程序,varnish可以造成很多麻烦。假设用户A访问该网站并将一个项目添加到他们的购物车。然后,用户B访问该网站,并查看其中包含用户A的项目的购物车的缓存版本。不好。 另一个缺点是,Django,默认情况下,试图强制上游缓存从缓存的内容,这导致一场战斗结束在不稳定的行为。 但我有个好消息:Django的有它自己的高速缓存架构 ,这将使你两件事。
- 它将使您的应用程序更易于缓存,使它与Varnish(如果你选择使用它)
- 它将让您控制网站的哪些部分缓存
如果你使用更小的Droplet,我建议使用数据库缓存。它很容易打开,并避免需要运行另一个服务器进程。如果你有足够的RAM
memcached提供了极佳的缓存后端。本文将演示基于数据库的缓存。 请阅读上面链接的文档,了解许多优秀的细节,但这里是您需要做的开始。 为缓存创建数据库表。在这种情况下,我们的表称为“cache_table”:
python manage.py createcachetable cache_table
现在编辑您的settings.py文件并通过添加以下行来配置缓存:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'cache_table',
}
}
还有可配置的其他配置选项。阅读他们的
文档 。我特别查看TIMEOUT和CULL_FREQUENCY。 现在你需要决定要缓存什么。如果你只是想使您的网站的工作更加精美,Varnish然后检查了每个站点的缓存配置 。但是这不是很令人兴奋,所以让我们深入到每个视图的缓存。 假设您有一个购物车产品页面,很少更改,并不是很动态。有一个名为观点
product_detail(request, product_id)
这将是完美的缓存。 您可以使用简单的装饰器为此启用缓存:
from django.views.decorators.cache import cache_page
@cache_page(60 * 60)
def product_detail(request, product_id):
...
这将允许该视图被缓存60分钟(60秒* 60分钟)。 再次,我想引用文档一些极好的提示 。 一个特别强大的功能是有所不同的基础上头 。如果您有一个网站被翻译成多种语言,或根据浏览器版本显示不同的内容,这可以是一个很大的帮助。
关于内容变化频繁?
如果您有半动态网站,例如您的应用程序收到很多评论或数据经常刷新,您可能会担心使用缓存。这是一个有效的关注。 首先确定可以缓存的所有视图,然后缓存它们。 第二,确定延迟时间可以容忍某人看到过时的内容。例如,具有活动评论的网站可能容许延迟1到5分钟。缓存页面只要可以。 你会惊讶,即使缓存超时10秒可以是非常有帮助的。在许多情况下,突然过载的繁忙站点通常被到达特定页面的流量攻击。 如果10,000个人在一分钟内访问您网站上的某个网页,那么当对数据库的所有查询都立即运行时,它会融化您的服务器。如果您设置了10秒的缓存,则意味着页面将每分钟仅重新生成6次,而不管有多少人请求。任何服务器都可以做到这一点! 使用会话数据的电子商务网站和网站必须非常小心。调查
Vary标头的选项,看看是否可以缓存在你的情况下工作。不要害怕创造性! 网站有时会将所有HTML网页用作静态内容,并使用Ajax加载每用户会话信息。在电子商务网站的情况下,用户经常不会注意到,如果他们的购物车计数需要5秒来加载,只要他们可以正常浏览页面的其余部分。
提供静态内容
Django的内置开发服务器很高兴地提供静态内容。通常,我看到Django站点配置为供生产使用,静态内容由Django提供。 你唯一应该做的是如果你需要控制对内容的访问。但即使如此,考虑其他方式。
- 动态生成CSS -不,使用一个构建工具,如Grunt或更少的部署之前,建立你的CSS。 如果需要在服务器上生成周期性然后使用一个后台任务 。
- 经过身份验证的用户访问 -是的,你可能需要使用Django这一点。
- 一切 -不,让我们配置与您的Web服务器托管静态内容。
我不得不通过阅读文档静态文件前几次我知道了。我认为你应该自己阅读,但是如果你也努力,这里是一个场景,你可以使用: 在本地开发机器上,在“settings.py”中添加如下行:
STATIC_ROOT = os.path.join(BASE_DIR, "static")
然后运行manage.py命令这样:
python manage.py collectstatic
你现在应该在你的项目根目录中看到一个名为“静态”的文件夹,你会看到很多静态文件,如CSS和Javascript。特别是如果您已启用管理应用程序。 要使用这些文件,您需要配置Django,以便它知道在哪里查找它们。在settings.py文件夹中,您需要一个配置选项,如下所示:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
现在,如果你运行的开发者服务,并参观了管理区并查看任何页面的源代码,你应该看到,CSS文件正在从供应
/static/admin/css/
。 当你部署应用程序,你现在可以点Apache或Nginx的服务与
/静态/开头直接指向他们到文件的文件。 如果您的应用部署到
/ SRV / MyApp的/你所以具有一个名为
/srv/myapp/static/admin/css/base.css
那么你可以配置你的服务器是这样的:
Apache:
Alias /static/ "/srv/myapp/static/"
Nginx:
server {
...
location /static/ {
alias /srv/myapp/static/;
}
}
在这两种情况下,您只需将/ static / URL指向找到文件的硬盘驱动器上的精确位置。 Apache和Nginx可以比Django更快地提供这些服务。
使用uWSGI
如果我想快速发布网站,我使用Apache的mod_wsgi。如果我想要最好的性能,我使用uWSGI。如果你想知道如何发音,那就是“你威士忌”。 uWSGI是一个服务器进程,在Web服务器之外运行您的应用程序。对于Apache,您需要安装这些软件包:
sudo apt-get install uwsgi uwsgi-plugin-python uwsgi-plugin-cgi
如果您使用Apache作为您的网络服务器,也请安装:
sudo apt-get install libapache2-mod-uwsgi
一旦你做到了这一点,你会发现,你现在有两个新的文件夹进行配置:
/etc/uwsgi/apps-available
,并
/etc/uwsgi/apps-enabled
,就像你会看到你的虚拟主机配置与Apache或Nginx。 当你想创建一个新的应用程序,你把配置文件中
/etc/uwsgi/apps-available
,然后创建一个从启用应用程序,一个符号链接到它。 让我们假设你做了一个项目,称为newproject,你已经把它在
/srv/newproject
。 由于是典型的Django的项目,还有在settings.py文件
/srv/newproject/newproject/settings.py
。 创建一个名为`/etc/uwsgi/apps-available/newproject.ini的文件,并将其编辑为如下所示:
[uwsgi]
touch-reload = /tmp/newproject
socket = 127.0.0.1:3031
workers = 2
chdir = /srv/newproject
env = DJANGO_SETTINGS_MODULE=newproject.settings
module = django.core.handlers.wsgi:WSGIHander()
现在,创建一个名为的空文件
/tmp/newproject
:
touch /tmp/newproject
您必须通过将文件链接到启用应用程序来激活应用程序:
sudo ln -s /etc/uwsgi/apps-available/newproject.ini /etc/uwsgi/apps-enabled/newproject.ini
然后重新启动uWSGI:
sudo service uwsgi restart
如果你检查“ps ax”的输出,你应该看到一些与你的应用程序相关的进程。 请注意,如果您有多个应用程序在同一服务器上运行,那么您需要为每个应用程序的套接字使用不同的端口。 此外,如果你更新你的应用程序,你应该简单地“Touch”文件/ tmp / newproject和uWSGI将重新加载自身。 在任何时候,你可以查看
/var/log/uwsgi/app/newproject.log
看到信息的消息和错误。
Apache配置
如果您使用MOD
WSGI现在是关键时刻。
你应该禁用国防部 WSGI并启用mod_uwsgi。这可能会导致错误,因此在测试服务器上执行此操作,直到找到正确的配置。
sudo a2dismod wsgi
sudo a2enmod uwsgi
现在更新应用程式的设定。在你的apache配置你可能有这样一行:
WSGIScriptAlias / /srv/newproject/newproject.wsgi
你会更新为像这样:
SetHandler uwsgi-handler
uWSGISocket 127.0.0.1:3031
现在重新加载Apache配置:
sudo service apache2 reload
Nginx配置
在您的服务器配置中,您将需要用以下代码替换现有的wsgi指令:
uwsgi_pass 127.0.0.1:3031;
include uwsgi_params;
uwsgi_param UWSGI_SCHEME $scheme;
很简单!
uWSGI优点
使用uWSGI的一个美好的方面是,你可以限制应用程序在内存中运行的次数。通常有一个父进程,如果你使用上面共享的配置,2工人。如果您需要更多的工作,您可以简单地编辑应用程序的.ini文件,并增加“工人”的数量。然后重新加载uWSGI与“sudo服务uwsgi重新加载”更新更改。 在增加进程数之前,请考虑使用多少服务器内存。如果你运行mod_wsgi,你应该看到内存使用减少。看看uWSGI工作人员的大小。随着应用程序的使用,它们的大小趋于增加。不是因为内存泄漏,而是因为内存中的数据集很小。
最大化利用率
在应用程序预热并使用一段时间后,请检查服务器的内存利用率。 使用命令
free -m
,看看有多少内存被用于缓存/缓存与应用。键值是“免费”列中的顶部数字。理想情况下,繁忙的服务器将使用几乎所有的RAM。 如果你发现你有RAM空余,你的网站缓慢,那么挖掘什么是利用不足。 通常你会看到进程正在等待MySQL。可能需要为数据库分配更多的系统内存。这是非常常见的,因为MySQL的默认配置使用RAM非常少。 也有可能没有足够的RAM分配给磁盘缓存。你有不必要的进程占用内存吗?默认情况下,Linux将尽可能多地将RAM分配给磁盘缓存,当应用程序需要它时,会勉强放弃它。 在理想情况下,在内存受限VPS环境中永远不会发生这种情况,所有只读资产将在缓存中进行缓冲。因此摆脱不必要的后台进程。
包起来
您已经学习了一些缓存技术,包括使用Varnish缓存整个网站或在每个视图的基础上控制缓存设置。 您确保静态文件正在使用网络服务器,而不是Django。 您已经学会了如何使用uWSGI来通过从Web服务器中运行它来提高Django应用程序的性能。 (顺便说一句,感谢里卡多·帕斯卡尔对他的
优秀的Apache / uWSGI文档) 最后,您已经了解了为服务器应用程序分配尽可能多的内存,以最大限度地提高您的利用率。