首先对比一下LVS/Nginx/HAProxy特点

名称特点
LVS1) 抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;
2) 配置性比较低,所以并不需要太多接触,是缺点也是优点,可大大减少了人为出错的几率;
3) 工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived;
4) 无流量,保证了均衡器IO的性能不会收到大流量的影响;
5) 应用范围比较广,可以对所有应用做负载均衡;
6) 本身不支持正则处理,不能做动静分离;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。
7) 如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了。
Nginx1) 工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;
2) Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;
3) Nginx安装和配置比较简单,测试起来比较方便;
4) 也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;
5) Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;
6) Nginx支持http和Email,在适用范围上面小很多;
7) Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,在高流量的环境中也有很好的效果。

8) Nginx还可以作为静态页面的前段缓存使用。

注:nginx1.9版本以后支持TCP的反向代理

Haproxy1) 支持两种代理模式:TCP(四层)和HTTP(七层)HAProxy是支持虚拟主机的。
2) 能够补充Nginx的缺点比如Session的保持,Cookie的引导等工作。
3) 支持url检测后端的服务器出问题的检测会有很好的帮助。

4) 它跟LVS一样,本身仅做负载均衡之用;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。运行在时下的硬件上,完全可以支持数以万计的并发连接。

5) Haproxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS。

6) Haproxy的算法多,算法灵活.

7) 对比Nginx, HAProxy是通过ACL将fronted和backend相关联起来;而Nginx是通过定义的location实现的。

注:Haproxy比较坑的就是配置相当复杂


Haproxy工作原理

  HAProxy是一种高效、可靠、免费的高可用及负载均衡解决方案,非常适合于高负载站点的七层数据请求。客户端通过HAProxy代理服务器获得站点页面,而代理服务器收到客户请求后根据负载均衡的规则将请求数据转发给后端真实服务器。

  HAProxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

两种工作模式:

    TCP mode:四层调度(模拟实现,依赖于socket进行通信)

    HTTP mode:七层调度


主要配置部分:

注:其核心和强大的功能都是基于配置文件中的定义而发挥功用的,所以配置较繁琐。

 global          全局部分      

#下面四项为代理配置区段项

 defaults              #用于为listen、frontend、backend提供默认值。

 frontend (name vip)      #定义监听的套接字,用于接收客户端请求并与之连接,描述了接收客户端请求的监听配置

 backend (name server列表)   #定义接受请求处理的后端服务器组的配置,用于处理frontend转发来的请求    

 listen  <name>          #监听服务端口,或通过关联一组前端和后端直接一对一绑定的组配置 定义一个完整的代理服务器

注:name可使用大小写字母、数字,_/-/./:


准备工作

# vi /etc/selinux/config

SELINUX=disabled    #修改

# setenforce 0     # 临时关闭SeLinux

防火墙开放22/80端口,编辑IPtables文件

-A RH-Firewall-1-INPUT -d 224.0.0.18 -j ACCEPT                                   #允许组播地址通信

-A RH-Firewall-1-INPUT -p    vrrp    -j ACCEPT                                       #允许VRRP(虚拟路由器冗余协)通信

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT       #允许80端口通过防火墙

测试网络连通性


编译安装方法

#cd  haproxy-1.4.24             

#make TARGET=linux26 CPU=x86_64  PREFIX=/usr/local/haprpxy          #编译  TARGET=内核版本

#make install PREFIX=/usr/local/haproxy                             #安装

#cp /usr/src/haproxy-1.4.24/examples/haproxy.init  /etc/init.d/haproxy

#ln -s /usr/local/sbin/haproxy /usr/sbin/haproxy

以下例子为yum安装

haproxy记录日志,默认haproxy是不记录日志的,为了记录日志还需要配置syslog模块,在linux下是rsyslogd服务,

用rsyslog的理由:

1.防止系统崩溃无法获取系统日志分享崩溃原因,用rsyslog可以把日志传输到远程的日志服务器上

