haproxy+varnish搭建高可用web缓存服务器

  套句马哥经常说的话,cache is king,在现在的企业架构中,都用到了缓存服务器,缓存,可以减轻对后端服务器的压力,而且对于请求比较频繁的热区数据,我们如果缓存在缓存服务器上,都会增加被命中的概率,对于大并发的请求情况下,对于后端的服务器也是一种保护。

     下面我们要介绍的是缓存服务器中的新秀,varnish,这是一款轻量级的缓存服务,相比squid,性能更高,速度更快,管理上还更加方便,被说烂的例子就是挪威最大的在线报纸,用3台varnish替换掉了12台squid,性能上还有提升,可见varnish的地位上升之快。

     varnish于nginx有着众多的相似之处,它们都是各自领域的新秀,而且,都是有一个master进程,多个子进程所构成,这次,我要利用varnish的缓存功能,加上haproxy的调度和高可用性,搭建一个高可用,且具有很强缓存的web服务

 

系统:CentOS 6.5

服务器数量:5台

所需要的软件及下载地址:

varnish-3.0.5-1.el6.x86_64.rpm

varnish-libs-3.0.5-1.el6.x86_64.rpm

https://repo.varnish-cache.org/redhat/varnish-3.0/el6/x86_64/varnish/
haproxy.x86_64 0:1.4.24-2.el6     #通过yum安装 

 

首先,我们先在node3、和node4这两个主机上,提供web服务,提供主页

node3上:

[root@node3 ~]# cat /var/www/html/index.html
<h1>I am a linux lover</h1>

node4上:

[root@node4 ~]# cat /var/www/html/index.html
<h1>shell is difficult to learn</h1>

然后,将这两个web服务启动

[root@node3 ~]# service httpd start
[root@node4 ~]# service httpd start

后端的web服务已完成,下面就是搭建我们的varnish缓存服务器了

在node1和node2上都执行下列操作

[root@node1 ~]# yum install varnish-libs-3.0.5-1.el6.x86_64.rpm varnish-3.0.5-1.el6.x86_64.rpm      #可以自动解决依赖关系

备份varnish的配置文件

[root@node1 ~]# cp /etc/varnish/default.vcl /etc/varnish/default.vcl.bak

编辑varnish的启动脚本的配置文件,让其监听在80端口上,而且,指定存储类型为mallo

VARNISH_LISTEN_PORT=80     #监听在80端口
VARNISH_STORAGE_SIZE=100M     #缓存大小为100M
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"     #这里是调用上面的变量

然后,启动varnish服务

[root@node2 ~]# service varnish start
[root@node1 ~]# ss -tlnp | grep 80     #此时,80端口已经被监听(最好确保我们的其他web程序是关闭的)
LISTEN     0      128                      :::80                      :::*      users:(("varnishd",8840,8))
LISTEN     0      128                       *:80                       *:*      users:(("varnishd",8840,7))

登录到我们的varnish的控制端查看

[root@node2 ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

-S:指定密钥文件

-T:指定可以登录的管理员的地址和端口,这个是在/etc/sysconfig/varnish文件中定义的

 

实验要求:(对varnish而言)

1、要通过负载均衡的方式调度后端的两个web服务器

2、可以在后端的web服务器的日志文件上,查看真正访问web服务的客户端的IP地址

3、实现对后端两个web服务器健康状态的检测


使用轮询的调度方法

在/etc/varnish/目录中新建一个lb.vcl的文件,作为负载均衡作用的配置文件,配置如下

backend web1 {
  .host = "192.168.77.13";
  .port = "80";
}
backend web2 {
  .host = "192.168.77.14";
  .port = "80";
}
director webs round-robin {     #使用轮询的调度算法
    {.backend = web1;}
    {.backend = web2;}
}
 
sub vcl_recv {
    set req.backend = webs;     #要调用上面这个组
}

然后,我们可以通过上面的管理接口,使用这个配置文件了

varnish> vcl.load lb ./lb.vcl     #加载这个配置
200       
VCL compiled.     #这样就是编译成功的提示
varnish> vcl.use lb     #使用上面定义的配置
200

此时,我们在浏览器中测试,先访问node1,再访问node2

之后,无论怎么刷新都不改变了,调出开发者工具查看

 

我们可以查看我们的后端web服务器的日志文件

[root@node4 ~]# tail /var/log/httpd/access_log
192.168.77.12 �C - 
[20/Sep/2014:20:32:28 +0800] "GET /favicon.ico HTTP/1.1" 404 288 "-" 
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 
Firefox/32.0"
192.168.77.11 �C - [20/Sep/2014:20:35:23 +0800] "GET / 
HTTP/1.1" 200 37 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 
Safari/537.36

此时,显示的是我们的varnish服务器的地址

在后端记录客户端IP地址

 

更改配置文件,使其能够记录客户端的IP地址,在上面的实验上扩展

[root@node1 varnish]# cp lb.vcl log.vcl
[root@node1 varnish]# vim log.vcl 
backend web1 {
  .host = "192.168.77.13";
  .port = "80";
}
backend web2 {
  .host = "192.168.77.14";
  .port = "80";
}
director webs round-robin {
    {.backend = web1;}
    {.backend = web2;}
}
sub vcl_recv {
    set req.http.X-Forwarded-For = clinet.ip;
    if (req.url ~ "index.html$") {
    return (pass);
    }
    set req.backend = webs;
}

两个web服务器都做修改

然后,将后端的web记录日志的格式修改如下

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

重启httpd服务

[root@node3 ~]# service httpd restart

回到varnish服务器,加载新的配置

varnish> vcl.load log ./log.vcl
200       
VCL compiled.
varnish> vcl.use log
200

到浏览器中,分别访问


发现,网页发生了变化,这是缓存时间结束了,新的请求返回新的网页,之后,连续刷新时,就不会缓存了

 

查看我们后端web服务器的日志文件

[root@node3 ~]# tail /var/log/httpd/access_log 
192.168.77.11 �C
 - [20/Sep/2014:20:35:24 +0800] "GET /favicon.ico HTTP/1.1" 404 288 "-" 
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/35.0.1916.114 Safari/537.36"
 
[root@node4 ~]# tail /var/log/httpd/access_log
192.168.77.1,
 192.168.77.1 �C - [20/Sep/2014:20:54:51 +0800] "GET / HTTP/1.1" 200 37 
"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
 Gecko) Chrome/35.0.1916.114 Safari/537.36"

