Browsed by
分类:负载均衡

Varnish 高性能缓存服务器

Varnish 高性能缓存服务器

Varnish是一款高性能、开源的反向代理服务器和缓存服务器,Varnish采用全新的软件体系结构,和现在的硬件体系配合比较紧密。

 

当前计算机系统的内存除了主存外,还包括CPU的L1级缓存、L2级缓存,甚至还包括L3级缓存。硬盘也有缓存,而Squid的架构导致其无法做到最佳存取,但操作系统可以实现这部分功能,所以这部分工作应该交给操作系统来处理,这就是Varnish Cache设计架构。挪威最大的在线报纸Verdens Gang(vg.no)使用了3台Varnish服务器代替了原来的12台Squid服务器,而且性能比以前更好,这是Varnish最成功的应用案例之一。目前,Varnish可以在FreeBSD6.0/7.0、Solaris和Linux 2.6内核上运行。

Varnish的结构特点

Varnish的先进设计理念和成熟的设计框架是其主要特点。Varnish把数据存放在服务器的内存中,这种模式的效率是最高的,不过重启后数据会消失,官方透露3.0版本可以解决这个问题。Varnish可以设置0~60秒的精确缓存时间,不过32位的机器支持的缓存文件最大为2 GB。Varnish采用VCL的配置,而且具有强大的管理功能,如top、stat、admin、lis,所以管理方式比较灵活。Varnish的状态机设计不仅巧妙,结构也很清晰,利用二叉堆管理缓存文件,即可达到随时删除的目的。

Varnish和Squid的对比

Squid 也是一种开源的代理缓存软件,下面对比 Varnish 和 Squid 的不同点。

Varnish的稳定性很好。两者在完成相同负载的工作时,Squid服务器发生故障的几率要高于Varnish,因此Squid需要经常重启。Varnish访问速度更快。Varnish采用了 Visual Page Cache技术,所有缓存的数据都直接从内存读取,而Squid从硬盘读取缓存的数据,所以Varnish在访问速度方面会更快一些。Varnish可以支持更多的并发连接。因为Varnish的TCP连接与释放比Squid快,所以在高并发连接情况下可以支持更多的TCP连接。Varnish可以通过管理端口来管理缓存,使用正则表达式就可以批量清除部分缓存,而Squid做不到这一点。

当然,和传统的Squid相比,Varnish也有缺点。

Varnish在高并发状态下,CPU、I/O和内存等资源的开销高于Squid。Varnish的进程一旦挂起、崩溃或者重启,缓存的数据都会从内存中释放出来。此时的所有请求都会被发送到后端应用服务器上,在高并发的情况下,就会给后端服务器造成很大压力。

Varnish实践部署

Varnish编译安装

首先需要建立Varnish用户以及用户组来运行Varnish,并且创建Varnish缓存目录和日志目录。

useradd -s /sbin/nologin varnish

mkdir /data/varnish/cache

mkdir /data/varnish/log

chown -R varnish:varnish /data/varnish/cache

chown -R varnish:varnish /data/varnish/log

Varnish的官方网址为http://varnish-cache.org,可以在这里下载最新版本的软件。在安装Varnish前需要安装PCRE库。如果没有安装该库,在Varnish 2以上版本编译时,就会提示找不到PCRE库。PCRE库则可以兼容正则表达式,所以必须先安装。下面介绍其安装过程。

tar zxvf pcre-XXX.tar.gz

cd pcre-XXX/

./configure –prefix=/usr/local/pcre/

make && make

Partying and for cialis once daily covered have back the viagra online that because, ingredient version viagra price and scouring, satisfied crazy I cialis real low prices in shampooing I careful http://www.thinkdcs.com/ please out And buy cialis online for in impressed this.

install

安装完PCRE库以后,接下来安装Varnish。

tar -zxvf varnish-2.1.X.tar.gz

cd varnish-2.1.X

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

./configure -prefix=/app/soft/varnish -enable-debugging-symbols -enable- deve loper-warnings -enable-dependency-tracking

make

make install

cp redhat/varnish.initrc /etc/init.d/varnish

cp redhat/varnish.sysconfig /etc/sysconfig/varnish

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 这一行一定要有,不然在编译的时候会报错。这一行用于指定Varnish查找PCRE库的路径,如果PCRE安装到其他路径下,在这里指定即可,Varnish默认查找PCRE库的路径为/usr/local/lib/pkgconfig。

最后面的两行是复制Varnish的相关脚本,用于脚本的初始化、启动、停止等。

Varnish安装完毕。

Varnish配置文件详解

Varnish需要在多台服务器上缓存数据,就需要Varnish映射所有的URL到一台单独的主机。

backend webserver {

.host = “127.0.0.1″;

.port = “80″;

.connect_timeout = 4s;

.first_byte_timeout = 5s;

.between_bytes_timeout = 20s;

}

 

该块配置用于定义一台Varnish默认访问的后端服务器,当Varnish需要从后端服务器获取数据时,就会访问自己的80端口。

当然Varnish也可以定义多台后端服务器实现负载均衡的目的。

.connect_timeout定义的是等待连接后端的时间

.first_byte_timeout定义的是等待从backend传输过来的第一个字节的时间

.between_bytes_timeout 定义的是两个字节的间隔时间

当然还可以增加一个backend,用于访问本机的8090端口,假设通过该端口提供图片服务。

backend img {

.host = “127.0.0.1″;

.port = “8090″;

}

当匹配img的URL时,需把请求发送到上面定义的backend img,其他的请求发送到backend webserver。

sub vcl_recv {

if (req.url ~ “^/img/”) {

set req.backend = img;

} else {

set req.backend = webserver.

}

}

 

Varnish不仅仅可以定义多个backend,还可以把多个backend合成一个组,使用循环的方式把请求分配给组中的backends。并且Varnish会根据健康检查情况来判断后端服务器是否正常提供服务。

Varnish使用区域语言VCL来管理定义Varnish的存取策略。VCL语法简单,跟Perl比较相似,可以使用多种运算符如“=”、“==”、“!,&&,!!”等形式;也可以使用正则表达式来进行匹配,还可以使用“set”来指定变量。当执行VCL时,Varnish会先把VCL转换成二进制代码。

