varnish缓存代理

varnish 概述

Varnish 是一款高性能的开源 HTTP 加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no)

使用 3 台 Varnish 代替了原来的 12 台 squid,性能居然比以前更好。



Varnish 的作者 Poul-Henning Kamp 是 FreeBSD 的内核开发者之一,他认为现在的计算机比起 1975

年已经复杂许多。在 1975 年时,储存媒介只有两种:内存与硬盘。但现在计算 机系统的内存除了主存外, 还包括了 cpu 内的 L1、L2,甚至有 L3 快取。硬盘上也有自己的快取装置,因此 squid cache 自行处理 物件替换的架构与可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应 该交给操作系统处理,这就是 Varnish cache 设计架构。



监听端口号: 6081



官方网站:

https://www.varnish-cache.org/

下载:

https://www.varnish-cache.org/releases



varnish 基础概念详解

比起 squid 更加轻量级,大致有以下几个特点:

·可以基于内存缓存,也可以在磁盘上缓存

如果期望内存大小超过几十个 G,比如图片服务器,纯粹使用内存,性能未必好,这时候可以使用磁盘 进行缓存,或使用 SSD X 2 做 RAID1 避免磁盘损坏,在实现随机访问上 ssd 硬盘要比机械硬盘要好的 多,如果必须要缓存在磁盘上还是建议使用 ssd 磁盘

·可以利用虚拟内存方式,IO 性能会非常好 支持设置 0-60 秒 精确缓存时间



·支持 VCL

其配置是通过 vcl 编程语言来完成的。 其配置需要先转换成 C 代码,所以使用 vcl 所写的配置,要先转 换成 C 语言代码,因此要依赖于 GCC 临时的编译 vcl 配置的,编译完之后才能运行起来

注: Varnish Configuration Language - VCL(varnish 配置语言-VCL)。

Varnish 使用区域配置语言,这种语言叫做“VCL”(varnish configuration language),在执行 vcl

时,varnish 就把 VCL 转换成二进制代码。

VCL 文件被分为多个子程序,与同的子程序在与同的时间里执行,比如一个子程序在接到请求时执 行,另一个子程序在接收到后端服务器传送的文件时执行。




·独特的日志存储及管理机制

日志既然保存在内存中,日志可以供多个应用程序所访问,所以一般查看命中率,当前请求有多少 get post 方法等等,都需使用专用的工具才可以查看,比如 varnishshtopvarnishlog 等命令工具用来查看 日志信息



·支持使用 varnish 状态引擎 通过巧妙的状态引擎的设计完成与同的引擎对用户的请求和缓存代理机制进行处理,用配置文件为状态

引擎提供状态法则,完成缓存处理、完成代理处理等等



varnish 缓存数据机制:

wKiom1XHa9vzouDZAAF4jzfkQsg325.jpg

VCL 处理流程图

wKioL1XHbfPiPRteAAFQ6D-Qh2g939.jpg

处理过程大致分为如下几个步骤:

(1)Receive 状态,也就是请求处理的入口状态,根据 VCL 规则判断该请求应该是 Pass 或 Pipe,或者 进入 Lookup(本地查询)。



(2)Lookup 状态,在缓存中查找用户请求的对象,如果缓存中没有其请求的对象,后续操作很可能会将

其请求的对象进行缓存;进入此状态后,会在 hash 表中查找数据,若找到,则进入 Hit 状态,否则进入

miss 状态。



(3)Pass 状态,在此状态下,会进入后端请求,即进入 fetch (取)状态。

(4)Fetch 状态,在 Fetch 取状态下,对请求,进行后端的获取,发送请求,获得数据,并进行本地的 存储。

(5)Deliver  提供状态, 将获取到的数据发送给客户端,然后完成本次请求。 注:

pass:绕过缓存,即与从缓存中查询内容或与将内容存储至缓存中;

pipe:与对客户端进行检查或做出任何操作,而是在客户端与后端服务器之间建立专用“管道”,

并直接 将数据在二者之间进行传送;此时,keep-alive 连接中后续传送的数据也都将通过此管道进行直接传送,并与会出现在任何日志中;


流程:

wKiom1XHbFaTBQmlAAGH-ljZeN0667.jpg

