前言
在我的上一篇关于Nginx的动静分离实现博客中我提到了动静分离的意义,因为动静分离确实是一个有效又容易实现的解决问题的方案,那么这篇博客我再次演示动静分离的实战例子,不过这次的主角不是Nginx,而是varnish。
在下文中我会用varnish实现动静分离并且举例讲解varnish对后端服务器的调度功能以及服务器状态检查功能。
网络拓扑
操作
准备
如上面的网络拓扑图,这次使用到了四台CentOS7.3分别的角色:
1,varnish服务器,IP172.16.253.143,hostname:varnish
2,httpd服务器1,IP172.16.250.135,hostname:html1
3,httpd服务器2,IP172.16.254.235,hostname:html2
4,httpd+php服务器,IP172.16.250.39,hostname:php
整个实验过程中需要注意selinux和防火墙的限制。
第一步,配置httpd服务器和httpd+php服务器
配置httpd服务器是最简单的事了,就不做描述直接演示操作了。
#html1配置 [root@html1 ~]# yum install httpd -y [root@html1 ~]# echo '<h1>Html1 server</h1>' > /var/www/html/index.html [root@html1 ~]# systemctl start httpd #html2配置 [root@html2 ~]# yum install httpd -y [root@html2 ~]# echo '<h1>Html2 server</h1>' > /var/www/html/index.html [root@html2 ~]# systemctl start httpd #php配置 [root@php ~]# yum install php httpd -y [root@php ~]# echo '<?php phpinfo(); ?>' > /var/www/html/index.php [root@php ~]# systemctl start httpd
第二步,varnish服务器配置
在这一步中为了让整个配置过程思路更加清晰,我先实现后端只有一动一静服务器这样的拓扑,然后再在这个基础上实现两静一动这个拓扑,因为这样用到varnish的不同功能所以分开演示。
[root@varnish ~]# yum install varnish -y #安装包,varnish包在epel源里
[root@varnish ~]# vim /etc/varnish/default.vcl #打开配置文件
#更改配置文件为:
#注意:在这个配置文件中每一句结尾需要加上分号,不然要报错
backend html1 { #backend是定义后端服务器地址以及端口的,html1是给这个后端服务器命名后面调用
.host = "172.16.250.135"; #指定IP地址
.port = "80"; #指定端口号
}
backend php { #这里和上面是一样的,这个地方定义的是php服务器的
.host = "172.16.250.39";
.port = "80";
}
sub vcl_recv { #以下内容需写在vcl_recv下
if (req.url ~ "(?i)\.html") { #这里的意思是如果请求的url和后面双引号中的格式匹配的话就将请求转到html1
set req.backend_hint = html1;
}
if (req.url ~ "(?i)\.php") { #这里表示结尾匹配.php的请求都转到php服务器
set req.backend_hint = php;
}
}
[root@varnish ~]# vim /etc/varnish/varnish.params #打开配置文件
#更改默认监听端口6081为80
在正常的生产环境中varnish是不会直接作为前端的,在varnish前面还有诸如nginx的代理服务器,所以如果是完整的架构的话这里的端口改不改都没有什么影响,只是代理服务器在配置代理的时候需要注意一下而已,这里我只是做测试环境所以就直接把默认监听端口改成了80
那么现在就可以启动服务器了
[root@varnish ~]# systemctl start varnish [root@varnish ~]# ss -ntl #检查端口是否监听 State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 10 127.0.0.1:6082 *:* LISTEN 0 128 :::80 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::*
第三步,测试
访问172.16.253.143/index.html
如图所示
访问172.16.253.143/index.php
如上图,一切正常
两个静态一个动态拓扑实现
实现方法
从上面的配置可以知道,要把请求代理至后端服务器只需要配置一个backend就行了,但是这样的话同样的后端只能存在一台,这样显然不符合实际,那么后端服务器要实现负载均衡又怎么做呢。
varnish在实现后端服务器负载均衡的方法上和nginx类似但是略有不同,都是将多台服务器定义为一个组然后再调用,那么具体配置方法请看下面的操作。
[root@varnish ~]# vim /etc/varnish/default.vcl #打开配置文件 #添加以下内容 backend html2 { #增加html2的配置 .host = "172.16.254.235"; .port = "80"; } sub vcl_init { #这个要注意这是一个新的sub,是配置文件中的根配置,不能存在于其他任何sub中 new htmls = directors.round_robin(); #命名服务器组为htmls,定义调度算法为轮询 htmls.add_backend(html1); #添加组成员html1 htmls.add_backend(html2); #添加组成员html2 } #既然定义了静态服务器的组,那么在给后端服务器转发请求的时候就不能指定html1了需要指定htmls组 set req.backend_hint = htmls.backend(); #更改这一句中html1为htmls.backend()
写成这样基本上就已经完成了,下面可以测试一下
测试
其实在上面一步我留了一个坑,为了加深印象,我将需要注意的一个重要的问题写在测试这里。
那么配置文件我似乎已经配置完毕,现在重载一下配置文件然后测试结果
[root@varnish ~]# varnish_reload_vcl #重载配置文件 Loading vcl from /etc/varnish/default.vcl Current running config name is Using new config name reload_2017-09-08T16:37:32 Message from VCC-compiler: Symbol not found: 'directors.round_robin' at ('input' Line 32 Pos 17) new htmls = directors.round_robin(); ----------------#####################--- Running VCC-compiler failed, exited with 2 VCL compilation failed Command failed with error code 106 varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 vcl.load failed [root@varnish ~]#
如上所示,出现了报错信息,仔细一看错误提醒可以发现错误在directors.round_robin()上面,出现这个错误的原因是因为我没有加载directors模块,这个很重要千万不能忘了。那么现在我加上去然后再次重载配置文件
[root@varnish ~]# vim /etc/varnish/default.vcl #打开配置文件在vcl4.0下加上这么一句 import directors; [root@varnish ~]# varnish_reload_vcl Loading vcl from /etc/varnish/default.vcl Current running config name is Using new config name reload_2017-09-08T16:44:30 VCL compiled. VCL 'reload_2017-09-08T16:44:30' now active available 0 boot active 0 reload_2017-09-08T16:44:30 Done [root@varnish ~]# #顺利加载
虽然现在配置文件已经配置完毕,服务也正常,可以测试却有点尴尬了。因为varnish是缓存服务,后端静态网页服务器虽然设置的是轮询但是只要第一次访问成功,varnish就会把页面缓存下来下次访问的时候就提供已经缓存了的页面,那么无论怎么刷新页面都是同一个网页,这就很尴尬了。
不过也是有办法的,我可以清理一次缓存然后访问一次,但是需要写配置文件。
[root@varnish ~]# vim /etc/varnish/default.vcl #打开配置文件添加以下内容: sub vcl_purge { return (synth(200,"Purged")); } if (req.method == "PURGE") { #在sub vcl_recv下添加 return(purge); } [root@varnish ~]# varnish_reload_vcl Loading vcl from /etc/varnish/default.vcl Current running config name is Using new config name reload_2017-09-08T16:59:09 VCL compiled. VCL 'reload_2017-09-08T16:59:09' now active available 0 boot available 0 reload_2017-09-08T16:44:30 active 0 reload_2017-09-08T16:59:09 Done [root@varnish ~]# #重载配置文件
现在我开启另外一台服务器利用crul -X PURGE便可以清理缓存,现在开始测试吧。
[root@client ~]# curl http://172.16.253.143/index.html <h1>Html1 server</h1> [root@client ~]# curl http://172.16.253.143/index.html <h1>Html1 server</h1> #我这里连续访问两次都是html1在相应,那么我清理一次缓存再访问 [root@client ~]# curl -X PURGE http://172.16.253.143/index.html #清理缓存 <!DOCTYPE html> <html> <head> <title>200 Purged</title> #清理成功 </head> <body> <h1>Error 200 Purged</h1> <p>Purged</p> <h3>Guru Meditation:</h3> <p>XID: 65593</p> <hr> <p>Varnish cache server</p> </body> </html> [root@client ~]# curl http://172.16.253.143/index.html #然后再次访问 <h1>Html2 server</h1> #成功!! [root@client ~]#
可以看到清理缓存之后顺利访问到了html2,如果现在再次清理一下缓存再访问的话又可以访问到hmtl1了,后面就不再演示了。
完结撒花,要转载的朋友请注明转载,谢谢。