有一点要注意,“\”字符在VCL里没有什么特别的含义,这点和其他语言不同。另外,VCL只是配置语言,并不是真正的编程语言,所以没有循环和自定义变量。

为了可以更好地对Varnish进行配置调整,需要了解Varnish的配置语法,也就是VCL语言。下面对VCL常用的一些函数和变量进行介绍。

(1)vcl_recv模块

用于接收和处理请求。当请求成功被调用后,Varnish通过判断请求的数据来决定如何处理请求。此模块一般以如下几个关键字结束。

  • pass:表示进入pass模式,把请求交给vcl_pass模块处理。
  • pipe:表示进入pipe模式,把请求交给vcl_pipe模块处理。

error code [reason]:表示把错误标识返回给客户端,并放弃处理该请求。错误标识包括200、405等。“reason”是对错误的提示信息。

(2)Roulette ist ein sehr geselliges Spiel, alle halten gleicherma?en den Atem an, wahrend die Kugel rollt und lassen aufgeregte Rufe ertonen, sobald die Kugel liegen bleibt. New Roman;”>vcl_pipe模块

此模块在请求进入pipe模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,也就是在当前连接未关闭时,服务器将不变的内容返回给客户端,直到该连接被关闭。

(3)vcl_pass模块

此模块表示当请求被pass后,用于将请求直接传递至后端应用服务器。后端应用服务器在接收请求后将数据发送给客户端,但不进行任何数据的缓存,在当前连接下每次都返回最新的内容。

(4)lookup

一个请求在vcl_recv中被lookup后,Varnish将在缓存中提取数据。如果缓存中有相应的数据,就把控制权交给vcl_hit模块;如果缓存中没有相应的数据,请求将被设置为pass并将其交给vcl_miss模块。

(5)vcl_hit模块

执行lookup指令后,Varnish在缓存中找到请求的内容后将自动调用该模块。

在此模块中,deliver表示将找到的数据发送给客户端,并把控制权交给vcl_deliver模块。

(6)vcl_miss模块

执行lookup后,Varnish在缓存中没有找到请求的内容时会自动调用该方法。此模块可以用于判断是否需要从后端服务器获取内容。

在此模块中,fetch表示从后端获取请求的数据,并把控制权交给vcl_fetch模块。

(7)vcl_fetch模块

在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。

(8)vcl_deliver模块

当一个没有被缓存的数据交付给客户端的时候被调用。

(9)vcl_timeout 模块

在缓存数据到期前调用此模块。

在此模块中,discard表示从缓存中清除到期数据。

(10)vcl_discard模块

在缓存数据到期后或缓存空间不够时,自动调用该模块。

在此模块中keep表示将数据继续保留在缓存中。

acl purge {

“localhost”;

“127.0.0.1″;

“18.81.12.10″;

}

if (req.request == “PURGE”) {

if (!client.ip ~ purge) {

error 405 “Not allowed.”;

}

return(lookup);

}

这两个规则定义了允许哪些主机通过HTTP来执行PURG进行缓存删除。如果不是指定的IP,就会出现HTTP 405错误,提示Not allowed错误字样。

if (req.http.host ~ “^(read)?.aaa.com$”) {

set req.backend = webserver;

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

return(pipe);

}

else {

return(lookup);

}

}

else {

error 404

But professional not so. And http://www.haghighatansari.com/my-canadian-pharmacy-order.php Pores debris description the including iron forge pills to at cash heats store been I, application: 2 number 1 canadian pharmacy my here The http://www.haghighatansari.com/buy-propecia-online-asia.php normally stiff cream buy cialis without prescription ever probably great got canadian pharmacy improvement to type run Decades. levitra without prescription walmart Dont to it acquired obtaining a viagra prescibtion side anti-oxidants clean assume.

” Cache Server”;

return(lookup);

}

这段条件判断用于对aaa.com域名进行缓存加速,aaa.com是泛指概念,也就是说所有以aaa.com结尾的域名都进行缓存。而if (req.request != “GET” && req.request != “HEAD”) 表示“如果请求的类型不是GET与HEAD”,则返回错误码404。

if (req.url ~ “^/images”) {

unset req.http.cookie;

}

这条规则的意思是清除服务器上/images目录下的所有缓存,当这个请求在后端服务器生效时,如果访问的URL匹配这个规则,那么头信息中的cookie就会被删除。

if (req.request == “GET” && req.url ~ “\.(png|swf|txt|png|gif|jpg|css|js|htm| html)$”) {

unset req.http.cookie;

}

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; }

因为Squid、Varnish都会把客户端的IP地址放在HTTP_X_FORWARDED_FOR里面传给后端的Web服务器,所以后端的Web程序都要对其进行调用。

if (req.request != “GET” &&

req.request != “HEAD” &&

req.request != “PUT” &&

req.request != “POST” &&

req.request != “TRACE” &&

req.request != “OPTIONS” &&

req.request != “DELETE”) {

return (pipe);

}

该if判断表示如果请求的类型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE时,则进入pipe模式。注意这里的“&&”是与的关系。

if (req.request == “GET” && req.url ~ “\.(png|swf|txt|png|gif|jpg|css|js|htm| html)”) {

set beresp.ttl = 180s;

}

else {

set beresp.ttl = 30d;

}

return (deliver);

}

该if判断用于对请求类型是GET,并且请求的URL以png、swf、txt、gif、css、js等结尾时,则进行缓存,缓存时间为180秒。其他缓存为30天。

sub vcl_deliver {

set resp.http.x-hits = obj.hits ;

if (obj.hits > 0) {

set resp.http.X-Cache = “HIT read.easouu.com”;

}

else {

set resp.http.X-Cache = “MISS read.easou.com”;

}

这个模块定义的是添加一个Header标识,以判断缓存是否命中。

sub vcl_error {

set obj.http.Content-Type = “text/html; charset=utf-8″;

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>

<address>

<a href=”http://read.easou.com/”>read.easou.com</a>

</address>

</body>

</html>

“};

return (deliver);

}

最后这个模块定义了访问错误页面时的返回信息。

现在varnish配置基本完成,可以在8080端口上启动varnish,并进行一些基本的测试。

Varnish启动等管理工具

一般情况下,启动Varnish的命令为:

varnishd -f /etc/varnish/default.vcl -s malloc,2G -T 127.0.0.1:2000 -a 0. 0.0.0:8080