总结: 用户通过 varnish 加速时,有 4 线路可以获得数据。

wKioL1XHbmvTkCIyAAHs-wnc8bM814.jpg

一、安装 varnish

1、安装 varnish, 将上传 varnish 软件包

[root@silence80 ~]# rpm -ivh varnish-libs-3.0.6-1.el6.x86_64.rpm

[root@silence80 ~]#   rpm -ivh varnish-3.0.6-1.el6.x86_64.rpm



或:

rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-3.0.el6.rpm yum install varnish

参数:

--nosignature 想要略过数字签名的检查,与检测合法性。因为这个 rpm 包与是 redhat 发布的。

-i install   安装



vcl 置文件:

[root@silence80 ~]# ls /etc/varnish/default.vcl varnish 主配置文件

[root@silence80 ~]# vim /etc/sysconfig/varnish



启 varnish 服务:

1)通过脚步启动

[root@silence80 ~]# /etc/init.d/varnish start


2)手动启动

[root@silence80 ~]#varnishd -f /etc/varnish/default.vcl -s malloc,256M -T 127.0.0.1:2000 -a 0.0.0.0:80


or


[root@silence80 ~]#varnishd -a 192.168.1.203:80   -f /etc/varnish/default.vcl    -T 127.0.0.1:6082   -t 120  -p thread_pool_min=50  -p thread_pool_max=1000 -p thread_pool_timeout=120 -u varnish -g varnish  -S /etc/varnish/secret    -s malloc,256M

-s 指定缓存方式   malloc  内存   file 硬盘

   -s malloc,256M

   -s file,/cache/data,1G


-f /etc/varnish/default.vcl  指定配置文件路径

-T 127.0.0.1:6082  Varnish 管理ip及端口  (telnet 127.0.0.1 6082)

-t 120  

-p thread_pool_min=50  -p thread_pool_max=1000 -p thread_pool_timeout=120  线程最小 最大 数量 超时时间

-u varnish -g varnish   运行varnish进程的用户及组

-S /etc/varnish/secret  varnish安全文件




实战:配置 xuegod63 成为 varnish 服务器加速 xuegod64 web 服务器

通过 CDN 加速 web 网站 网宿 , 蓝讯

智能 DNS, DNS 视图



实战:配置 xuegod63 成为 varnish 服务器

[root@silence80 ~]# vim /etc/varnish/default.vcl

###配置一个后端服务器 改:

7 backend default {

8 .host = "127.0.0.1";

9 .port = "80";

10 }

为:

backend web1 {

.host = "192.168.1.84";

.port = "80";

}

###查看缓存命中情况 在:

90 # sub vcl_deliver {

91 # return (deliver);

92 # }

追加:



sub vcl_deliver {

if (obj.hits > 0) {

set resp.http.X-Cache = "HIT from xuegod cache";

}

else {

set resp.http.X-Cache = "MISS from xuegod cache";

}

return (deliver);

}

保存退出。



配置 varnish 服务端口

[root@silence80 ~]# vim /etc/sysconfig/varnish

改:

66 VARNISH_LISTEN_PORT=6081

为:

VARNISH_LISTEN_PORT=80


改:

92 VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE

 #不要将数据缓存到硬盘中,否则硬盘会越来越大,IO队列越来越长

为:

VARNISH_STORAGE="malloc,1024M"        定义内存缓存


注释掉:

106 #             -S ${VARNISH_SECRET_FILE} \    



启动 varnish 服务器

[root@silence80 ~]# /etc/init.d/varnish start

Starting Varnish Cache: [   OK   ]



配置 xuegod64 为 web 服务器

[root@silence84 ~]# yum install httpd -y

[root@silence84 ~]# echo 192.168.1.84 > /var/www/html/index.html   #创建首页

 [root@silence84 ~]# service httpd restart #在 xuegod64 上开启 web 服务器 

Stopping httpd: [FAILED]

Starting httpd: [   OK   ]



测试源站点:

在浏览器中访问:http://192.168.1.84/



测试加速:

在浏览器中访问:http://192.168.1.80/

wKioL1XHc67TRHGJAADzlBbGoEs175.jpg

能够正常访问,说明代理设置成功。




测试缓存命中: 扩展:curl 命令