此时,上面记录的都是当前windows主机的地址了,如果没有,可以多次刷新网页后查看,可能还是缓存命中

 

健康检查机制:

如果,我们的后端web宕机了呢?我们是否发觉?下面引入健康检查机制

[root@node1 varnish]# cp log.vcl health.vcl
[root@node1 varnish]# vim health.vcl 
probe healthchk {          #定义一个健康检测的标准
  .url = "/";
  .interval = 5s;
  .timeout = 2s;
}
backend web1 {
  .host = "192.168.77.13";
  .port = "80";
  .probe = healthchk;     #调用健康检测
}
backend web2 {
  .host = "192.168.77.14";
  .port = "80";
  .probe = healthchk;
}
director webs round-robin {
    {.backend = web1;}
    {.backend = web2;}
}
sub vcl_recv {
    set req.http.X-Forwarded-For = client.ip;
    if (req.url ~ "index.html$") {
    return (pass);
    }
    set req.backend = webs;
}

加载新的配置,并使用

varnish> vcl.load health ./health.vcl
200       
VCL compiled.
varnish> vcl.use health
200

此时,我们可以将后端的两个web服务器的http服务都停掉

[root@node4 ~]# service httpd stop

在我们的浏览器中查看

此时,健康状态就显示出来了,不过,你可能要等缓存失效后,才能刷出这个网页

 

最后,我们可以在前端加上一个haproxy,作为这两个varnish缓存服务器的负载均衡器

安装haproxy,这里使用yum的方式

[root@hap ~]# yum install -y haproxy

备份配置文件,并且对配置文件进行编辑

[root@hap ~]# cd /etc/haproxy/
[root@hap haproxy]# cp haproxy.cfg haproxy.cfg.bak
[root@hap haproxy]# vim haproxy.cfg
frontend main *:80
    maxconn 3000
    default_backend webs
backend webs
    balance uri
    server varnish1 192.168.77.11 check port 80
    server varnish2 192.168.77.12 check port 80
    server back 127.0.0.1:8080 backup
    stats enable     #开启status功能
    stats admin if TRUE     #开启管理功能
    stats hide-version     #隐藏版本号
    stats scope .     #当前作用域
    stats uri  /admin?stas     #自定义uri
    stats realm admin\ authorizen     #用户认证模式
    stats auth hapadmin:varnish     #认证的用户名和密码

然后,启动haproxy服务

[root@hap haproxy]# service haproxy start
[root@hap haproxy]# ss -tlnp | grep 80     #此时,已经监听80端口
LISTEN     0      128                       *:80                       *:*      users:(("haproxy",2497,4))

将后端的两个web服务启动,然后,在浏览器中访问

 

此时,还可以查看我们的status状态页


此时,我们还可以提供sorry server,即这里的back,在haproxy的本机上

[root@hap haproxy]# cat /var/www/html/index.html
<h1>Sorry! please wait!</h1>

同时,还得修改httpd的配置文件,使其监听在8080端口上,因为80被haproxy占用

[root@hap haproxy]# vim /etc/httpd/conf/httpd.conf 
Listen 8080     #修改此项
并且,把http服务启动
[root@hap haproxy]# service httpd start

我们可以在stats页面上,让后端的两个varnish服务器停止工作,刷浏览器

访问我们的站点


当后端主机宕机后,我们的haproxy上的sorry server就能派的上用场了,详细的varnish的内容会在近期的varnish原理知识中发布出来,这也是自己的任务。


你可能感兴趣的:(haproxy,缓存,varnish)