2.使用rsyslog日志可以减轻系统压力,因为使用rsyslog可以有效减轻系统的磁盘IO

3.rsyslog使用tcp传输非常可靠,可以对日志进行过滤,提取出有效的日志,rsyslog是轻量级的日志软件,在大量日志写的情况下,系统负载基本上在0.1以下

#yum –y install rsyslog                    #先安装rsyslog

#cd /etc/rsyslog.d/ && touch haproxy.conf

#vim /etc/rsyslog.conf

$ModLoad imudp                      #添加

$UDPServerRun 514                  #添加,基于UDP接收日志请求

*.info;mail.none;authpriv.none;cron.none;local2.none;   /var/log/messages   #添加红色部分

local2.*    /var/log/haproxy.log                               #这个必须和haproxy.cfg的配置文件一致。可多个。表示单独记录日志

#vi  /etc/sysconfig/rsyslog                         

SYSLOGD_OPTIONS="-r -m 0"                            #接收远程服务器日志

重启rsyslog服务

系统日志级别;

日志的level: local0~local7

16~23      保留为本地使用
emerg 0     系统不可用
alert 1     必须马上采取行动的事件
crit 2      关键的事件
err 3       错误事件
warning 4    警告事件
notice 5    普通但重要的事件
info 6      有用的信息


HAproxy配置

在master与backup上面同时配置

安装可采用yum直接安装,或下载tar包编译安装。

两台前端HAproxy配置一样

haproxy的配置文件通常分为三部分: global(全局配置部分) defaults(默认配置部分) listen(应用组件部分)

# vim /etc/haproxy/haproxy.cfg

global

#【程序及安全相关的配置参数】

    log         127.0.0.1 local2           #将日志发送到指定的rsyslog服务器,日志级别local2。此处发到本机

    chroot      /var/lib/haproxy             #haproxy工作目录安装目录

    pidfile     /var/run/haproxy.pid

    user        haproxy

    group       haproxy

    daemon                                        #haproxy以守护进程的方式工作于后台

    stats socket /var/lib/haproxy/stats           #统计数据保存位置

#【性能调优相关的参数】绿色的“调优选项”根据情况使用

    maxconn    4000                          ###每个haproxy单进程所接受的最大并发连接数

    nbproc      8                                                         #进程数量,可以设置多个,提高处理效率

  maxpipes                 #haproxy使用pipe机制实现内核级tcp报文重组;此参数用来定义每个haproxy能够使用的最大pipe数量,默认为maxconn/4;

  maxsslconn <number>        #设定单haproxy进程的ssl连接最大并发连接数;
  maxsslrate <number>        #单haproxy进程的ssl连接的创建速率上限;

  noepoll/nokqueue/nopoll/nosepoll     # :禁用事件机制

  nosplice                 #禁用内核级tcp报文重组功能

  spread-checks <0-50>         #分散健康状态检测时间,数值为百分比;避免对于后端检测同时并发造成的问题,设置错开时间比,范围0到50,一般设置2-5较好。.


#【Debug】

  debug/quite


defaults 

#绿色的根据情况选择

    mode                    http                  #默认的模式mode #指定frontend和backend工作模式{ tcp|http|health },tcp是4层,http是7层,health只会返回OK

