需要处理大量的流量? 缓存应该是提高吞吐量最佳的方式之一。 意思是你的服务器不需要每次访问时从头开始重新生成相同的动态内容。 通过将缓存代理(如Varnish Cache)放在Web服务前面来对HTTP请求的响应加速并减少服务器工作负载,从而节省服务器资源。
Varnish工作在你的后端前面,比如Apache,Nginx还是别的什么。 如果Varnish找不到请求缓存,它会将请求转发到您的后端,然后缓存其输出。 您可以选择将这些缓存的请求存储在内存中,这会使它们的检索速度非常快。
安装
1.首先更新当前软件包并从apt安装Varnish:
- apt-get update
- apt-get upgrade
- apt-get install varnish
2.接下来我们要做的是编辑Varnish的守护进程选项,让它加载你的自定义配置:
- nano /etc/default/varnish
向下滚动到配置文件的这个块,找到当前的默认值:
/etc/default/varnish:
- ## Alternative 2, Configuration with VCL
- #
- # Listen on port 6081, administration on localhost:6082, and forward to
- # one content server selected by the vcl file, based on the request. Use a 1GB
- # fixed-size cache file.
- #
- DAEMON_OPTS="-a :6081
- -T localhost:6082
- -f /etc/varnish/default.vcl
- -S /etc/varnish/secret
- -s malloc,256m"
我们需要编辑-f选项。 将其更改为:
- -f /etc/varnish/user.vcl
或者你喜欢的任何名称。 重要的是让您的配置独立于默认的VCL文件,因为软件包更新可能会覆盖它。
从上面的配置,我们还看到Varnish将其缓存项存储在内存中,并且设置最多使用256MB的内存。 如果您需要调整此分配,只需编辑此行上的值:
- -s malloc,256m
稍后再编辑这些守护进程选项。 现在,让我们来配置Varnish的后端。
基本配置
Varnish通过Varnish配置语言(VCL)进行配置。 一旦配置文件被加载,Varnish将VCL代码翻译并编译成与Varnish进程并行运行的C程序。
让我们开始定制您的VLC。 首先将default.vcl复制到一个新文件:
- cd /etc/varnish
- cp default.vcl user.vcl
- nano user.vcl
配置后端
1.首先,先更改varnish的后端,如Apache。 这是Varnish将请求转发到的地方,也就是要缓存的内容来源。 在我们的示例中,我们的后端Apache运行在80端口,与Varnish在同一台服务器上,因此相应地更改后端:
- backend default {
- .host = "127.0.0.1";
- .port = "80";
- }
2.重新启动Varnish
- service varnish restart
3.默认情况下,Varnish在端口6081上运行,因此在Web浏览器中,访问服务器上的端口6081:
- http://example.com:6081
您应该会看到您网站的首页。 要确认您看到的是网站的缓存版本,请检查返回的响应头。 您应该会看到以下两个响应头:
- Via: 1.1 varnish
- Age: 10
配置缓存生存时间(TTL)
默认情况下,Varnish将缓存请求两分钟。 如果您想调整此项,请返回并打开您的VCL文件,并通过在后端声明下面添加此代码覆盖vcl_fetch子例程:
- sub vcl_fetch
- {
- set beresp.ttl = 5m;
- }
在从后端获取请求后调用此子例程。 您可以看到我们将对象TTL变量设置为五分钟。 值可以是秒(120秒),分钟(2分)或小时(2小时)。 您的理想TTL可能需要根据网站上的内容更新频率,网站的大小以及您需要处理的流量有所不同。
放置varnish到前端
如果上面的varnish配置能符合预期正常工作,那我们现在让Varnish和Apache交换端口,以便我们的网站的请求默认通过Varnish。
1.要更改Apache的端口,我们需要编辑/etc/apache2/ports.conf和任何存在的虚拟主机。 打开ports.conf以查找NameVirtualHost *:80和Listen 80,并把80端口更改为另一个端口。 我们将使用8080:
- NameVirtualHost *:8080
- Listen 8080
2.接下来,进入/etc/apache2/sites-available,并更改每个VirtualHost声明的开头,以更改新的端口号:
- <VirtualHost *:8080>
3.现在我们配置Varnish监听端口80。回到我们的守护进程选项文件(/etc/default/varnish),找到我们之前编辑的未注释的选项。 带-a标志的行指定端口号,更改为80:
- DAEMON_OPTS="-a :80
4.最后,我们需要编辑Varnish的后端配置,打开/etc/varnish/user.vcl并将后端配置更改为:
- backend default {
- .host = "127.0.0.1";
- .port = "8080";
- }
5.重启Apache和Varnish
- service apache2 reload
- service varnish restart
高级配置
VCL提供了对缓存请求的多种配置,并且可以根据需要对varnish进行一些自定义修改。 让我们来看一些常见的VCL修改,以及一些提示和技巧。
跳过某些请求的缓存
如果你的服务器运行多个网站,通常想要从Varnish的缓存中排除它们中的一些。 为此,我们将通过Varnish的请求对象来获取有关请求的信息,并根据条件告诉varnish将请求直接传递给后端。
我们需要在我们的VCL文件中覆盖vcl_recv子例程,每次Varnish收到请求时都运行它,然后添加一个条件:
- sub vcl_recv
- {
- if (req.http.host ~ "example.com" ||
- req.url ~ "^/admin")
- {
- return (pass);
- }
- }
你可以看到我们设置的不想缓存的两个条件。 第一个是针对example.com的任何请求,第二个是针对以/admin开头的任何URI请求。 如果这些都满足,Varnish不会缓存请求。
删除cookies
如前所述,如果Varnish检测到您的网站正在设置Cookie,它会假设您的网站需要与这些Cookie进行交互,并相应地显示动态内容,导致Varnish将不会缓存这些网页。 我们可以通过在Varnish的req.http对象清空Cookies。
将它添加到我们的VLC中的vcl_recv的底部:
- unset req.http.Cookie;
您可能会发现特定的Cookie对于显示内容很重要,或者用来确定您的用户是否已登录。 在这种情况下,您可能不想显示缓存的内容,只要将用户直接发送到后端。
对于这种情况,我们将检查req.http.Cookie一个名为“logged_in”的cookie,如果我们找到它,将请求直接传递到后端。 这里是我们整个vcl_recv子例程:
- sub vcl_recv
- {
- if (req.http.host ~ "example.com" ||
- req.url ~ "^/admin" ||
- req.http.Cookie ~ "logged_in")
- {
- return (pass);
- }
- unset req.http.Cookie;
- }
缓存POST还是不缓存POST?
很可能你不想缓存POST请求,因为他们可能需要与后端交互以收集动态数据或设置用户的会话。 在上面的例子中,我们选择不缓存请求,如果用户登录。我们需要确保他们可以登录。 一个简单的方法是跳过POST请求。
让我们将这个条件添加到我们现有的在vcl_recv中的return(pass)块:
- if (req.http.host ~ "example.com" ||
- req.url ~ "^/admin" ||
- req.http.Cookie ~ "logged_in" ||
- req.request == "POST")
- {
- return (pass);
- }
最终VCL文件
/etc/varnish/user.vcl:
- backend default {
- .host = "127.0.0.1"; # IP address of your backend (Apache, nginx, etc.)
- .port = "8080"; # Port your backend is listening on
- .probe = {
- .url = "/";
- .timeout = 34ms;
- .interval = 1s;
- .window = 10;
- .threshold = 8;
- }
- }
- sub vcl_recv
- {
- # Do not cache example.com, the admin area,
- # logged-in users or POST requests
- if (req.http.host ~ "example.com" ||
- req.url ~ "^/admin" ||
- req.http.Cookie ~ "logged_in" ||
- req.request == "POST")
- {
- return (pass);
- }
- # Don’t allow cookies to affect cachability
- unset req.http.Cookie;
- # Set Grace Time to one hour
- set req.grace = 1h;
- }
- sub vcl_fetch
- {
- # Set the TTL for cache object to five minutes
- set beresp.ttl = 5m;
- # Set Grace Time to one hour
- set beresp.grace = 1h;
- }