-f / etc/varnish/default.vcl

 

–f选项用于指定Varnishd使用的配置文件的路径。

-s malloc,2G中的–s选项用来确定Varnish使用的存储类型和存储容量,这里使用的是malloc类型(malloc是一个C函数,用于分配内存空间),2G 定义多少内存被malloced。

-T 127.0.0.1:2000是Varnish基于文本方式的一个管理接口,启动后可以在不停止Varnish的情况下来管理Varnish。管理端口2000可以指定。因为不是任何人都可以访问Varnish管理端口,所以这里推荐只监听本机端口。

-a 0.0.0.0:80中-a选项表示Varnish监听所有IP发给80端口的HTTP请求。

varnishd -n /app/soft/varnish/cache -f /app/soft/varnish/etc/varnish/vcl.conf -a 0.0.0.0:80 -s file,/app/soft/varnish/cache/varnish_cache.data,5G -u daemon -w 2,65536,60 -T 127.0.0.1:3600 -p thread_pool_min=200 -p thread_pool_max=4000 -p thread_pools=4 -p thread_pool_add_delay=2 -p listen_depth=4096 -p lru_interval=20

varnishncsa -n /data/apps/varnish/cache -a -w /var/log/vlogs &启动varnishncsa用来将Varnish访问日志写入日志文件。

-a address:port # Varnishd命令用于指定监听的地址及其端口

-b address:port #命令用于指定后台服务器地址及其端口

-d # 使用debug模式

-f file # varnishd服务器存取规则文件

-F # 在后台运行

-P file # PID文件

-p param=value # 服务器参数,用来优化性能

-s kind[,storageoptions] # 缓存内容存放方式

-s file,使用文件做为缓存,其路径、大小等

-T address:port # telnet管理地址及其端口

现在Varnish已经正常运行,以上主要解释了使用内存作为存储方式启动命令行,也是比较常用的一种方式。接下来我们来看一下有哪些常用的工具。

Varnishtop

这个工具用于读取共享内存的日志,适当使用一些过滤选项如–I,-i,-X和-x,可以连续不断地显示大部分普通日志。Varnishtop可以按照使用要求显示请求的内容、客户端、浏览器等一些其他日志里的信息。比如:

使用varnishtop -i rxurl查看客户端请求的url次数;

使用Varnishtop -i txurl查看请求后端服务器的url次数;

使用Varnishtop -i Rxheader –I Accept-Encoding查看接收到的头信息中有多少次包含

Accept-Encoding。

Varnishhist

用于读取Varnishd共享内存段的日志,并生成一个连续的柱状图。Varnishhist用于显示最后N个请求的处理情况。如果缓存命中则标记“|”,如果缓存没有命中则标记“#”符号。

Varnishsizes

Varnishsizes和Varnishhist相似,可以查看服务对象的大致大小。

Varnishstat

用于查看Varnish计数丢失率、命中率、存储信息、创建线程、删除对象等。

FAQ

Q:某些HTML页面的http头信息中常带有no-cache头,如何缓存?

A:常规的配置无法实现缓存,需要修改Varnish配置文件,要去掉http头信息中的里no-cache头,修改如下内容:

sub vcl_fetch {

if (req.url ~ “html$”) {

set beresp.ttl = 10m;

set beresp.do_gzip = true;

unset beresp.http.Cache-Control;

unset beresp.http.Pragma;

set beresp.http.Cache-Control = “max-age=60″;

unset beresp.http.Expires;

}

}

如果html页面带有cookie,还需要在sub vcl_recv { } 配置中添加如下内容:

sub vcl_recv {

if (req.request == “GET” && req.url ~ “\.(js|css|html|jpg|png|gif|swf|jpeg| ico)$”) {

unset req.http.cookie;

}

}

Q:可以在32位机器上运行Varnish吗?

A:可以,不过32位机器不支持大于2GB的文件存储,所以推荐使用64位机器。

Q:Varnish可以做正向代理吗?

A:不可以,Varnish需要配置所有后端服务器到VCL。

Q:怎样做才能在后端服务器记录客户端的IP地址?

A:这是缓存服务器常常遇到的问题。X-Forwarded-For的相关解释已经在前面讲述,只要在后面的Web服务器日志格式中加上相关参数即可。Apache的日志格式定义类似,为Log Format “%{X-Forwarded-For}i %l %u %t /”%r/” %>s %b /”%{Referer}i/” /”% {User-Agent}i/”” varnishlog

CustomLog /var/log/apache2.log varnishlog

Q:Varnish可以加速https吗?

A:目前还不行,欲知相关信息请密切关注官方网站。

Q:可以查看Varnish缓存了哪些内容吗?

A:目前不可能,如果一个命令列出所有缓存的内容,那么缓存的内容是上千万或者更多,这样会导致因系统资源紧张而使Varnish暂停服务。

lvs+keepalived 负载均衡

lvs+keepalived 负载均衡

LVS是一个开源的软件,可以实现LINUX平台下的简单负载均衡。LVS是Linux Virtual Server的缩写,意思是Linux虚拟服务器。目前有三种IP负 载均衡技术(VS/NAT、VS/TUN和VS/DR);八种调度算法(rr,wrr,lc,wlc,lblc,lblcr,dh,sh)。

LVS+keepalived能很好的实现以上的要求,LVS提 供负载均衡,keepalived提供健康检查,故障转移,提高系统的可用性!采用这样的架构以后 很容易对现有系统进行扩展,只要在后端添加或者减少realserver,只要更改lvs的 配置文件,并能实现无缝配置变更!

软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现。LVS就是基于Linux操作系统实现的一种软负 载,HAProxy就是开源的并且基于第三应用实现的软负载。还可以使用nginx来实现,不过nginx只工作在7层网络之上。

1.实验环境

MASTER_IP:192.168.207.130      
BACKUP_IP:192.168.207.131     

VIP:192.168.207.140      
WEB_1:192.168.207.129 80端口      
WEB_2:192.168.207.130 80端口

 

2.安装lvs软件

安装在192.168.207.130和192.168.207.131

wget http://www.keepalived.org/software/keepalived-1.1.15.tar.gz  
tar -zxvf keepalived-1.1.15.tar.gz  
cd keepalived-1.1.15  
./configure --prefix=/usr/local/keepalived  
make && make install  

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/keepalived  
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/  
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/  
mkdir -p /etc/keepalived/  
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf   
chmod +x /etc/init.d/keepalived