curl 是通过 url 语法在命令行下上传或下载文件的工具软件,它支持 http,https,ftp,ftps,telnet 等多种 协议,常被用来抓取网页和监控 Web 服务器状态。

参数:

-I 只取 http 响应头的信息,与取网页内容



例:

[root@silence80 ~]# curl -I 192.168.1.84   #在 xuegod63 上查看 xuegod64 开启动的 web 服务 器类型

HTTP/1.1 403 Forbidden

Date: Sat, 08 Aug 2015 11:17:49 GMT Server: Apache/2.2.15 (Red Hat) Accept-Ranges: bytes

Content-Length: 3985

Connection: close

Content-Type: text/html; charset=UTF-8



实例 2:测试缓存命中

[root@silence80 ~]# curl -I 192.168.1.80

HTTP/1.1 503 Service Unavailable

Server: Varnish

Content-Type: text/html; charset=utf-8

Retry-After: 5

Content-Length: 419

Accept-Ranges: bytes

Date: Sat, 08 Aug 2015 11:12:20 GMT X-Varnish: 1141298100

Age: 0

Via: 1.1 varnish

Connection: close

X-Cache: MISS from linuxidc cache   #未命中



再次测试:

[root@silence80 ~]# curl -I 192.168.1.80

。。。

X-Cache: MISS from linuxidc cache   #还是没有命中



解决需要开启 apache 长链接功能

[root@silence84 ~]# vim /etc/httpd/conf/httpd.conf

改:   76 KeepAlive Off



为:   KeepAlive On

[root@silence84 ~]# service httpd restart



再次测试:

[root@silence80 ~]# curl -I 192.168.1.80

HTTP/1.1 200 OK

Server: Apache/2.2.15 (Red Hat)

Last-Modified: Sat, 08 Aug 2015 11:21:11 GMT ETag: "25f61-d-51ccaf318dbb9"

Content-Type: text/html; charset=UTF-8

Content-Length: 13

Accept-Ranges: bytes

Date: Sat, 08 Aug 2015 11:28:36 GMT X-Varnish: 1141298120

Age: 0

Via: 1.1 varnish

Connection: keep-alive

X-Cache: MISS from linuxidc cache



[root@silence80 ~]# curl -I 192.168.1.80

HTTP/1.1 200 OK

Server: Apache/2.2.15 (Red Hat)

Last-Modified: Sat, 08 Aug 2015 11:21:11 GMT ETag: "25f61-d-51ccaf318dbb9"

Content-Type: text/html; charset=UTF-8

Content-Length: 13

Accept-Ranges: bytes

Date: Sat, 08 Aug 2015 11:28:37 GMT X-Varnish: 1141298121 1141298120

Age: 1

Via: 1.1 varnish

Connection: keep-alive

X-Cache: HIT from linuxidc cache #命中




varnish 服务器基本操作:

[root@silence80 ~]# varnishadm ban.url   .*$ #清除所有

[root@silence80 ~]# curl -I 192.168.1.80

。。。

X-Cache: MISS from linuxidc cache



[root@silence80 ~]# varnishadm ban.url   /index.html #清除 index.html 页面缓存 测试:

[root@silence80 ~]# curl -I 192.168.1.80/index.html




[root@silence80 ~]#   varnishadm ban.url /admin/$ #清除 admin 目录缓存




实战 2:使用 varnish 加速多个与同域名站点的 web 服务器 配置 silence84 和 silence81 为 web 服务器

silence84 之前已经配置成 web 服务器



配置 silence81 为 web2 服务器

[root@silence81 ~]# yum install httpd -y

[root@silence81 ~]# echo 192.168.1.81 > /var/www/html/index.html

[root@silence81 ~]# vim /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4

::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.1.81   silence81.cn

[root@silence81 ~]# service httpd restart

Stopping httpd:  [FAILED] 

Starting httpd: [   OK   ]




配置 silence80  上的 varnish 服务器:

[root@silence80  ~]# vim /etc/varnish/default.vcl

改:

backend web1 {

.host = "192.168.1.64";

.port = "80";

}

为:

backend web1 {

.host = "192.168.1.64";

.port = "80";

}

backend web2 {

.host = "192.168.1.62";

.port = "80";

}



