varnish+nginx实现单双web服务器缓存

实验目的:

varnish利用实现对后端单双静态web服务器的缓存

varnish包的下载路径:http://repo.varnish-cache.org/redhat/varnish-3.0/el6 可以下载到varnish的rpm包

需要下载的有:

varnish-3.0.5-1.el6.x86_64

varnish-docs-3.0.5-1.el6.x86_64

varnish-libs-3.0.5-1.el6.x86_64

varnish的官网地址:https://www.varnish-cache.org/

实验环境:

web1:172.16.18.3            Nginx

web2:172.16.17.12          Nginx

varnish:172.16.18.1         Varnish

实验内容:

一,安装varnish包,配置web服务器

[[email protected]~]# rpm -ql varnish     
/etc/rc.d/init.d/varnish              #varnish的启动程序     
/etc/rc.d/init.d/varnishlog           #日志     
/etc/rc.d/init.d/varnishncsa          #日志     
/etc/sysconfig/varnish                #配置文件,varnish定义自身属性     
/etc/varnish                          #配置文件目录     
/etc/varnish/default.vcl              #默认配置文件,定义后端节点的     
/usr/bin/varnish_reload_vcl           #加载vcl,     
/usr/bin/varnishadm                   #客户端程序     
/usr/bin/varnishstat                  #状态监控

二,编辑配置文件

[[email protected] ~]# vim /etc/sysconfig/varnish
NFILES=131072
MEMLOCK=82000
NPROCS="unlimited"
RELOAD_VCL=1                                                        #是否重载VCL文件
## Alternative 3, Advanced configuration
VARNISH_VCL_CONF=/etc/varnish/default.vcl              #vcl文件路径
VARNISH_LISTEN_PORT=80                                     #varnish自己工作于那个端口。默认是6081
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1       #管理接口
VARNISH_ADMIN_LISTEN_PORT=6082                    #管理接口监听端口
VARNISH_SECRET_FILE=/etc/varnish/secret                #密钥文件
VARNISH_MIN_THREADS=50                                    #最少空闲线程
VARNISH_MAX_THREADS=1000                                #最多启动线程
VARNISH_THREAD_TIMEOUT=120                            #work超时时长
#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin        #存储文件
VARNISH_STORAGE_SIZE=64M                                                    #存储文件文件大小
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"    #存储方式file
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"     #基于内存方式
VARNISH_TTL=120
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT}              -f ${VARNISH_VCL_CONF}              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT}              -t ${VARNISH_TTL}              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT}              -u varnish -g varnish              -S ${VARNISH_SECRET_FILE}              -s ${VARNISH_STORAGE}"
[[email protected] ~]# vim /etc/varnish/default.vcl
backend default {
  .host = "172.16.18.3";
  .port = "80";
}

此时varnish就已经可以启动了。下来就是最重要的编写vcl文件。

那么我们就应该熟悉这张表,每一个状态引擎所对应的变量

简单介绍一下vcl的语法

VCL的设计参考了C和Perl语言,因此,对有着C或Perl编程经验者来说,其非常易于理解。其基本语法说明如下:

(1)//、#或/* comment */用于注释

(2)sub $name 定义函数

(3)不支持循环,有内置变量

(4)使用终止语句,没有返回值

(5)域专用

(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)

编译vcl文件中状态引擎的顺序我们按照默认配置文件的顺序来,此顺序也符合请求处理的基本顺序,当然,为了配合实验也会有些改动。我们来看一张图,可以明确的明白请求的过程:

1,首先我们来编写vcl_recv段,

vcl_recv作为进入varnish对请求报文解码后第一个子例程,可以在此处做访问控制,是否查询缓存,以及无法识别的数据的判定。

首先对default.vcl文件复制一份重新改名为test1.vcl

acl purgers {                                        #定义一个acl

"127.0.0.1";

"172.16.0.0"/16;

}