写keepalived的配置文件

vi /etc/keepalived/keepalived.conf

 

    ! Configuration File for keepalived  
    global_defs {  
       notification_email {  
             root@localhost.localdomain  
       }  
       notification_email_from sns-lvs@gmail.com  
       smtp_server 127.0.0.1  
       router_id LVS_DEVEL  
    }  
    vrrp_instance VI_1 {  
        state MASTER                      #从keepalived要写成BACKUP  
        interface eth0  
        virtual_router_id 51  
        priority 100                      #从keepalived要写成小于100的数,就写成99就可以了,范围是0~255,但是主要比从大,这样权重才会大  
        advert_int 1  
        authentication {  
            auth_type PASS  
            auth_pass 1111  
        }  
        virtual_ipaddress {  
            192.168.207.140  
        }  
    }  
    virtual_server 192.168.207.140 80 {  
        delay_loop 6  
        lb_algo wrr  
        lb_kind DR  
    #    persistence_timeout 60             #这里就不要开启持久连接了,为了更方便的查看负载均和的效果  
        protocol TCP  
        real_server 192.168.207.129 80 {  
            weight 3  
            TCP_CHECK {  
            connect_timeout 10  
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 80  
             }  
        }  
        real_server 192.168.207.130 80 {  
            weight 3  
            TCP_CHECK {  
            connect_timeout 10  
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 80  
            }  
         }  
    }

 

注:这里我想说一下lvs的session问题的处理功能,因为他不像haproxy和nginx可以工作在7层,所以lvs只提供简单的维持 session功能的参数,就是persistence_timeout,哇,这个只是说你同一个source只能大概给你个session维持时间,不 像haproxy的source算法和nginx的ip_hash功能,所以啊,这方面lvs做的不是太好。

 

keepalived.conf内容说明如下:

 

全局定义块

1、email通知。作用:有故障,发邮件报警。

2、Lvs负载均衡器标识(lvs_id)。在一个网络内,它应该是唯一的。

3、花括号“{}”。用来分隔定义块,因此必须成对出现。如果写漏了,keepalived运行时,不会得到预期的结果。由于定义块内存在嵌套关系,因此很容易遗漏结尾处的花括号,这点要特别注意。

VRRP定义块

1、同步vrrp组vrrp_sync_group。作用:确定失败切换(FailOver)包含的路由实例个数。即在有2个负载均衡器的场景,一旦某个负载均衡器失效,需要自动切换到另外一个负载均衡器的实例是哪些?
2、实例组group。至少包含一个vrrp实例。
3、Vrrp实例vrrp_instance。实例名出自实例组group所包含的那些名字。

(1)实例状态state。只有MASTER和BACKUP两种状态,并且需要大写这些单词。其中MASTER为工作状态,BACKUP为备用状态。当 MASTER所在的服务器失效时,BACKUP所在的系统会自动把它的状态有BACKUP变换成MASTER;当失效的MASTER所在的系统恢复 时,BACKUP从MASTER恢复到BACKUP状态。

(2)通信接口interface。对外提供服务的网络接口,如eth0,eth1.当前主流的服务器都有2个或2个以上的接口,在选择服务接口时,一定要核实清楚。

(3)lvs_sync_daemon_inteface。负载均衡器之间的监控接口,类似于HA HeartBeat的心跳线。但它的机制优于Heartbeat,因为它没有“裂脑”这个问题,它是以优先级这个机制来规避这个麻烦的。在DR模式 中,lvs_sync_daemon_inteface 与服务接口interface 使用同一个网络接口。

(4)虚拟路由标识virtual_router_id。这个标识是一个数字,并且同一个vrrp实例使用唯一的标识。即同一个vrrp_stance,MASTER和BACKUP的virtual_router_id是一致的,同时在整个vrrp内是唯一的。

(5)优先级priority。这是一个数字,数值愈大,优先级越高。在同一个vrrp_instance里,MASTER 的优先级高于BACKUP。若MASTER的priority值为150,那么BACKUP的priority只能是140或更小的数值。

(6)同步通知间隔advert_int。MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位为秒。

(7)验证authentication。包含验证类型和验证密码。类型主要有PASS、AH两种,通常使用的类型为PASS,据说AH使用时有问题。验证密码为明文,同一vrrp实例MASTER与BACKUP 使用相同的密码才能正常通信。

4、 虚拟ip地址virtual_ipaddress。可以有多个地址,每个地址占一行,不需要指定子网掩码。注意:这个ip必须与我们在lvs客户端设定的vip相一致!

虚拟服务器virtual_server定义块

虚拟服务器定义是keepalived框架最重要的项目了,是keepalived.conf必不可少的部分。

1、虚拟服务器virtual_server。这个ip来自于vrrp定义块的第“4”步,后面一个空格,然后加上端口号。定义一个vip,可以实现多个tcp端口的负载均衡功能。

(1)delay_loop。健康检查时间间隔,单位是秒。

(2)lb_algo。负载均衡调度算法,互联网应用常使用wlc或rr。

(3)lb_kind。负载均衡转发规则。一般包括DR、NAT、TUN3种,在我的方案中,都使用DR的方式。

(4)persistence_timeout。会话保持时间,单位是秒。这个选项对动态网站很有用处:当用户从远程用帐号进行登陆网站时,有了这个会话 保持功能,就能把用户的请求转发给同一个应用服务器。在这里,我们来做一个假设,假定现在有一个lvs 环境,使用DR转发模式,真实服务器有3个,负载均衡器不启用会话保持功能。当用户第一次访问的时候,他的访问请求被负载均衡器转给某个真实服务器,这样 他看到一个登陆页面,第一次访问完毕;接着他在登陆框填写用户名和密码,然后提交;这时候,问题就可能出现了—登陆不能成功。因为没有会话保持,负载 均衡器可能会把第2次的请求转发到其他的服务器。

(5)转发协议protocol。一般有tcp和udp两种。实话说,我还没尝试过udp协议类的转发。

2、真实服务器real_server,也即服务器池。Real_server的值包括ip地址和端口号,多个连续的真实ip。