#当访问 www.silence.cn 域名时从 web1 上取数据,访问 bbs.silence.cn 域名时到 web2 取数据,访 问其他页面报错。

[root@silence80  ~]# vim /etc/varnish/default.vcl   #在之前的 sub vcl_deliver   { 。。。  }   之 前,插入以下内容:



sub vcl_recv {

if (req.http.host ~ "^(www.)?xuegod.cn") {



set req.http.host = "www.xuegod.cn";

set req.backend = web1;

} elsif (req.http.host ~ "^bbs.xuegod.cn") {

set req.backend = web2;

} else { error 404 "xuegod cache";

}

}

sub vcl_deliver {

if (obj.hits > 0){

set resp.http.X-Cache = "HIT from linuxidc cache";

}

else {

set resp.http.X-Cache = "MISS from linuxidc cache";

}

return (deliver);

}



重新加载 varnish 配置文件:

[root@silence81 ~]# service varnish reload Loading vcl from /etc/varnish/default.vcl Current running config name is boot

Using new config name reload_2015-08-08T19:42:11

VCL compiled. available 2 boot

active 0 reload_2015-08-08T19:42:11

Done



测试:网页访问 www.xuegod.cn  和 bbs.xuegod.cn 则会显示与同的内容。

在 silence81  上测试:

[root@silence81  ~]# vim /etc/hosts #添加 hosts 文件

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4

::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.1.81   silence81.cn

192.168.1.80   www.xuegod.cn

192.168.1.80   bbs.xuegod.cn



[root@silence81  ~]# yum install elinks -y

[root@silence81  ~]# elinks www.xuegod.cn --dump

192.168.1.81

[root@silence81 ~]# elinks bbs.xuegod.cn --dump

192.168.1.84



测试报错信息:

http://192.168.1.80/


wKiom1XHbbrgFGKBAAFRFUyZF4s063.jpg

在win下的host标注


wKioL1XHcFnwnFLUAANAKg_bmvI044.jpg

访问www.silence.cn和bbs.silence.cn

wKiom1XHb1HyYLgMAAEbNC1Ok-k475.jpg

可以结合以下某些功能进行缓存代理

在win下给hosts添加语句

wKiom1XHb5iT-BmDAAGWssd7QaA875.jpg

缓存一个网站

    vim /etc/varnish/default.vcl

#设置varnish向谁取源

在第7行插入:

backend default { 

  .host = " www.vfast.com.cn"; 

  .port = "80"; 

}


acl abc{

"127.0.0.1";

"192.168.1.80";

"192.168.1.84";

}




本地缓存  ctrl+F5   刷新



Varnish查看命令:

[root@silence80 ~]# varnishhist  #varnish图表  可以查看哪些数据是走缓存 哪些走源

[root@silence80 ~]# varnishstat  #查看varnish状态


#删除url的方法 PURGE


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

    if (!client.ip ~ abc) {

       error 405 "Method not allowed";

   }

        return (lookup);

}


定义请求方法

#分析用户请求方法 哪些请求方法使用pipe函数 

#以下列出的请求头使用pass or lookup ,在28行打开以***释。

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

       req.request != "HEAD" && 

       req.request != "PUT" && 

       req.request != "POST" && 

       req.request != "TRACE" && 

       req.request != "OPTIONS" && 

       req.request != "DELETE") { 

#         /* Non-RFC2616 or CONNECT which is weird. */ 

         return (pipe); 

     } 


#如果请求方法不是get or head那么其他请求方法走pass ,在38行打开以***释。

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

#         /* We only deal with GET and HEAD by default */ 

         return (pass); 

     } 


#假如你的请求方法是get or head 那么请求头中包含以下字段也不缓存 ,在42行插入。

if (req.url ~ "\.(html|gif|jpg|png|css)$" && req.request == "GET") {

     unset req.http.Cookie;    #删除cookie,让html|gif|jpg|png|css格式可以缓存

 }


#Authorization    cookie    走lookup,在46行插入。

     if (req.http.Authorization || req.http.Cookie) { 

#         /* Not cacheable by default */ 

         return (pass); 

     } 

     return (lookup);

 }


手动添加

#如果url是以.jsp或.do结尾,或者url中包含?这从后端拿数据. 