sub vcl_recv {

if (req.url ~ "^/test.html$") {             #请求首部的url匹配到test.html,

return(pass);                       #跳过缓存

}

if

if (req.request != "GET" &&             #请求方法不是已知的这7中则发到pipe上去

req.request != "HEAD" &&

req.request != "PUT" &&

req.request != "POST" &&

req.request != "TRACE" &&

req.request != "OPTIONS" &&

req.request != "DELETE") {

return (pipe);

}

if (req.request != "GET" && req.request != "HEAD") {         #不是获取资源的全部跳过缓存,减少无用缓存查询

return (pass);

}

if (req.request == "PURGE") {

if (!client.ip ~ purgers) {                                                   #请求IP不在ACL中定义,则发挥405错误页。

error 405 "Method not allowed";

}

return (lookup);

}

return (lookup);

}

那么此时如何加载这个test1让他生效呢?

第一修改配置文件。

第二,利用varnishadm客户端工具。

varnishadm

[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082         #进入到管理工具    
200     
-----------------------------    
Varnish Cache CLI 1.0    
-----------------------------    
Linux,2.6.32-431.el6.x86_64,x86_64,-sfile,-smalloc,-hcritbit    
varnish-3.0.5 revision 1a89b1f    
Type ‘help‘ for command list.    
Type ‘quit‘ to close CLI session.    
varnish> vcl.load test1 test1.vcl                                                                    #加载vcl文件

200

VCL compiled.

varnish> vcl.list

200

active 2 boot

available 0 test1

varnish> vcl.use test1

200

varnish> vcl.list

200

available 2 boot

active 0 test1

这样就设定成功了。

为了显示效果我们来配置一下deliver段,给客户端返回时候匹配到缓存信息,以便我我们来查看实验结果。

sub vcl_deliver {

if (obj.hits > 0) {                                                                        #判断条件缓存匹配次数大于0

set resp.http.X-Cache = "HIT via" + " " + server.hostname;    #添加HIT via

} else {

set resp.http.X-Cache = "MISS via" + " " + server.hostname;   #没有匹配到则添加MISS via

}

}

访问缓存172.16.18.1.第一次是miss via 之后的访问在缓存有效期内都是HIT via

当访问test.html是会被vcl_recv定义的pass匹配到,直接跳过缓存,所以X-cache状态一直是MISS via

2,编辑vcl_hash,自定义hash生成时的数据来源。

sub vcl_hash {

hash_data(req.url);                   #依据req.url来匹配

if (req.http.host) {

hash_data(req.http.host);          #请求首部的host来缓存

} else {

hash_data(server.ip);

}

return (hash);

}

3,编辑vcl_hit,从缓存中查找到缓存对象时要执行的操作

sub vcl_hit {

if(req.request == "PURGE"){        #当进入缓存后清理缓存对象,返回Purged;

purge;

error 200 "Purged";

}

}

非pipe请求必经过hit,miss,pass,这三条任意一条,所以也要在其他两路做purge匹配。

4,vcl_miss ,从缓存中查找不到缓存对象时要执行的操作;

sub vcl_miss {

if (req.request == "PURGE") {                如果直接不经过缓存,匹配到了PURGE,则返回404说没有进入缓存,否则发往fetch

error 404 "Not in cache";

}

return (fetch);

}

5,vcl_pass,用于将请求直接传递至后端主机

vcl_pass {

if (req.request == "PURGE") {              #如果直接是pass,跳过缓存,且匹配到PURGE,

error 502 "PURGE on a passed object";

}

return (pass);

}

6,vcl_fetch,是在请求从后端被成功接收后调用的,可以使用req,bereq,beresp.

可在此处定义cache的缓存有效时长

sub vcl_fetch {

set beresp.ttl = 360s;                             #修改缓存时长为360s,

if (req.url ~ ".[jpg|gif|png]$"){                #图片文件缓存时长1h

set beresp.ttl = 1h;

}

if (beresp.status != 200){                        #backend返回状态码不是200,则不缓存数据

return (hit_for_pass);

}

return (deliver);

}

6,sub vcl_deliver ,将用户请求的内容响应给客户端时用到的方法;deliver,在recv之后我们就用过,在里边添加了一个相应给用户的X-cache,是否用到了缓存。复制下来!完善一下!

sub vcl_deliver {

if (obj.hits > 0) {

set resp.http.X-Cache = "HIT via" + " " + server.hostname;

} else {

set resp.http.X-Cache = "MISS via" + " " + server.hostname;

}

set resp.http.host = server.hostname;

retuen (deliver);

}

7,sub vcl_pipe {

return (pipe);

}

到此一个简单的vcl功能就写好了。

先请求一下curl -X PURGE http://172.16.18.1/index.html

[[email protected] html]# curl -X PURGE http://172.16.18.1/index.html    
<html>    
<head><title>405 Not Allowed</title></head>             #发现和我们定义的Method not allowed不一样,那是为什么呢?

<body bgcolor="white">    
<center><h1>405 Not Allowed</h1></center>    
<hr><center>nginx/1.6.2</center>    
</body>    
</html>

经过查看vcl_recv段发现,我们在PURGE之上就将不是定义的方法送到了pipe.无法到达PURGE.修改如下。将PURGE写在方法判断之前

sub vcl_recv {

if (req.url ~ "^/test.html$") {

return(pass);

}

if (req.request == "PURGE") {

if (!client.ip ~ purgers) {

error 405 "Method not allowed";

}

return (lookup);

}

if (req.request != "GET" &&

req.request != "HEAD" &&

req.request != "PUT" &&

req.request != "POST" &&

req.request != "TRACE" &&

req.request != "OPTIONS" &&

req.request != "DELETE") {

return (pipe);

}

if (req.request != "GET" && req.request != "HEAD") {

return (pass);

}

return (lookup);

}

[[email protected] html]# curl -X PURGE http://172.16.18.1/index.html    
<?xml version="1.0" encoding="utf-8"?>    
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"    
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">    
<html>    
<head>    
<title>404 Not in cache</title>    
</head>    
<body>    
<h1>Error 404 Not in cache</h1>

Not in cache

<h3>Guru Meditation:</h3>

XID: 506876240

<hr>

Varnish cache server

</body>    
</html>

这下和我们定义的一样的,看来还得注意判断的先后次序。

下边我们来定义一下有cookie的文件走向。

首先在vcl_resv添加

if (!(req.url ~ "wp-(login|admin)")) {                #所有有cookie的请求都不查缓存

unset req.http.cookie;

}

在vcl_fetch中定义抹除cookie

sub vcl_fetch {

if (!(req.url ~ "wp-(login|admin)")) {

unset beresp.http.Set-Cookie;

}

}

三,后端主机的健康检测

backend web1 {

.host = "172.16.18.3";

.port = "80";

.probe = {

.url = "/index.html";            #探测什么文件

.interval = 1s;                     #几秒探测一次

.window = 5;                      #失败探测多少次

.threshold = 2;                   #成功探测多少次

}

}

在varnishadm中查看

varnish> backend.list

200

Backend name Refs Admin Probe

default(172.16.18.3,,80) 8 probe Healthy 5/5

四,varnish使用多台后端主机

Varnish中可以使用director指令将一个或多个近似的后端主机定义为一个逻辑组,并可以指定的调度方式(也叫挑选方法)来轮流将请求发送至这些主机上。不同的director可以使用同一个后端主机,而某director也可以使用“匿名”后端主机(在director中直接进行定义)。每个director都必须有其专用名,且在定义后必须在VCL中进行调用,VCL中任何可以指定后端主机的位置均可以按需将其替换为调用某已定义的director。

注意:当使用自定义的主机时一定要在vcl_recv中指定使用哪个主机,

backend web1 {

.host = "172.16.18.3";

.port = "80";

.probe = {

.url = "/index.html";

.interval = 1s;

.window = 5;

.threshold = 2;

}

backend web2 {

.host = "172.16.18.3";

.port = "80";

.probe = {

.url = "/index.html";

.interval = 1s;

.window = 5;

.threshold = 2;

}

director webservers round-robin {

{.backend = web1;}

{.backend = web2;}

}

vcl_recv {                                                        添加下边段落

set req.backend = webservers;                        放在最前边    
}

}

下来访问172.16.18.1验证有没有将请求在两个web服务器上轮询,

可以看到请求的test.html是轮询的,为什么不请求172.16.18.1呢,应为172.16.18.1有缓存,看不到效果。

varnish的实验就到此了。

时间: 2025-01-05 00:07:16

varnish+nginx实现单双web服务器缓存的相关文章

keepalived+nginx+tomcat搭建高性能web服务器集群

使用keepalived+nginx+tomcat搭建高性能web服务器集群,系统采用centos6.9,前端用nginx做反向代理实现负载均衡,同时结合keepalived对nginx实现高可用,后端使用两台tomcat做动态jsp解析,实现了动静分离. 搭建环境 准备四台服务器 vip: 192.168.75.130master: 192.168.75.131 (安装nginx做反向代理实现负载匀衡,结合keepalived实现高可用)backup: 192.168.75.132 (同上)w

Apache、IIS、Nginx等绝大多数web服务器,都不允许静态文件响应POST请求

最近调用一个接口,发现httppost请求目标网站会出现405 状态码,原因为 Apache.IIS.Nginx等绝大多数web服务器,都不允许静态文件响应POST请求 所以将post请求改为get请求即可 package com.changyou.test; import java.io.IOException; import java.io.UnsupportedEncodingException; //import org.apache.commons.httpclient.HttpCli

Nginx+uWSGI+Django部署web服务器

目录 Nginx+uWSGI+Django部署web服务器 环境说明 前言 搭建项目 Django部署 编辑luffy/luffy/settings.py 编辑luffy/app01/views.py 编辑luffy/luffy/urls.py 运行并测试 uWSGI部署 测试运行uWSGI 使用uWSGI运行django项目 uWSGi热加载Djangoa项目 部署nginx nginx配置uwsgi和django django部署static文件 重新加载nginx进行测试 测试nginx

Nginx配置文件(作为Web服务器)

Nginx作为Web服务器时,其配置文件参数如下: #user  nobody; #默认的运行用户 worker_processes  1; #工作进程数,建议和CPU核心数一致,默认为1 #error_log  logs/error.log; #error_log  logs/error.log  notice; #error_log  logs/error.log  info; #pid        logs/nginx.pid; events { worker_connections  

Web服务器缓存

前面提到的一些缓存技术都是有我们的动态才程序控制的,现在的web服务器功能越来越强大,常用的web服务器软件也都内置了缓存功能,下面我们就简单的说下服务器端缓存的应用. 首先,我们先来介绍一下URL映射,对于所有web服务器我们向其发送Http请求,他解析后将结果返回给我们客户端,这听起来很简单么?真的是这样么,真相是web服务器还有很多“暗操作”,大家都知道Url重写技术吧,比如apache的mod_rewrite,这样的话我们请求的地址,很可能不是真正文件所存放的地址,取个简单的例子,我们请

FreeBSD下配置Nginx+php+mysql高性能web服务器

概述: FreeBSD版本8.4 Nginx版本1.6 php版本5.4 mysql版本5.6 在配置之前要先更新系统,在root模式下输入如下命令查看pkg安装工具版本,如果版本低于1.4,那么需要更新才可使用: 配置环境的服务器要能上网,因为需要直接从官方资源站点下载配置包. #pkg info将看到如下信息,系统提示需要安装pkg工具:[email protected]:/usr/home/root001 # pkg infoThe package management tool is n

nginx反向代理后端web服务器记录客户端ip地址

nginx在做反向代理的时候,后端的nginx web服务器log中记录的地址都是反向代理服务器的地址,无法查看客户端访问的真实ip. 在反向代理服务器的nginx.conf配置文件中进行配置. location /bbs { proxy_pass http://192.168.214.131/bbs; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarde

Tomcat结合Apache、Nginx实现高性能的web服务器

一.Tomcat为什么需要与apache.nginx一起结合使用? Tomcat虽然是一个servlet和jsp容器,但是它也是一个轻量级的web服务器.它既可以处理动态内容,也可以处理静态内容.不过,tomcat的最大优势在于处理动态请求,处理静态内容的能力不如apache和nginx,并且经过测试发现,tomcat在高并发的场景下,其接受的最大并发连接数是由限制的,连接数过多会导致tomcat处于"僵死"状态,因此,在这种情况下,我们可以利用nginx的高并发,低消耗的特点与tom

CentOS 6.4 安装 FastDFS、使用Nginx作为文件访问WEB服务器

安装环境:1. CentOS-6.4-i3862. FastDFS_v4.063. fastdfs-nginx-module_v1.154. Nginx-1.5.6(安装见此)5. libevent-2.0.21-stable tracker server  IP:192.168.1.11 storage1 server IP:192.168.1.12 group1 storage2 server IP:192.168.1.13 group2 storage3 server IP:192.168