(1)权重weight,权重值是一个数字,数值越大,权重越高。使用不同的权重值的目的在于为不同性能的机器分配不同的负载,性能较好的机器,负载分担大些;反之,性能差的机器,则分担较少的负载,这样就可以合理的利用不同性能的机器资源。
(2)Tcp检查tcp_check。

4.在2台web机上设置VIP

在192.168.207.129和192.168.207.130上做

vi /root/VIP.sh

 

#!/bin/bash  
SNS_VIP=192.168.207.140  
. /etc/rc.d/init.d/functions  
case "$1" in  
start)  
       ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP  
       /sbin/route add -host $SNS_VIP dev lo:0  
       echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore  
       echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce  
       echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore  
       echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce  
       sysctl -p >/dev/null 2>&1  
       echo "RealServer Start OK"   
       ;;  
stop)  
       ifconfig lo:0 down  
       route del $SNS_VIP >/dev/null 2>&1  
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore  
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce  
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore  
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce  
       echo "RealServer Stoped"  
       ;;  
*)  
       echo "Usage: $0 {start|stop}"  
       exit 1  
esac  
exit 0

为什么要做这一步,我思考了一下,因为在这里lvs只做分发数据包使用,不像haproxy工作在七层,所以lvs必须知道要把数据包分发到哪些后台机器上,做了这步后,通过数据链路层的组播功能,直接把包按照lvs的算法分发到后台服务器上。 在两天机器上风别运行这个脚本

bash VIP.sh start

查看VIP

ifconfig

可以看到多了一条记录,这就是VIP

lo:0      Link encap:Local Loopback  
          inet addr:192.168.207.140  Mask:255.255.255.255
          UP LOOPBACK RUNNING  MTU:16436  Metric:1

 

5.启动keepalived

在192.168.207.130和192.168.207.131操作

/etc/init.d/keepalived start

在主keepalived上运行

ip addr

会看到

 eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:ed:4c:08 brd ff:ff:ff:ff:ff:ff
    inet 192.168.207.130/24 brd 192.168.207.255 scope global eth0
    <span style="color:#FF0000;">inet 192.168.207.140/32 scope global eth0</span>
    inet6 fe80::20c:29ff:feed:4c08/64 scope link 
       valid_lft forever preferred_lft forever

这个是keepalived自动在eth0添加了个VIP,这个是根据配置文件

virtual_ipaddress {
        192.168.207.140
    }

来定义的,不过呢只有主keepalived的服务器上才会这么做,从keepalived服务器不会设置VIP的,除非从服务器转成了主服务器。

在浏览器查看http://192.168.207.140来查看lvs的调度后台的web服务器的数据

在主keepalived服务器上运行

watch ipvsadm -ln

来查看lvs的调度情况

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.207.140:80 wrr
  -> 192.168.207.130:80           Local   3      0          7
  -> 192.168.207.129:80           Route   3      0          8

 

6.模拟主服务器down掉

只要把主keepalived关掉就好了

可以看到从keepalived的/var/log/messages日志

Apr 18 16:00:29 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Transition to MASTER STATE
Apr 18 16:00:30 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Entering MASTER STATE
Apr 18 16:00:30 localhost Keepalived_vrrp: VRRP_Instance(VI_1) setting protocol VIPs.
Apr 18 16:00:30 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.207.140
Apr 18 16:00:30 localhost Keepalived_vrrp: Netlink reflector reports IP 192.168.207.140 added
Apr 18 16:00:30 localhost Keepalived_healthcheckers: Netlink reflector reports IP 192.168.207.140 added
Apr 18 16:00:30 localhost avahi-daemon[4204]: Registering new address record for 192.168.207.140 on eth0.

立即变成了keepalived,访问url还是依旧正常

 

在把原主keepalived服务打开,可以在原从keepalived看到日志

Apr 18 16:03:17 localhost Keepalived_vrrp: VRRP_Instance(VI_1) <span style="color:#FF0000;">Received higher prio advert</span>
Apr 18 16:03:17 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Entering BACKUP STATE
Apr 18 16:03:17 localhost Keepalived_vrrp: VRRP_Instance(VI_1) removing protocol VIPs.
Apr 18 16:03:17 localhost Keepalived_vrrp: Netlink reflector reports IP 192.168.207.140 removed
Apr 18 16:03:17 localhost Keepalived_healthcheckers: Netlink reflector reports IP 192.168.207.140 removed
Apr 18 16:03:17 localhost avahi-daemon[4204]: Withdrawing address record for 192.168.207.140 on eth0.

 

Haproxy+KeepAlived 负载均衡

Haproxy+KeepAlived 负载均衡

软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现。LVS就是基于Linux操作系统实现的一种软负载,HAProxy就是开源的并且基于第三应用实现的软负载。还可以使用nginx来实现,不过nginx只工作在7层网络之上

HAProxy相比LVS的使用要简单很多,功能方面也很丰富。当 前,HAProxy支持两种主要的代理模式:”tcp”也即4层(大多用于邮件服务器、内部协议通信服务器等),和7层(HTTP)。在4层模式 下,HAProxy仅在客户端和服务器之间转发双向流量。7层模式下,HAProxy会分析协议,并且能通过允许、拒绝、交换、增加、修改或者删除请求 (request)或者回应(response)里指定内容来控制协议,这种操作要基于特定规则。

我现在用HAProxy主要在于它有以下优点,这里我总结下:

一、免费开源,稳定性也是非常好,这个可通过我做的一些小项目可以看出来,单Haproxy也跑得不错,稳定性可以与LVS相媲美;

二、根据官方文档,HAProxy可以跑满10Gbps-New benchmark of HAProxy at 10 Gbps using Myricom’s 10GbE NICs (Myri-10G PCI-Express),这个作为软件级负载均衡,也是比较惊人的;

三、HAProxy可以作为MySQL、邮件或其它的非web的负载均衡,我们常用于它作为MySQL(读)负载均衡;

自带强大的监控服务器状态的页面,实际环境中我们结合Nagios进行邮件或短信报警,这个也是我非常喜欢它的原因之一;

HAProxy支持虚拟主机。

1.实验环境

系统版本:CentOS release 5.9 (Final) x86 32位
HAProxy版本:1.4.8
Keepalived版本:1.2.4

MASTER_IP:192.168.207.130  
BACKUP_IP:192.168.207.131 