#tcp:基于layer4实现代理,可代理大多数基于tcp的应用层协议,例如ssh/mysql/pgsql等;
#http:客户端的http请求会被深度解析;
#health:工作为健康状态检查响应模式,当请求到达时仅回应“OK”即断开连接;

    log                     global              #日志使用全局中定义的日志参数

    option                  httplog             #启用http的log,启用对http请求会话计时捕获到cookie的日志,默认原格式简陋,后面还可跟参数[clf] clf格式

    option                  dontlognull         ##不记录空信息,保证HAProxy不记录上级负载均衡发送过来的用于检测状态没有数据的心跳包。

    option    http-server-close                 #启用http连接在服务器端关闭功能,支持客户端一侧长连接#每次请求完毕后主动关闭http通道

    option    forwardfor     except 127.0.0.0/8     # forwardfor将用户请求转发后端服时,在HTTP请求报文中添加"X-Forwarded-For"特殊首部,以便后端服记录真实发起请求的客户端IP地址,而不是代理服务器内网卡地址。#不记录本机转发的日志

    option                  redispatch           # 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了, 但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。#如果后端有服务器宕机,强制切换到正常服务器

 #   option  http-pretend-keepalive                                #服务器端保持长连接

  #     option  forceclose                                                        #服务端响应后主动关闭请求连接,及早释放服务连接,不必等到客户端应答确认

  #     option  accept-invalid-http-request                          #接受无效的http请求,一般建议不设置,但是可解决部分杂牌浏览器访问打不开页面问题

 #    option  abortonclose                                                 #当Haproxy服务器负载很高的时候,自动结束掉当前队列处理比较久的连接#丢弃由于客户端等待时间过长而关闭连接但仍在haproxy等待队列中的请求

 #    option  originalto                                                    #记录客户端访问的目的IP

    retries                 3                   # 定义连接后端服务器的失败重连次数,三次连接失败,则判断服务不可用

    timeout http-request    10s                  #http请求超时时间

    timeout queue           1m                  #后端有多个服务器,当每个后端服务器都达到最大连接上限,haproxy等待发送到对应后端服务器的队列已满或请求已入列但未处理的超时时间1分种#一个请求在队列里的超时时间

    timeout connect         10s                   #haproxy向后端服务器请求建立连接的超时时间

    timeout client          1m                    #发起连接请求的前端客户端连接处于非活动态的最大超时时间,过时断开,默认单位是ms;最好与timeout server一致。。相当于Apache的timeout keepalive

    timeout server          1m                    #服务器端连接处于非活动态的最大超时时间,默认单位是ms;

    timeout http-keep-alive 10s                   #长连接超时时间,设定最大等待新请求的空闲时长,默认单位为ms;

    timeout check           10s                   #做健康状态检测的超时时间#检测超时时间

  timeout client-fin <timeout>           #在客户端侧设定半关闭连接非活动超时
  timeout server-fin <timeout>           #在服务端侧设定半关闭连接非活动超时Example:


listen stats *:11111

#stats:haproxy数据统计页面相关的配置

    stats enable                      #开启stats统计页面

      stats  uri   /stats                            #haproxy 状态页面

   stats realm "Haproxy Auth"              #开启认证功能

      stats auth   admin:admin                      #haproxy登陆验证的用户名密码

   stats admin if TRUE                  #在指定条件下开启admin功能

      stats   refresh    30s                                           #统计页面自动刷新时间间隔

      stats    hide-version                                               #隐藏统计页面上HAProxy版本信息

      stats show-desc demo                                         //统计页面显示的相关描述信息


frontend  proxy *:80                    #监听任意地址80端口,或者在下一行使用bind  <IP>:<port>--(BIND 仅在frontend和listen区域使用。)

    acl url_static       path_beg       -i /static /p_w_picpaths /javascript /stylesheets   #path_begin路径以XX开头,-i忽略大小写

    acl url_static       path_end       -i .jpg .gif .png .css .js .html        #定义静态访问规则#path_end路径以XX结尾,同名acl逻辑或关系

    acl dynamic_content  path_end      -i .php        #定义动态访问规则

    use_backend static          if url_static         #满足ACL url_static 使用backend static。

    default_backend             dynamic               #当use_backend 的使用规则没有被匹配时,由default_backend 指定默认服务器组;

#注:以上定义--在没有匹配到静态页面 static,则判定为动态请求,交给dynamic


#调度算法动静区别在于调整配置文件haproxy.cfg,动态调整reload生效,静态调整restart生效

