一、Varnish概述 2.1.1 Varnish的结构与特点 Varnish是一个轻量级别的Cache和反向代理软件,先进的设计理念和成熟的设计框架是Varnish的主要特点: 基于内存进行缓存,重启后数据将消失 利用虚拟内存方式,I/O性能好. 支持设置0~60秒的精确缓存时间 VCL配置管理比较灵活 32位机器上缓存文件大小为最大2GB 具有强大的管理功能,例如:top stat admin list等 状态设计巧妙,结构清晰 利用二叉堆管理缓存文件,达到可以积极***目的。 2.1.2 Varnish与Squid的对比 说到Varnish,就不能不提Squid,Squid是一个高性能的代理缓存服务器,它和Varnish的相比较有诸多的异同点,下面进行分析: 相同点: 都是一个反向代理服务器 都是开源软件 异同点,也是Varnish的优点: Varnish的稳定性很高,两者在完成相同的负荷的工作时,Squid发生的故障几率要高于Varnish,因为Squid需经常重启. Varnish访问速度更快,Varnish采用用了”Visual Page Cache”技术,所有缓存的数据都直接从内存读取,而且Squid是从硬盘读取缓存数据,因此Varnish访问速度更快 Varnish可以支持更多的并发连接,因为Varnish的TCP连接要比Squid释放快,所以在高并发连接情况可以支持更多地TCP连接。 Varnish可以通过管理端口,使用正则表达式清除部分缓存,而Squid做不到。 Varnish缺点如下: 在高并发状态下CPU,I/O和内存等资源开销都要高于Squid。 Varnish进程一旦挂起,崩溃或者重启,缓存数据都会从内存当中完全释放,此时所有的请求会发送后端的WEB服务器,在高并发的情况下,这会给后端的服务器造成很大压力。 Internet外网 | ---FW-->防火墙 | | | | --Varnish1 --Varnish2 --Varnish3 | | | | | | | | | | | | WEB1 WEB2 WEB3 二、Varnish安装 2.1、环境: Varnish-server:10.0.0.202 Nginx-Server:10.0.0.201 2.2.2、创建Varnish用户缓存目录和日志 # useradd varnish -s /sbin/nologin 创建varnish用户 # mkdir /varnish/cache –p 创建varnish缓存目录 # mkdir /varnish/log 创建varnish日志 # chown -R varnish:varnish /varnish/ 修改赋权组 2.2.3、安装PCRE 为了兼容正则表达式,编译 2.0以上版本时否则会报错pcre找不到。 # yum install gcc # yum install gcc-c++ libstdc++-devel # yum install -y httpd-devel pcre perl pcre-devel zlib zlib-devel GeoIP GeoIP-devel # wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.34.tar.bz2 # tar -xvf pcre-8.34.tar.bz2 # cd pcre-8.34/ # ./configure --prefix=/usr/local/prce/ # make && make install 2.2.4、安装Varnish # wget http://repo.varnish-cache.org/source/varnish-3.0.0.tar.gz # tar -xzvf varnish-3.0.0.tar.gz # cd varnish-3.0.0 #./configure --prefix=/usr/local/varnish PKG_CONFIG_PATH=/usr/lib/pkgconfig # make && make install # cd /usr/local/varnish/sbin ./varnishd -V 2.3.1、VCL使用说明 VCL,即Varnish Configaution Language 用来定义Varnish的存储策略 VCL内置函数 (1)、vcl_recv函数 用于接收和处理请求,当请求到达并成功接收后被调用. 函数一般以如下几个关键字结束 pass表示进入pass模式,把请求控制权交给vcl_pass函数 pige 表示进入pige模式,把请求控制权交给vcl_pipe函数 error code[reason] 表示返回”code”给客户,并放弃处理该请求,”code”是错误的标识 ,例如:200和405等,”reason”是错误信息 (2)、vcl_pipe函数 此函数在进入pipe模式时被调用,用于请求直接传至后端主机,在请求和返回内容没有改变的情况下,将不变的内容返回给客户端,直到这个连接被关闭。 此函数一般以如下几个关键字结束: error code[reason] pipe (3)、vcl_pass函数 此函数在进入pass模式时被调用,用于请求直接传至后端主机,后端主机但应数据,将答应的数据传至客户端,但不进行任何缓存,当前连接下每次都返回最新的内容。 此函数一般以如下几个关键字结束: error code[reason] pass (4)、lookup函数 表示在缓存中查找被请求的对象,并且根据查找的结果把控制权交给vcl_hit或者函数vcl_miss (5)、vcl_hit函数 在执行lookup指令后,在缓存中找到请求的内容后将自动调用该函数 此函数一般以如下几个关键字结束: fetch 表示从后端获取请求的内容,并且把控制权交给vcl_fetch函数 deliver 表示将找到的内容发送给客户,并且把控制权交给函数vcl_deliver error code[reason] pass (6)、vcl_miss函数 在执行lookup指令后,在缓存中没有找到请求的内容时自动调用该方法,此函数可以于判断是否需要从后端服务器获取内容 此函数一般以如下几个关键字结束: fetch:表示从后端获取请求内容,并且把控制权交给vcl_fetch函数 error code[reason] pass (7)、vcl_miss函数 在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端, 此函数一般以如下几个关键字结束: error code[reason] pass deliver (8)、vcl_deliver函数 将在缓存中找到请求的内容发送给客户端调用此方法。 此函数一般以如下几个关键字结束: error code[reason] deliver (9)、vcl_timeout函数 在缓存内容到期前调用此函数. 此函数一般以如下几个关键字结束: discard:表示从缓存中清除内容 fetch (10)、vcl_discard函数 在缓存内容到期后或者缓存空间不足时,自动调用该函数. 此函数一般以如下几个关键字结束: keep:表示将内容继续保留在缓存当中 discard 三、Varnish配置 2.3.2、配置Varnish配置实战 由于本版不同,Varnish配置文件的写法也存在一定的差异,Varnish3.x版本不但在配置写法上和2.x版本不同,修复了很多不应用BUG,本文以3.x版本为基准 Varnish安装完成后,默认的配置文件/usr/local/varnish/etc/varnish/default.vcl 此配置文件默认是全部注释掉的.配置文件如下: 先编辑配置文件 # vi /usr/local/varnish/etc/varnish/default.vcl # This is a basic VCL configuration file for varnish. See the vcl(7) # man page for details on VCL syntax and semantics. # # Default backend definition. Set this to point to your content # server. # # This is a basic VCL configuration file for varnish. See the vcl(7) # man page for details on VCL syntax and semantics. # # Default backend definition. Set this to point to your content # server. # #设置后端WEB服务-关注点 backend webtest1 { .host = "10.0.0.201"; .port = "80"; .connect_timeout = 1s; .first_byte_timeout = 5s; .between_bytes_timeout = 2s; } #可以定义多台WEB-关注点 #backend webtest2 { # .host = "192.168.100.6"; # .port = "80"; # .connect_timeout = 1s; # .first_byte_timeout = 5s; # .between_bytes_timeout = 2s; #} #多台WEB可以定义负载均衡-关注点lb_test, #director lb_test random { # { # .backend = webtest1; # .weight = 5; # } # { # .backend = webtest2; # .weight = 5; # } #} #定义那些IP或者IP段具有访问权-关注点 acl purge { "localhost"; "127.0.0.1"; "192.168.1.0"/24; "10.0.0.0"/16; } sub vcl_recv { #开启压缩模式,图片格式取消压缩 if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|png|gif|jpeg|flv)" ) { remove req.http.Accept-Encoding; remove req.http.Cookie; } else if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } else if (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { remove req.http.Accept-Encoding; } } #根据host设置后端服务器-关注点 if (req.http.Host ~ "(?i)(www.test1.com|www.test2.com|10.0.0.202)") { #set req.backend = lb_test; #如果开启负载用此项,上面的负载均衡的POOL的名叫注意:lb_test set req.backend = webtest1; }else if (req.http.Host ~ "(?i)p_w_picpath.wdj.com"){ set req.backend = webtest1; }else { error 408 "Hostname not found"; } #如果为purge请求,客户端ip不在访问列表中,返回405拒绝-关注点 if (req.request == "PURGE") { if (!client.ip ~purge) { error 405 "Not Allowed"; } #本地缓存查找 return(lookup); } #如果为GET请求,url后缀为jpg,png,gif等 取出cookie if (req.request == "GET"&&req.url ~ "(?i)\.(jpg|png|gif|swf|jpeg|ico)$") { unset req.http.cookie; } #如果GET请求,url为php,则穿过cache,不缓存 if (req.request =="GET"&&req.url ~ "(?i)\.php($|\?)"){ return (pass); } #简单防盗链--关注点 if (req.http.referer ~ "http://.*") { if ( !(req.http.referer ~ "http://.*test1\.com" || req.http.referer ~ "http://.*test2\.com" || req.http.referer ~ "http://.*wdj\.com" || req.http.referer ~ "http://.*google\.com" || req.http.referer ~ "http://.*baidu\.com" || req.http.referer ~ "http://.*yahoo\.cn" )) { error 404 "Not Found!"; } } #获取客户端ip # if (req.restarts == 0) { if (req.http.x-forwarded-for) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } # } #不是以下请求进入pipe模块 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 和HEAD请求不缓存 if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization) { /* Not cacheable by default */ return (pass); } return (lookup); } # sub vcl_pipe { return (pipe); } # sub vcl_pass { return (pass); } #使用url+host hash算法查找数据 sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (hash); } # 如果请求为purge 将清除缓存 sub vcl_hit { if (req.request == "PURGE") { set obj.ttl = 0s; error 200 "Purged"; } return (deliver); } sub vcl_miss { return (fetch); } # sub vcl_fetch { if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") { /* * Mark as "Hit-For-Pass" for the next 2 minutes */ set beresp.ttl = 0 s; return (hit_for_pass); } if (beresp.http.Pragma ~"no-cache" || beresp.http.Cache-Control ~"no-cache" || beresp.http.Cache-Control ~"private") { return (deliver); } #为特定格式文件设置缓存时间,有多种格式可以直接在后面加-关注点 if (req.request == "GET"&&req.url ~ "(?i)\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$") { set beresp.ttl = 30d; } if (req.request == "GET"&&req.url ~ "(?i)\.(html|htm)$") { set beresp.ttl = 1d; } return (deliver); } # 设置返回状态 sub vcl_deliver { set resp.http.x-hits = obj.hits; if (obj.hits > 0) { set resp.http.X-Cache = "Hit test.com"; }else { set resp.http.X-Cache = "Miss test.com"; } set resp.http.Server = "BWM"; return (deliver); } # 定义错误 sub vcl_error { set obj.http.Content-Type = "text/html; charset=utf-8"; set obj.http.Retry-After = "5"; synthetic {" <?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>"} + obj.status + " " + obj.response + {"</title> </head> <body> <h1>Error "} + obj.status + " " + obj.response + {"</h1> <p>"} + obj.response + {"</p> <h3>Guru Meditation:</h3> <p>XID: "} + req.xid + {"</p> <hr> <p>Varnish cache server</p> </body> </html> "}; return (deliver); } sub vcl_init { return (ok); } sub vcl_fini { return (ok); } 四、Varnish运行 -u 以什么用运行 -g 以什么组运行 -f varnish配置文件 -a 绑定IP和端口 -s varnish缓存文件位置与大小 -w 最小,最大线程和超时时间 -t 缓存时间s -T varnish管理端口,主要用来清除缓存 -p client_http11=on 支持http1.1协议 -P(大P) /usr/local/varnish/var/varnish.pid 指定其进程码文件的位置,实现管理 停止varnish /usr/local/varnish/sbin/varnishd -u varnish -g varnish -f /usr/local/varnish/etc/varnish/default.vcl -a 10.0.0.202:80 -s file,/varnish/cache/varnish_cache.data,1G -w 1024,51200,10 -t 3600 -T 10.0.0.202:3000 企业里里面开启为100G 2.4.2、启动日志 # /usr/local/varnish/bin/varnishncsa -w /varnish/log/varnish.log & 日志加入开机启动: echo "/usr/local/varnish/bin/varnishncsa -w /data/varnish/logs/varnish.log &" >> /etc/rc.local 参数: -w 指定varnish访问日志要写入的目录与文件
Varnish
原创江山此夜寒 博主文章分类:linux server ©著作权
文章标签 软件 varnish 加速 代理 文章分类 服务器
-
Varnish && Varnish Cache
Varnishhttps://.varnish-cache.org/intro/index.html#intro
Varnish Varnish Cache Ubuntu