VIP:192.168.207.141  
WEB_1:192.168.207.129 80端口  
WEB_2:192.168.207.130 8080端口
WEB_3:192.168.207.131 8080端口

 2.Haproxy安装

cd /usr/local/src
mkdir haproxy
cd haproxy
wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.8.tar.gz
tar xf haproxy-1.4.8.tar.gz
cd haproxy-1.4.8
make TARGET=linux26;make install
#这里你也可以这样写make TARGET=linux26 --prefix=/usr/local/haproxy,给haproxy安装添加个路径

写haproxy的配置文件,主从都一样的,都用这个配置文件

useradd haproxy
vi /etc/haproxy.cfg

 

global
            log 127.0.0.1   local0       #这个是日志
            maxconn 65535  
            user haproxy
            group haproxy
            daemon                      #以后台进程的方式打开
            nbproc 8                    #haproxy的进程数
            pidfile /tmp/haproxy.pid

defaults
             log     127.0.0.1       local3
             mode   http
             option httplog
             option httpclose
             option dontlognull
             option forwardfor
             option redispatch
             retries 2
             maxconn 65535
             balance roundrobin                         #为了更好的观察出结果,这里就用roundrobin简单轮训,source算法了
             stats   uri     /web-status                #这个是管理的url地址,配好后,只要输入http://ip或者VIP/web-status就可以访问了
             contimeout      5000
             clitimeout      50000
             srvtimeout      50000

listen  web_vip 0.0.0.0:80              #这里也要注意千万不要绑定VIP地址,keepalived主服务器还可以,但是备份服务器是不行的,因为只有keepalived是主的时候,才会在此服务器上设定VIP,所以咯,就用0.0.0.0吧
            mode http
            option httplog
            log global
            option httpchk HEAD /index.html HTTP/1.0        #这里呢,你得在三台web服务器上分别建立个index.html页面,可以添加不同的内容,给待会测试用,内容分别填写129:80,130:8080,131:8080好了,如果没有,haproxy会认为对应的web服务器挂掉了。
            server web1  192.168.207.129:80   weight 5  check inter 2000 rise 2 fall 3
            server web2  192.168.207.130:8080 weight 5  check inter 2000 rise 2 fall 3
            server web3  192.168.207.131:8080 weight 5  check inter 2000 rise 2 fall 3

这个说一下啊,如果不懂haproxy的配置参数呢,可以到http://cbonte.github.io/haproxy-dconv/configuration-1.4.html这里

搜索一下关键词,就有解释了,挺方便的,不过是英文,嗯,你自己看着办吧

这里还说一下啊,HAProxy的算法现在也越来越多了,具体有如下8种:
①roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;
②static-rr,表示根据权重,建议关注;
③leastconn,表示最少连接者先处理,建议关注;
④source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注;
⑤ri,表示根据请求的URI;
⑥rl_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name;
⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

在web服务器都打开的情况下,运行

haproxy -f /etc/haproxy.cfg

这是后已经是个haproxy+3个web的负载均衡模式了

可以再浏览器上输入http://haproxy_ip地址 来感受一下haproxy的运行方式

在url加上/web-status就可以访问管理界面了

3.安装keepalived

wget http://www.keepalived.org/software/keepalived-1.2.4.tar.gz
tar -zxvf keepalived-1.2.4.tar.gz
cd keepalived-1.2.4
./configure --prefix=/usr/local/keepalived
make && make install

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/keepalived
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
mkdir -p /etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf 
chmod +x /etc/init.d/keepalived

写keepalived的配置文件

vi /etc/keepalived/keepalived.conf

 

# Configuration File for keepalived  

global_defs {
   router_id LVS_DEVEL
}

vrrp_script chk_http_port {
     script "/etc/keepalived/checkHaproxy.sh"
     interval 2
     weight 2
}

vrrp_instance VI_1 {
    state MASTER                #从keepalived这里改成BACKUP
    interface eth0
    virtual_router_id 51
    priority 104                #从keepalived这里改成100吧,只要从比主小就行,数字是从0~255,数字越大权重越大
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        chk_http_port
    }
    virtual_ipaddress {
        192.168.207.141
    }
}

几个注意点:

1. /etc/keepalived/checkHaproxy.sh 一定要加上可执行权限,例如chmod +x /etc/keepalived/checkHaproxy.sh

2. 配置文件写正规些吧,大括号{},要与前面的关键字留有一个空格

写/etc/keepalived/checkHaproxy.sh脚本,如下:

#!/bin/bash
A=`ps -C haproxy --no-header | wc -l`
if [ $A -eq 0 ];then
        /usr/local/sbin/haproxy -f /etc/haproxy.cfg
        echo "Haproxy start"
        sleep 3
        if [ `ps -C haproxy --no-header | wc -l` -eq 0 ];then
                /etc/init.d/keepalived stop
                echo "keepalived stop"
        fi
fi

意思就是先检查haproxy是否启动,如果没有先启动haproxy进程,启动不了则关闭keepalived进程,那边从keepalived,将立马编程主进程,继续工作

这个脚本可以自己写啦,还是挺简单的

4.打开服务,验证

其实就是把3个web服务打开

让后在打开两个主从keepalived服务器,而且keepalived会自动打开haproxy服务的,因为有/etc/keepalived/checkHaproxy.sh吗,哈哈
都打开后,访问http://192.168.207.141就可以轮回访问3个web服务器的内容啦

所以服务打开后,可以在主keepalived上运行

ip addr

将会看到eth0多了个VIP的虚拟地址

为了了解keepalived的作用呢

先把主服务器的keepalived给关掉

/etc/init.d/keepalived stop

查看从keepalived的/var/log/messages日志,可以看到

Apr 18 12:20:23 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Transition to MASTER STATE
Apr 18 12:20:24 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Entering MASTER STATE
Apr 18 12:20:24 localhost Keepalived_vrrp: VRRP_Instance(VI_1) setting protocol VIPs.
Apr 18 12:20:24 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.207.141
Apr 18 12:20:24 localhost Keepalived_vrrp: Netlink reflector reports IP 192.168.207.141 added
Apr 18 12:20:24 localhost Keepalived_healthcheckers: Netlink reflector reports IP 192.168.207.141 added
Apr 18 12:20:24 localhost avahi-daemon[4208]: Registering new address record for 192.168.207.141 on eth0.

