Haproxy + Varnish 实现WEB静态页面缓存
一.缓存介绍及Haproxy+Varnish架构图:
1.)简介:现阶段的互联网时代,缓存成为一个必不可少的一环,不论是对于整体架构的优化,减少服务器的压力,加速用户访问速度,都是需要用到缓存。而缓存的种类也是很多,例如CDN,Squid,Memcached,Varnish,已经成为一个中型,大型架构中基本的实现。
2.)CDN缓存技术是根据全国各地的用户,直接缓存到离用户最近的地方。
3.)Squid是处于前端的缓存,并且可以用作为正向代理,反向代理,透明代理。
4.)Memcached主要用于应用服务器和数据库之间的缓存,提高缓存命中率,减轻数据库的压力。
5.)Varnish缓存是介于代理服务器与WEB服务器之间,通过代理服务器访问到主机名后,直接先找 Varnish缓存,如果查找不到,再去麻烦后端的WEB服务器。
而下图就是作为Varnish所工作的区域:
二.Varnish工作原理介绍:
1.)Varnish进程分为master进程和child进程。master进程读入命令,进行一些初始化,而fork监控child进程。child进程分配若干线程进行工作,主要包括管理线程和很多woker线程。
2.)文件缓存部分,master读入存储配置,调用合适的存储类型,然后创读入相应大小的缓存大文件。接着,master初始化管理该存储空间的结构体。这些变量都是全局变量,在fork以后会被child进程所继承(包括文件描述符)。
3.)在child进程主线程初始化过程中,将前面打开的存储大文件整个mmap到内存中,创建并初始化分配内存。如果此时分配一个10M的内存,仅占用2M,其余8M内存暂时空闲,而不是全部使用。
4.)Varnish的accept负责接受新HTTP连接的线程开始等待用户,如果有新的HTTP连接过来,它总负责接收,然后叫醒某个等待中的线程,并把具体的处理过程交给它。Worker线程读入HTTP请求的URI,查找已有的object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
5.)分配缓存时,根据所读到的object大小,创建相对应大小的缓存文件。如果内存已经占用满了,会根据设定的ttl值或者手动去释放内存。当内存已经占满的时候,没有自动释放内存或者手动释放内存,则Varnish会选择到swap分区继续缓存。
三.安装Varnish,版本是在官网下载的:
# yum installvarnish-3.0.5-1.el6.x86_64.rpm varnish-libs-3.0.5-1.el6.x86_64.rpm
四.说说Varnish VCL内置变量:如下图
五.配置Varnish:
1.)刚安装好的varnish默认配置文件基本都是被注释掉的。用到什么配置的时候解释什么的。
# curl http://172.16.32.14 <h1>Varnishproxy cache</h1>
2.)修改Varnish默认监听端口。
# vim/etc/sysconfig/varnish VARNISH_LISTEN_PORT=80 #修改默认监听端口为80端口 VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"
3.)定义后端主机。
# vim/etc/varnish/default.vcl backend default { #定义后端主机 .host = "172.16.32.14"; .port = "80"; }
可以看到通过访问172.16.32.10已经访问到172.16.32.14WEB主机中的内容了。
4.)Varnishadm管理使用。
# varnishadm -S/etc/varnish/secret -T 127.0.0.1:6082 #指定管理地址及端口 200 varnish>vcl.list #查看当前活动的vcl 200 active 1 boot varnish>vcl.load proxy proxy.vcl #定义一个新的vcl 200 VCL compiled. varnish>vcl.use proxy #使新的vcl生效 200 varnish>vcl.list 200 available 1 boot active 0 proxy
5.)定义http响应客户端报文。
# vim/etc/varnish/proxy.vcl sub vcl_deliver { if (obj.hits > 0) { #定义缓存次数命中大于0就是在缓存中获取到的 set resp.http.X-Cache = "HIT via"+ " " + server.hostname; #在http响应报文中添加HIT自定义字符串 } else { set resp.http.X-Cache ="MISS via" + " " + server.hostname; #如果没命中的http响应报文 } }
6.)重新载入一个vcl。
varnish>vcl.load proxy2 proxy.vcl #重新载入一个VCL,proxy2仅是个名字 200 VCL compiled. varnish>vcl.use proxy2 #使新加入的proxy2生效 200 varnish>
可以看到测试的响应结果,由于是浏览器是无痕浏览,每次都会显示未命中。正常访问的时候如下图:
7.)定义varnish为代理服务器加缓存服务器。
# vim proxy.vcl backend web1 { #定义后端两个主机 .host = "172.16.32.14"; .port = "80"; .probe = { .url = "/index.html"; #需要缓存的页面 .interval = 2s; #检查间隔时长 .window = 8; #维持8个Healthy .threshold = 2; #最少2此window是成功的缓存 } } backend web2 { .host = "172.16.32.15"; .port = "80"; .probe = { .url = "/index.html"; .interval = 2s; .window = 8; .threshold = 2; } } directorwebservice round-robin { #包含起定义的两个主机 { .backend = web1; } { .backend = web2; } } sub vcl_recv { set req.backend = webservice; #调用两个主机 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; } if (req.url ~ "^/test.html$"){ #如果访问的是test.html,将不缓存 return(pass); } return (lookup); } } 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; } return (deliver); }
8.)使新定义的acl生效。
varnish>vcl.load proxy8 proxy.vcl 200 VCL compiled. varnish>vcl.use proxy8 200 varnish>vcl.load proxy9 proxy.vcl 200 VCL compiled. varnish>vcl.use proxy9 200 varnish>backend.list #查看在线列表 200 Backend name Refs Admin Probe default(172.16.32.14,,80) 3 probe Healthy (no probe) web1(172.16.32.14,,80) 5 probe Healthy 8/8 web2(172.16.32.15,,80) 5 probe Healthy 8/8
六.接下来是Haproxy + Varnish + Httpd组合:
1.)首先在172.16.32.11节点上安装varnish,并将172.16.32.10如下文件复制到想对应的目录
# scp /etc/varnish/* 172.16.32.11:/etc/varnish/ root@172.16.32.11‘spassword: default.vcl 100% 3122 3.1KB/s 00:00 proxy.vcl 100% 660 0.6KB/s 00:00 secret 100% 37 0.0KB/s 00:00 # scp/etc/sysconfig/varnish 172.16.32.11:/etc/sysconfig/ root@172.16.32.11‘spassword: varnish 100%3659 3.6KB/s 00:00
2.)在172.16.32.10的节点删除如下段落:
backend web2 { .host = "172.16.32.15"; .port = "80"; .probe = { .url = "/index.html"; .interval = 2s; .window = 8; .threshold = 2; } } directorwebservice round-robin { { .backend = web1; } { .backend = web2; } }
3.)而在172.16.32.15节点是相反操作。
4.)切换到172.16.32.15节点,启动varnish,添加新的vcl。
varnish>vcl.load proxy proxy.vcl 200 VCL compiled. varnish> vcl.useproxy 200
访问测试两个节点
5.)安装haproxy,在172.16.32.9节点上。
# yum installhaproxy # vim/etc/haproxy/haproxy.cfg frontend main*:80 default_backend varnish backend varnish balance roundrobin server s1 172.16.32.10:80 server s2 172.16.32.11:80
输入地址172.16.32.9,反问测试
因为之前的haproxy主机有WEB服务,测试的时候haproxy使用的8080端口,但是不影响正常访问。
可以看到,网页缓存下来了,并且实现调度。关于haproxy这里只是简单的使用下,之后会有详细的介绍,主要是varnish缓存。varnish可以缓存很多节点,我这里仅是1对1的实现了。
本文出自 “你对谁都微笑” 博客,请务必保留此出处http://54276311.blog.51cto.com/9130197/1558091