#轮调平均分配访问到后端服,访问动态页面需要保持会话因此source consistent源地址一致性hash算法把来自于同一客户端请求始终转发于同一台后端服


backend static                       #定义一个使用static方法的后端服务器组

    balance     roundrobin                         #指定调度算法详细介绍见《Haproxy支持的调度算法

  option httpchk <method> <uri> <version>    #基于http协议作7层健康状态检测机制,默认是基于tcp层进行检测;返回状态码2XX,3XX意味成功;示例: option httpchk OPTIONS /index.html HTTP/1.1\r\nHost:\ www

    server     web01 10.10.10.11:80  check inter 2000 fall 3 weight 30      #后端静态web主机

    server     web02 10.10.10.12:80  check inter 2000 fall 3 weight 30      #每隔2000ms检查服务器80端口状态,连续失败次数最多3次,权重30

cookie,详细介绍见Haproxy的三种保持客户端会话保持方式

check:对当前server进行健康状态检测:

     inter  2000     心跳检测间隔时间;

     rise 3     三次连接成功,判定为“健康”状态;

     fall  3     三次连接失败,判定为“不健康”状态;

     addr <ipv4|ipv6>  port < port >    健康状态检测时使用的IP和端口;

weight 100   权重设置。

maxconn <maxconn>:当前server的最大并发连接数;

maxqueue <maxqueue>:当前server的等待队列的最大长度;

disabled:将主机标记为不可用;

redir <prefix>:将发往当前server的所有请求GET和HEAD类的请求均重定向至指定的URL;


#注意:默认为传输层检测,即探测端口是否能响应;需要执行应用层检测,则需要httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk;


backend dynamic                     #定义一个使用dynamic方法的后端服务器组

    balance     roundrobin                         #指定调度算法 ,hash-type决定动态静态加hash-type consistent 

    server     web03 10.10.10.13:80  check inter 2000 fall 3 weight 30     #后端动态web主机

    server     web04 10.10.10.14:80  check inter 2000 fall 3 weight 30

   server   first 10.1.1.1:1080 id 3 cookie first check inter 1000 maxconn 10000 maxqueue 2000


在web1,web2服务器配置中日志格式添加"X-Forwarded-For"特殊首部,以便后端服务器记录真实发起请求的客户端IP地址

验证静态页面的负载均衡,(动态页面长连接保持于同一后端服务器),动静分离。

Haproxy反代日志会详细显示前端客户端IP,Haproxy反代IP,根据动静分离ACL选择不同后端服务器,GET到不同页面。后端upstream服务器别名


可选配置:

 日志记录

为frontend或backend定义日志记录机制;

    log global  :使用全局定义的日志记录方式
    log <address> [len <length>] <facility> [<level> [<minlevel>]]:自定义
    no log :不记录
    capture request header <name> len <length>
    -->记录请求报文中的指定的首部的值于日志中;len用于指定要记录的信息的长度;
    capture response header <name> len <length>
    -->记录响应报文中的指定的首部的值于日志中;len用于指定要记录的信息的长度;
  示例:

     capture request header Referer len 30

  自定义错误页面

- errorfile <code> <file>

    < code > 指定HTTP返回的状态码。200, 400, 403, 408, 500, 502, 503, 504 可使用;
    < file > 指定一个文件代替HTTP响应; 
  示例:

    errorfile 503 /etc/haproxy/errorfiles/503sorry.http

    

- errorloc <code> <url>- errorloc302 <code> <url>

    发生错误时由haproxy重定向至指定url,以上两个命令等同,响应状态码为302
  示例:

    errorloc 503 http://www.mydomain.com/index...

- errorloc303 <code> <url>

    响应状态码为303,表示以GET方法重新请求页面


  修改请求或响应报文首部

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