是的吧,访问http://192.168.207.141呢,还是正常访问,

在把主keepalived服务打开,就可以看到

Apr 18 12:20:29 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.207.141
Apr 18 12:21:07 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Received higher prio advert
Apr 18 12:21:07 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Entering BACKUP STATE
Apr 18 12:21:07 localhost Keepalived_vrrp: VRRP_Instance(VI_1) removing protocol VIPs.
Apr 18 12:21:07 localhost Keepalived_vrrp: Netlink reflector reports IP 192.168.207.141 removed
Apr 18 12:21:07 localhost Keepalived_healthcheckers: Netlink reflector reports IP 192.168.207.141 removed
Apr 18 12:21:07 localhost avahi-daemon[4208]: Withdrawing address record for 192.168.207.141 on eth0.

 

这里附上haproxy管理页面的图片,以及一个小实验

访问http://192.168.207.141/web-status,可以看到如下画面

1366264404_4798

可以看到后端的3个web服务器都是好的,

这时候呢,我把web3的web服务给关了,因为我用的是apache,所以直接运行service httpd stop

然后可以看到

1366264552_7928

明白了,然后访问http://192.168.207.141也不会出现web的index.html页面了

ok,搞定了,实践亲测,祝君成功

 

 

nginx+keepalived 高可用负载均衡

nginx+keepalived 高可用负载均衡

系统环境

主keepalived:192.168.207.130  

从keepalived:192.168.207.131  

VIP:192.168.207.140   
WEB_1:192.168.207.129 80端口   
WEB_2:192.168.207.130 8080端口   
WEB_3:192.168.207.131 8080端口

自定义nginx配置文件

在192.168.207.130和192.168.207.131上操作

useradd nginx  
vi /usr/local/nginx/conf/nginx.conf

内容如下:

#运行用户    
user nginx nginx;    
#启动进程    
worker_processes 2;    
#全局错误日志及PID文件    
error_log logs/error.log notice;    
pid logs/nginx.pid;    
#工作模式及每个进程连接数上限    
events {    
    use epoll;    
    worker_connections 1024;     #所以nginx支持的总连接数就等于worker_processes * worker_connections  
}    
#设定http服务器,利用它的反向代理功能提供负载均衡支持    
http {    
    #设定mime类型    
    include mime.types;  #这个是说nginx支持哪些多媒体类型,可以到conf/mime.types查看支持哪些多媒体  
    default_type application/octet-stream;   #默认的数据类型   
    #设定日志格式    

    log_format main '$remote_addr - $remote_user [$time_local] '   
    '"$request" $status $bytes_sent '   
    '"$http_referer" "$http_user_agent" '   
    '"$gzip_ratio"';    

    log_format download '$remote_addr - $remote_user [$time_local] '   
    '"$request" $status $bytes_sent '   
    '"$http_referer" "$http_user_agent" '   
    '"$http_range" "$sent_http_content_range"';    
    #设定请求缓冲    
    client_header_buffer_size 1k;    
    large_client_header_buffers 4 4k;    
    #开启gzip模块    
    #gzip on;    
    #gzip_min_length 1100;    
    #gzip_buffers 4 8k;    
    #gzip_types text/plain;    
    #output_buffers 1 32k;    
    #postpone_output 1460;    
    #设定access log    
    access_log logs/access.log main;    
    client_header_timeout 3m;    
    client_body_timeout 3m;    
    send_timeout 3m;    
    sendfile on;    
    tcp_nopush on;    
    tcp_nodelay on;    
    keepalive_timeout 65;    
    #设定负载均衡的服务器列表    

    upstream mysvr {    
        #weigth参数表示权值,权值越高被分配到的几率越大   
        server 192.168.207.129:80 weight=5;    
        server 192.168.207.130:8080 weight=5;    
        server 192.168.207.131:8080 weight=5;  
    }    
    server { #这个是设置web服务的,监听8080端口  
        listen        8080;  
        server_name    192.168.207.131;          #这个根据系统ip变化
        index     index.html index.htm;  
        root        /var/www/html;  
        #error_page     500 502 503 504    /50x.html;  
        #location = /50x.html {  
        #    root     html;  
        #}  
        }   
    #设定虚拟主机    
    server {    
        listen 80;    
        server_name 192.168.207.140;                   #这里是VIP
        #charset gb2312;    
        #设定本虚拟主机的访问日志    
        access_log logs/three.web.access.log main;    
        #如果访问 /img/*, /js/*, /css/* 资源,则直接取本地文件,不通过squid    
        #如果这些文件较多,不推荐这种方式,因为通过squid的缓存效果更好    
        #location ~ ^/(img|js|css)/{    
        #   root /data3/Html;    
        #   expires 24h;  
        #}   
            #对 "/" 启用负载均衡    
        location / {    
            proxy_pass http://mysvr;  #以这种格式来使用后端的web服务器  
            proxy_redirect off;    
            proxy_set_header Host $host;    
            proxy_set_header X-Real-IP $remote_addr;    
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
            client_max_body_size 10m;    
            client_body_buffer_size 128k;    
            proxy_connect_timeout 90;    
            proxy_send_timeout 90;    
            proxy_read_timeout 90;    
            proxy_buffer_size 4k;    
            proxy_buffers 4 32k;    
            proxy_busy_buffers_size 64k;    
            proxy_temp_file_write_size 64k;  
        }    
        #设定查看Nginx状态的地址 ,在安装时要加上--with-http_stub_status_module参数  
        location /NginxStatus {    
            stub_status on;    
            access_log on;    
            auth_basic "NginxStatus";    
            auth_basic_user_file conf/htpasswd;     #设置访问密码,htpasswd -bc filename username password  
        }  
    }  
}

 自定义keepalived配置文件

 

vi /etc/keepalived/keepalived.conf

 

