介绍
Drupal 是一个用 PHP 编写的开源内容管理框架和平台。 用于为任何规模的网站和 Web 应用程序等构建丰富的、基于后端的解决方案,它非常受欢迎,具有极高的采用率统计数据。 它在 GNU 通用公共许可证下的分发意味着任何人都可以免费使用该软件,以各种方式为项目做出贡献,并与他人共享。 Drupal 的主要发行版称为 Drupal Core,截至 2013 年 10 月,它可以扩展,拥有超过 20000 个模块和近 2000 个主题。
利用 Drupal 等平台快速原型化和开发应用程序非常棒。 然而,同样迅速地,诸如解决产品增长之类的问题开始出现。 这将要求您快速扩展以继续快速为您的客户服务,以保持他们对您的产品的兴趣并保持他们的幸福感。
在这篇 DigitalOcean 文章中,作为 帮助开发人员进行缩放 系列的一部分,我们将讨论使用 Drupal 配置 Varnish。 这将大大减少用户加载基于 Drupal 的网站所需的时间,并通过首先通过 Varnish Cache 软件传递请求来增加 DigitalOcean VPS 的同时服务容量。
缩放
在谈论软件方面的扩展时,人们通常的意思是[系统的] 处理和容纳大于其构建的工作量(待处理)和数据(待处理)的能力。实时或以后保存和使用)。 关于网络,问题的定义和识别变得更简单,尽管实施彻底的解决方案通常成本更高,因为它可能需要进一步将硬件结合到系统中。
缩放网页(或 Web 应用程序)的两种最常见的方法是:Vertical 和/或 Horizontal 缩放。
垂直缩放(放大!)
简而言之,垂直缩放意味着通过向它们添加更多资源或增加它们的容量来增加作为我们服务器的单台计算机或垂直构成我们系统的任何计算机的资源。 添加更多内存,用更快的 CPU 替换 CPU,获得更高容量和更快的驱动器以及出色的读写速度(例如 我们的 DigitalOcean Droplets 的 SSD)都可以被视为垂直缩放。 有时,这也称为 Scaling Up。
水平缩放(向外扩展!)
当我们决定利用当今私有服务器的极低价格并将更多的私有服务器整合到我们的系统中时,它被称为 Horizontal Scaling,或“Scaling Out”。 这可能以多种方式发生,例如在自己的机器上运行我们应用程序堆栈的每个软件或克隆 Web 服务器以创建其他几个相同的服务器,并通过使用反向代理在它们之间分配来自客户端的传入请求,比如 NGINX。 有关反向代理的更多信息,请访问 http://en.wikipedia.org/wiki/Reverse_Proxy。
漆
坐在您的网站前面,Varnish Cache 直接处理提供静态或准静态内容,而无需将请求传回 Web 服务器(即 Apache)来一遍又一遍地处理。 由于大量内容(尽管它们将被访问的时间量)只需要计算和生成一次,因此从快速访问内存中存储并提供它们极大地减少了 Web 服务器的负载并增加了请求量这可以由我们的整个系统同时处理。
Varnish 如何提供帮助?
在(几乎)任何网站中使用 Varnish 意味着通过多种力量(当然取决于架构!)更快的网站。 由于 Varnish Cache 的扩展功能,这也意味着更可靠的产品(原因您将在配置过程中看到)。 所有这一切都转化为更快乐的客户,他们更喜欢使用您的产品,以及您可以更好地依靠交付的系统。
注意: 除非我们为 Varnish 使用单独的应用程序服务器实例(出于许多 好 的原因,我们应该这样做!)从技术上讲,这不是扩展的(既不向上,也不向外),但是具有良好的系统架构并且基本上是智能的。 但是,由于单个服务器可以处理的负载增加,这在某些方面可以称为扩展,因为我们的系统将获得更好的整体性能。 这确实是扩展所期望的结果,我们最终得到了一个可以在必要时真正扩展的系统架构; 但是,必须注意,更好的性能本身并不意味着可扩展。
1. 为 Varnish 准备 Web 服务器
在本文中,我们的目标是设置 Varnish 以直接从内存中快速提供页面。 这被称为 caching 并且为了使其工作,Varnish 需要能够首先处理传入的请求。 鉴于您的网络服务器(例如。 Apache)被设置为做完全相同的事情(处理传入的请求),我们需要对 Varnish 进行一些修改以取代它。 实现这一点的方法是修改它监听的端口(即 端口 80)。
修改 Apache
默认情况下,Apache 在(监听)端口 80 上运行,我们需要对其进行修改。
在ports.conf上修改Apache的设置:
我们需要修改的端口设置定义在一个名为 ports.conf 的文件中,该文件位于 /etc/apache2/
文件夹中。
让我们使用文本编辑器对其进行修改。 我们将在这里使用 nano,与其他一些相比,它以用户友好性着称。
运行以下命令打开编辑器编辑ports.conf文件的内容:
sudo nano /etc/apache2/ports.conf
在此文件中(默认情况下),您应该会看到类似于以下内容的内容:
NameVirtualHost *:80 Listen 80 <IfModule mod_ssl.c> # If you add NameVirtualHost *:443 here, you will also have to change # the VirtualHost statement in /etc/apache2/sites-available/default-ssl # to <VirtualHost *:443> # Server Name Indication for SSL named virtual hosts is currently not # supported by MSIE on Windows XP. Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule>
所以继续修改指定端口号的前两行,从原来的到,比如说,8000(记住这个数字):
NameVirtualHost *:8000 Listen 8000
现在为了保存并关闭,按 CTRL+X 并在出现提示时键入 Y 然后按 enter。 这将保存文件。
如果您还有 Virtual Host (vhost) 配置
如果您托管多个网站(或设置了特定于域的选项),您很可能拥有我们需要更新的 Virtual Host 配置。
运行以下命令以打开编辑器以编辑您站点的设置:
sudo nano /etc/apache2/sites-availbable/my-domain-dot-com
!! 不要忘记将 my-domain-dot-com 替换为适当的名称。
!! 如果您没有自定义命名虚拟主机配置,您可以在 /etc/apache2/sites-available/default
上找到默认设置。
根据您当前的设置,您将看到一个以(或包含)以下内容开头的文档:
<VirtualHost *:80>
我们现在需要用 ports.conf 中的 相同的端口替换它:
<VirtualHost *:8000>
按 CTRL+X 关闭并保存文件,然后键入 Y 并按相同的方式回车。
为了使更改生效,我们需要重新启动 Apache:
sudo service apache2 reload
截至目前,Apache 将在新设置的端口 8000 上接受传入请求。 我们已准备好进入下一步!
2. 安装清漆缓存
对于 Debian 和 Ubuntu:
在 Debian 和 Ubuntu 上设置 Varnish 非常简单,因为它与默认的系统包管理器一起分发:apt。 但是,为了确保我们获得最新版本,推荐的方法如下(参考。 https://www.varnish-cache.org/installation/debian):
我们需要将 Varnish 的下载 URL 添加到 aptitude 包管理器的源列表中。 为了验证来源,我们首先需要添加http://repo.varnish-cache.org提供的安全密钥。
让我们从添加安全密钥 [Debian 和 Ubuntu] 开始:
wget http://repo.varnish-cache.org/debian/GPG-key.txt apt-key add GPG-key.txt
现在将包 URL 添加到 apt-get 存储库源列表。
德比安:
echo "deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0" >> /etc/apt/sources.list
Ubuntu:
echo "deb http://repo.varnish-cache.org/ubuntu/ precise varnish-3.0" | sudo tee -a /etc/apt/sources.list
最后,让我们更新包管理器并下载/安装 Varnish Cache [Debian 和 Ubuntu]
apt-get update apt-get install varnish
3. 修改 Varnish 的设置
在修改 Apache 的端口并安装 Varnish 之后,我们准备继续修改 Varnish 的设置,以使其按照我们需要的方式运行。
将清漆放入生产模式
作为允许管理员在安装时测试 Varnish 的原因之一,默认设置是 而不是 设置为在前置端口 80 上运行,我们需要更改它。
Debian 和 Ubuntu 上的配置文件位于 /etc/default/varnish
。
打开编辑器编辑文件:
nano /etc/default/varnish
运行此命令后,您将看到一个相当长但不言自明的文档。 如果向下滚动,您将看到以文本 DAEMON_OPTS 开头的定义 Varnish daemon 选项的文本块,类似于:
DAEMON_OPTS="-a :6081 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m"
让我们修改它以将端口从 6081 更改为 80:
DAEMON_OPTS="-a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m"
VCL 语言和文件
Varnish 使用包含用 VCL 语言编写的指令的 .vcl 文件(默认位于 /etc/varnish/
为 default.vcl
)以运行其程序。 这用于定义 Varnish 应如何处理请求以及文档 缓存 系统应如何工作。 当一组新指令(通过 .vcl 文件)被加载时,由 Varnish 旋转的(管理器)进程将它们转换为 C 代码 并编译它——然后习惯于做这项工作。
修改/etc/varnish/
下的默认VCL文件
VCL 语言和文件一开始可能看起来很复杂,因为可以为 Varnish 定义大量的任务来执行。 幸运的是,我们在 https://www.varnish-cache.org/trac/wiki/VCLExamples 上提供了很多很棒的示例,并附有模式(对于某些)。 如果您对想要 Varnish 做什么有任何疑问或想法,阅读其中一些示例肯定会让您轻松地按照您需要的方式解决它。
话虽如此,对于 Drupal(以及大多数网站)的或多或少的默认配置组合,我们将使用可以在下面找到的设置。 复制并粘贴每个代码块中的所有代码以形成您的 .vcl 文件。
让我们再次打开我们的编辑器来修改 Drupal 的 default.vcl
(位于 /etc/varnish/ 下)的内容。
为了打开编辑器,运行以下命令:
nano /etc/varnish/default.vcl
您将看到一个包含默认设置的长文档。
首先,我们需要定义我们的 Web 服务器并告诉 Varnish 如何联系它。 所以让我们修改 backend default
部分:
backend default { .host = "127.0.0.1"; .port = "8000"; .max_connections = 250; .connect_timeout = 300s; .first_byte_timeout = 300s; .between_bytes_timeout = 300s; }
注意: 在下面,你会看到一大块被注释掉的默认 VCL 配置代码。 只要您没有错误地取消注释,您就可以保留它,在这种情况下编译它会产生错误。
我们现在将设置允许的清除客户端地址(请参阅以下问题以了解有关 purging 的更多信息):
acl purge { "localhost"; "127.0.0.1"; }
为了定义可以访问 cron.php 或 install.php 的允许地址,请附加以下内容:
acl internal { "192.10.0.0"/24; # For remote access, add your IP address here. # Ex: 162.xxx.xx.xx }
在这里,我们将编写程序来处理来自客户端的传入(接收)请求。 继续附加以下代码块:
sub vcl_recv { # A great functionality of Varnish is to check # your web server's health and serve stale pages # if necessary. # In case of web server lag, let's return the # request with stale content. if (req.backend.healthy) { set req.grace = 60s; } else { set req.grace = 30m; } # Modify (remove) progress.js request parameters. if (req.url ~ "^/misc/progress\.js\?[0-9]+$") { set req.url = "/misc/progress.js"; } # Modify HTTP X-Forwarded-For header. # This will replace Varnish's IP with actual client's. remove req.http.X-Forwarded-For; set req.http.X-Forwarded-For = client.ip; # Check if request is allowed to invoke cache purge. if (req.request == "PURGE") { if (!client.ip ~ purge) { # Return Error 405 if not allowed. error 405 "Forbidden - Not allowed."; } return (lookup); } # Verify HTTP request methods. if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE" && req.request != "PURGE") { return (pipe); } # Handling of different encoding types. if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { remove req.http.Accept-Encoding; } elsif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } elsif (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { remove req.http.Accept-Encoding; } } # Force look-up if request is a no-cache request. if (req.http.Cache-Control ~ "no-cache") { return (pass); } # Do not allow outside access to cron.php or install.php. Depending on your access to the server, you might want to comment-out this block of code for development. if (req.url ~ "^/(cron|install)\.php$" && !client.ip ~ internal) { # Throw error directly: error 404 "Page not found."; # Or; # Use a custom error page on path /error-404. # set req.url = "/error-404"; } # Remove certain cookies. set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "Drupal.toolbar.collapsed=[^;]+(; )?", ""); set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", ""); if (req.http.cookie ~ "^ *$") { unset req.http.cookie; } # Cache static content of themes. if (req.url ~ "^/themes/" && req.url ~ ".(css|js|png|gif|jp(e)?g)") { unset req.http.cookie; } # Do not cache these URL paths. if (req.url ~ "^/status\.php$" || req.url ~ "^/update\.php$" || req.url ~ "^/ooyala/ping$" || req.url ~ "^/admin" || req.url ~ "^/admin/.*$" || req.url ~ "^/user" || req.url ~ "^/user/.*$" || req.url ~ "^/users/.*$" || req.url ~ "^/info/.*$" || req.url ~ "^/flag/.*$" || req.url ~ "^.*/ajax/.*$" || req.url ~ "^.*/ahah/.*$") { return (pass); } # Cache the following file types. if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(\?[a-z0-9]+)?$") { unset req.http.Cookie; } # !! Do not cache application area if (req.url ~ "(^/app.php|^/app_dev.php|^)/([a-z]{2})/(payment|order|booking|media|autocomplete|monitor).*") { return (pass); } # !! Do not cache admin area if (req.url ~ "(^/app.php|^/app_dev.php|^)/admin" || req.url ~ "(^/app.php|^/app_dev.php|^)/(([a-z]{2})/admin)") { return (pass); } # !! Do not cache security area if (req.url ~ "(^/app.php|^/app_dev.php|^)/(([a-z]{2}/|)(login|logout|login_check).*)") { return (pass); } # Do not cache editor logged-in user sessions if (req.http.Cookie ~ "(sonata_page_is_editor)") { return (pass); } return (lookup); } sub vcl_hit { if (req.request == "PURGE") { purge; error 200 "Purged."; } } sub vcl_miss { if (req.request == "PURGE") { purge; error 200 "Purged."; } }
运行清漆
现在我们准备重启 Varnish 守护进程。
运行以下命令让 Varnish 运行:
/etc/init.d/varnish restart
验证应用程序的状态
让我们运行以下两个命令来验证 Apache 和 Varnish 是否都绑定到正确的端口:
阿帕奇:
netstat -lp | grep apache2
漆:
netstat -lp | grep varnish
结果应类似于以下内容:
tcp 0 0 localhost:8000 *:* LISTEN xxxx/apache2 -- or -- tcp6 0 0 [::]:8000 [::]:* LISTEN xxxx/apache2 -- and -- tcp 0 0 localhost:6082 *:* LISTEN xxxx/varnishd tcp 0 0 *:http *:* LISTEN xxxx/varnishd tcp6 0 0 [::]:http [::]:* LISTEN xxxx/varnishd
最后
我们已经设置了 Apache 和 Varnish 来配合我们的 Drupal 安装。 如果您想从 Drupal 后端获得更多关于 Varnish 的信息,您可能想尝试位于 https://drupal.org/project/varnish 的 Drupal Varnish 模块。
截至 2013 年 10 月,此模块的作用如下:
- 该模块提供管理套接字集成,允许 Drupal 动态地使缓存条目无效,还允许您查询 Varnish 管理界面的状态等。
注意: 如果您使用的是旧于版本 7 的 Drupal 系统,由于 Drupal 向访问者处理 cookie 的方式,您还需要使用此模块。
故障排除、注释和提示
如何找到我的 Linux 发行版及其版本?
由于本文讨论了多个发行版和版本,因此您可能需要确保您的目标是正确的。 幸运的是,解决方案相当简单。 只需运行以下命令:
cat /etc/*-release
这应该给你你的发行版的名称和版本。
在哪里可以了解有关 Apache 虚拟主机 (vhosts) 的更多信息?
For more information on Virtual Hosts files, please visit http://httpd.apache.org/docs/2.2/vhosts/examples.html and how-to-set-up-apache-virtual-hosts-on-ubuntu-12-04-lts respectively.
如何决定使用哪个端口? 我在哪里可以了解有关端口的更多信息?
您几乎可以选择您想要的任何端口,但最好避免使用某些端口,以防止将来出现问题或与其他应用程序发生冲突。 其中一些端口是:
- 简单邮件传输协议 (SMTP) 在 端口 25
- 网络新闻传输协议 (NNTP) 同步 在 端口 119
- HTTP over TLS/SSL (HTTPS) 在 端口 443
- MySQL 数据库系统 在 端口 3306
完整列表请参考: http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
就 Varnish 的功能而言,清除意味着什么?
清除是缓存文件的失效。 有关该主题的更多信息,请参阅:https://www.varnish-cache.org/docs/3.0/tutorial/purging.html
什么是 守护进程 ?
在计算中, 守护进程 是一个后台进程,它自己运行而不是与用户直接交互。 在 Varnish 的例子中,它的守护进程在编译 VCL 配置文件后会持续运行,就像你的 web 服务器一样执行预先设置和编译的指令。