if (req.url ~ "\.(jsp|do)($|\?)") {

           return (pass);

}

#除了以上列出的不满足的,剩下的满足条件的使用lookup操作 

     return (lookup); 


# 对pass函数的定义   打开59行的注释。

 sub vcl_pass { 

     return (pass); 

 } 


# lookup 子函数  ,打开63行的注释

# 查询varnish缓存中是否已经缓存了用户需要的数据 

# 缓存数据存在内存   key = value 

 sub vcl_hash { 

     hash_data(req.url); #key的实现  hash 的对象是用户请求的url 

     if (req.http.host) { 

         hash_data(req.http.host); 

     } else { 

         hash_data(server.ip); 

     } 

     return (hash); 

 } 



修改73行的hit,77行的miss,81行的fetch,94行的vcl_deliver

#hash函数查询缓存成功后 命中数据 将数据交给vcl_hit  

 sub vcl_hit { 

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

        purge;

        error 200 "purge OK SUCCESS!!!!!";

}

     return (deliver);  #hit 将数据交给deliver函数 

 } 

#  

# hash函数查询缓存失败  为命中   将用户请求交给vcl_miss 

 sub vcl_miss { 

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

      purge;

      error 200 "purge OK SUCCESS!!!!!";

}

     return (fetch);   #miss将请求交给fetch函数 

 } 

#  

# fetch 取源函数 去后端源服务器取数据 

 sub vcl_fetch {

##针对不同的内容设置不同的缓存时间

if (req.url ~ "\.(html|css|jss)$") {

       set beresp.ttl = 1d;

    } elseif (req.url ~ "\.(jpg)$") {

       set beresp.ttl = 120s;

    } elseif (req.url ~ "\.(gif|png)$") {

       set beresp.ttl = 300s;

    }


# 将数据交给用户 ,打上状态(hit or miss)

 sub vcl_deliver { 

if (obj.hits > 0) {

       set resp.http.X-Cache = "ABC-HIT";

    } else {

       set resp.http.X-Cache = "ABC-MISS";

    }

     return (deliver); 

 }


删除图片(删除时需要在客户端删除,在varnish上删除不了,要在varnish上添加可删除的客户端ip)

除了配置文件的配置之外,还要再64上配置

silence80为客户端

[root@silence80 ~]# vim /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6


192.168.1.64            silence80.cn             silence80

192.168.1.63            silence80.cn             silence80


192.168.1.63            www.vfast.com.cn


[root@silence80 ~]# curl -I http://www.vfast.com.cn/p_w_picpaths1/0.jpg

HTTP/1.1 200 OK

Server: nginx

Content-Type: p_w_picpath/jpeg

Last-Modified: Mon, 04 May 2015 05:30:14 GMT

ETag: "554703e6-20412"

Content-Length: 132114

Accept-Ranges: bytes

Date: Sat, 09 May 2015 17:27:39 GMT

X-Varnish: 288597595

Age: 0

Via: 1.1 varnish

Connection: keep-alive

X-Cache: ABC-MISS


[root@silence80 ~]# curl -I http://www.vfast.com.cn/p_w_picpaths1/0.jpg

HTTP/1.1 200 OK

Server: nginx

Content-Type: p_w_picpath/jpeg

Last-Modified: Mon, 04 May 2015 05:30:14 GMT

ETag: "554703e6-20412"

Content-Length: 132114

Accept-Ranges: bytes

Date: Sat, 09 May 2015 17:27:39 GMT

X-Varnish: 288597596 288597595

Age: 1

Via: 1.1 varnish

Connection: keep-alive

X-Cache: ABC-HIT


第一次访问会是miss,第二次就变成hit


[root@silence80 ~]# curl -X PURGE  http://www.vfast.com.cn/p_w_picpaths1/0.jpg

<?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>200 purge OK SUCCESS!!!!!</title>

  </head>

  <body>

    <h1>Error 200 purge OK SUCCESS!!!!!</h1>

    <p>purge OK SUCCESS!!!!!</p>

    <h3>Guru Meditation:</h3>

    <p>XID: 288597597</p>

    <hr>

    <p>Varnish cache server</p>

  </body>

</html>

删除成功

                                                                            j_0007.gif

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章