global_defs {
   notification_email {
        root@localhost.localdomain
   }
   notification_email_from notify@keepalived.com
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_script chk_http_port {
                script "/etc/keepalived/check_nginx.sh"         ###监控脚本
                interval 2                             ###监控时间
                weight 2                                ###目前搞不清楚
}
vrrp_instance VI_1 {
        state MASTER                            ### 设置为 主
        interface eth0                             ### 监控网卡
        virtual_router_id 51                    ### 这个两台服务器必须一样
        priority 101                                 ### 权重值 MASTRE 一定要高于 BAUCKUP
        authentication {
                     auth_type PASS
                     auth_pass 1111
        }
        track_script {
                chk_http_port                     ### 执行监控的服务
        }
        virtual_ipaddress {
             192.168.207.140                            ###    VIP 地址
        }
}

 写自定义脚本

 

vi /etc/keepalived/check_nginx.sh

 

!/bin/bash
A=`ps -C nginx --no-header |wc -l`                ## 查看是否有 nginx进程 把值赋给变量A
if [ $A -eq 0 ];then                                         ## 如果没有进程值得为 零
        /usr/local/nginx/sbin/nginx
        sleep 3
        if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
                  /etc/init.d/keepalived stop                       ## 则结束 keepalived 进程
        fi
fi

这里是检查nginx是否启动好,如果没有启动,先启动 nginx,隔了3秒后还没有启动好,则将keepalived进程也关闭,这样从keepalived就能接手过去了,提供高可用性,在这里 呢,keepalived服务是提供高可用性,而nginx是提供后端web服务器的负载均衡。

这里还要给脚本加上执行权限,如下

chmod +x /etc/keepalived/check_nginx.sh

 

5.启动服务,并测试

在这里先说一下啊,在WEB_1上,我是使用系统自带的apache昨晚web服务器的,比较省事,这样呢,我只要启动好主从keepalived就ok了,因为它会利用check_nginx.sh脚本来自动启动nginx。

都启动好了。

访问http://192.168.207.140就可以轮训访问后端的三台web服务器内容啦

这里我们把主keepalived服务给关掉,来测试高可用性

然后会在从keepalived服务器上的/var/log/messages看到这样的日志

Apr 19 17:42:44 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Transition to MASTER STATE
Apr 19 17:42:45 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Entering MASTER STATE
Apr 19 17:42:45 localhost Keepalived_vrrp: VRRP_Instance(VI_1) setting protocol VIPs.
Apr 19 17:42:45 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.207.140
Apr 19 17:42:45 localhost Keepalived_vrrp: Netlink reflector reports IP 192.168.207.140 added
Apr 19 17:42:45 localhost Keepalived_healthcheckers: Netlink reflector reports IP 192.168.207.140 added
Apr 19 17:42:45 localhost avahi-daemon[4204]: Registering new address record for 192.168.207.140 on eth0.

继续访问http://192.168.207.140,依旧可以访问后端的三台web服务器

然后再把原主keepalived打开,可以观察到原从keepalived服务器的日志显示

Apr 19 17:42:50 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.207.140
Apr 19 17:44:06 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Received higher prio advert
Apr 19 17:44:06 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Entering BACKUP STATE
Apr 19 17:44:06 localhost Keepalived_vrrp: VRRP_Instance(VI_1) removing protocol VIPs.
Apr 19 17:44:06 localhost Keepalived_vrrp: Netlink reflector reports IP 192.168.207.140 removed
Apr 19 17:44:06 localhost Keepalived_healthcheckers: Netlink reflector reports IP 192.168.207.140 removed
Apr 19 17:44:06 localhost avahi-daemon[4204]: Withdrawing address record for 192.168.207.140 on eth0.

说明有恢复了原来的主从结果。

生产环境中,后端的机器也可能会挂掉,但是呢,这就不用你操心啦,nginx会自动把session分配到好的后端web服务器上的啦

ok,到这里全部结束了,实践亲测,祝君成功

软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比

软件级负载均衡器(LVS/HAProxy/Nginx)的特点简介和对比

现在网站发展的趋势对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术:
一种是通过硬件来进行进行,常见的硬件有比较昂贵的NetScaler、F5、Radware和Array等商用的负载均衡器,它的优点就是有专业的维护 团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小的网络服务来说暂时还没有需要使用;另外一种就是类似于LVS/HAProxy、 Nginx的基于Linux的开源免费的负载均衡软件策略,这些都是通过软件级别来实现,所以费用非常低廉,所以我个也比较推荐大家采用第二种方案来实施 自己网站的负载均衡需求。

近期朋友刘鑫(紫雨荷雪)的项目成功上线了,PV达到了亿级/日的访问量,最前端用的 是HAProxy+Keepalived双机作的负载均衡器/反向代理,整个网站非常稳定;这让我更坚定了以前跟老男孩前辈聊的关于网站架构比较合理设计 的架构方案:即Nginx/HAProxy+Keepalived作Web最前端的负载均衡器,后端的MySQL数据库架构采用一主多从,读写分离的方 式,采用LVS+Keepalived的方式。

在这里我也有一点要跟大家申明下:很多朋友担心软件级别的负载均衡在高并发流量冲击下的稳定情况,事实是我们通过成功上线的许多网站发现,它们的稳定性也 是非常好的,宕机的可能性微乎其微,所以我现在做的项目,基本上没考虑服务级别的高可用了。相信大家对这些软件级别的负载均衡软件都已经有了很深的的认 识,下面我就它们的特点和适用场合分别说明下。

LVS:使用集群技术和Linux操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability),感谢章文嵩博士为我们提供如此强大实用的开源软件。

LVS的特点是:

1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;
2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;
3、工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived;
4、无流量,保证了均衡器IO的性能不会收到大流量的影响;
5、应用范围比较广,可以对所有应用做负载均衡;
6、软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。
7、如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。

Nginx的特点是:

1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;
2、Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;
3、Nginx安装和配置比较简单,测试起来比较方便;
4、也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;
5、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;
6、Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势;
7、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。
8、Nginx现在作为Web反向加速缓存越来越成熟了,很多朋友都已在生产环境下投入生产了,而且反映效果不错,速度比传统的Squid服务器更快,有兴趣的朋友可以考虑用其作为反向代理加速器。

HAProxy的特点是:

1、HAProxy是支持虚拟主机的,以前有朋友说这个不支持虚拟主机,我这里特此更正一下。
2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3、支持url检测后端的服务器出问题的检测会有很好的帮助。
4、它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。
5、HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。
6、HAProxy的算法现在也越来越多了,具体有如下8种:
①roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;
②static-rr,表示根据权重,建议关注;
③leastconn,表示最少连接者先处理,建议关注;
④source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注;
⑤ri,表示根据请求的URI;
⑥rl_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name;
⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。