HAProxy把请求报文发往后端主机之前在请求报文添加“X-Forwared-For”首部
目的为使后端服务器可记录发出请求客户端的IP地址
    [ except < network> ] :选择排除的网络地址
    [ header < name> ] :不使用X-Forwared-For,自定义名称
    [ if-none ]:有时请求原来带有该字段,此时不再更改
  Example:

    option forwardfor if-none

reqadd  <string> [{if | unless} <cond>]
rspadd <string> [{if | unless} <cond>]

在HTTP请求或响应首部内容尾部添加值Example:rspadd X-Via: HAProxy/1.5

reqdel  <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>]  (不区分大小写)        

删除HTTP请求中正则匹配的所有首部

rspdel  <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>]  (不区分大小写)

删除HTTP响应中正则匹配的所有首部。属于安全加强策略,删除一些服务器版本信息,防止针对***   Example:

    rspidel Server.*


 后端服务器获取真实IP;

.Tomcat 配置日志格式

wKioL1jY7dHyByIMAABwY65-N2k338.png 

 配置server.xml


%{X-ERAL-IP}

I 获取head

s 获取seession

c 获取cookie

 

.nginx 配置日志格式;

(1).修改haproxy配置文件,添加如下参数:

   option httpclose

   option forwardfor

 

(2).修改nginx配置文件,添加如下参数  注意:需要编译模块--with-http_realip_module;

set_real_ip_from    xxx.xx.xxx.xx;     #haproxy服务器IP

real_ip_header    X-Forwarded-For;

real_ip_recursive on;
  

(3).模拟客户端访问,在日志中查看效果;

   


———————————————我是华丽分割线———————————————————

以下为keepalived结合部分


配置文件关键配置项

notify_master "/etc/keepalived/clean_arp.sh  <VIP> <GATEWAY>"          #更新虚拟服务器(VIP)地址的arp记录到网关

vrrp_script check_Haproxy {               #对集群中某服务进行监控。这里为httpd

script “/etc/keepalived/scripts/check_haproxy.sh”  #检测端口的运行状态。判断服务是否正常。(或者“”里加脚本路径)

interval 2                           #检查的时间间隔。2秒

# weight 2   

fall 2                             #若请求失败两次,认为此节点故障

rise 1                             #若请求一次成功,认为此节点恢复正常

}

track_script {

check_Haproxy                         #监测Haproxy进程状态,。为vrrp_script 定义的名

}


配置haproxy的脚本,在/etc/keepalived目录添加目录sripts,存放haproxy的脚本脚本。

下面是clean_arp.sh脚本

#vi  /etc/keepalived/scripts/clean_arp.sh                    

#!/bin/sh

VIP=$1

GATEWAY=$2                               

/sbin/arping -I eth0 -c 5 -s $VIP $GATEWAY &>/dev/null


下面是check_haproxy.sh脚本

vi /etc/keepalived/scripts/check_haproxy.sh

##脚本含义:如果没有haproxy进程存在,若不存就启动haproxy,再检查若还不存停止keepalived。

#!/bin/bash

STARTHAPROXY="/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg"

STOPKEEPALIVED="/etc/init.d/keepalived stop"

LOGFILE="/usr/local/keepalived/var/log/keepalived-haproxy-state.log"

echo "[check_haproxystatus]" >>$LOGFILE

date >>$LOGFILE

A=`ps -C haproxy --no-header |wc -l`     #查看Haproxy命令所执行进程的情况

if [ $A-eq 0 ];then

    echo $STARTHAPROXY>> $LOGFILE

    $STARTHAPROXY >> $LOGFILE  2>&1

    sleep5

fi

if [`ps -C haproxy --no-header |wc-l` -eq 0 ];then

    exit 0

else

    exit 1

fi


/etc/keepalived.conf配置文件去掉#好,启动这些脚本

给脚本的权限:755

# chmod 755 /etc/keepalived/scripts/*


重启keepalived 服务

#Service keepalived restart

测试~~~Ing~~~~   略