vlambda博客
学习文章列表

Haproxy详解以及基于Haproxy的高可用实战

1.Haproxy与Keepalived VRRP 介绍

软件:haproxy---主要是做负载均衡的7层,也可以做4层负载均衡
          apache----也可以做7层负载均衡,但是很麻烦。实际工作中没有人用。
  负载均衡是通过OSI协议对应的
  7层负载均衡:用的7层http协议,
 4层负载均衡:用的是tcp协议加端口号做的负载均衡

------------------------------------------------------------------------------------------------------------------------------
ha-proxy概述
ha-proxy是一款高性能的负载均衡软件。因为其专注于负载均衡这一些事情,因此与nginx比起来在负载均衡这件事情上做更好,更专业。

ha-proxy的特点
ha-proxy 作为目前流行的负载均衡软件,必须有其出色的一面。下面介绍一下ha-proxy相对LVS,Nginx等负载均衡软件的优点

•支持tcp / http 两种协议层的负载均衡,使得其负载均衡功能非常丰富。
•支持8种左右的负载均衡算法,尤其是在http模式时,有许多非常实在的负载均衡算法,适用各种需求。
•性能非常优秀,基于单进程处理模式(和Nginx类似)让其性能卓越。
•拥有一个功能出色的监控页面,实时了解系统的当前状况。
•功能强大的ACL支持,给用户极大的方便。

haproxy算法
 1.roundrobin
 基于权重进行轮询,在服务器的处理时间保持均匀分布时,这是最平衡,最公平的算法.此算法是动态的,这表示其权重可以在运行时进行调整.
 2.static-rr
   基于权重进行轮询,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效.不过,其在后端服务器连接数上没有限制
 3.leastconn
  新的连接请求被派发至具有最少连接数目的后端服务器.

keepalived是什么
    keepalived是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。

keepalived工作原理
    keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。(云服务器不支持VRRP)

虚拟路由冗余协议,可以认为是实现高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。

keepalived主要有三个模块,分别是core、check和vrrp。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。vrrp模块是来实现VRRP协议的。
=========================================================================================
脑裂(裂脑):
      Keepalived的BACKUP主机在收到不MASTER主机报文后就会切换成为master,如果是它们之间的通信线路出现问题,无法接收到彼此的组播通知,但是两个节点实际都处于正常工作状态,这时两个节点均为master强行绑定虚拟IP,导致不可预料的后果,这就是脑裂。
解决方式:
    1、添加更多的检测手段,比如冗余的心跳线(两块网卡做健康监测),ping对方等等。尽量减少"裂脑"发生机会。(指标不治本,只是提高了检测到的概率);
    2、做好对裂脑的监控报警(如邮件及手机短信等或值班).在问题发生时人为第一时间介入仲裁,降低损失。例如,百度的监控报警短信就有上行和下行的区别。报警消息发送到管理员手机上,管理员可以通过手机回复对应数字或简单的字符串操作返回给服务器.让服务器根据指令自动处理相应故障,这样解决故障的时间更短.
   3、爆头,将master停掉。然后检查机器之间的防火墙。网络之间的通信

 

2.项目准备

准备四台虚拟机,两台做代理服务器,两台做真实服务器(真实服务器只是用来进行web测试)

1、选择两台Haproxy服务器作为代理服务器(一台master 一台backup)。

真实服务器需要nginx来提供web服务进行测试

2、给两台代理服务器安装keepalived制作高可用生成VIP

3、配置nginx的负载均衡

以上两台nginx服务器配置文件一致

根据站点分区进行调度

配置upstream文件

[root@master ~]# 192.168.13.128         主节点
[root@backup ~]# 192.168.13.129         备用节点
[root@real-server1 ~]# 192.168.13.133  第一台真实服务器
[root@real-server2 ~]# 192.168.13.137    第二台真实服务器

所有虚拟机
[root@master ~]# cat /etc/hosts
127.0.0.1       localhost
192.168.13.128  master
192.168.13.129  backup
192.168.13.133  real-server1
192.168.13.137  real-server2

3.nginx安装

只给两台真实服务器配置安装nginx ,所有机器关闭防火墙和selinux

192.168.13.133
[root@real-server1 ~]# systemctl stop firewalld && setenforce 0
[root@real-server1 ~]# cd /etc/yum.repos.d/
[root@real-server1 yum.repos.d]# vim nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
[root@real-server1 yum.repos.d]# yum install yum-utils -y
[root@real-server1 yum.repos.d]# yum install nginx -y
[root@real-server1 yum.repos.d]# systemctl start nginx  #启动
[root@real-server1 ~]# echo "this is first real-server" > /usr/share/nginx/html/index.html #方便区分,看出效果
[root@real-server1 ~]# vim /etc/nginx/nginx.conf
    keepalive_timeout  0;           #设置长链接
[root@real-server1 ~]# nginx -s reload

192.168.13.138
[root@real-server2 ~]# systemctl stop firewalld && setenforce 0
[root@real-server2 ~]# cd /etc/yum.repos.d/
[root@real-server2 yum.repos.d]# vim nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
[root@real-server2 yum.repos.d]# yum install yum-utils -y
[root@real-server2 yum.repos.d]# yum install nginx -y
[root@real-server2 yum.repos.d]# systemctl start nginx  #启动
[root@real-server2 ~]# echo "this is second real-server"> /usr/share/nginx/html/index.html
[root@real-server2 ~]# vim /etc/nginx/nginx.conf
    keepalive_timeout  0;#默认keepalive_timeout  65;
[root@real-server2 ~]# nginx -s reload
#修改后端nginx服务器的长连接是为了方便测试

4.调度器配置Haproxy(主/备)都执行

192.168.13.128
[root@ha-proxy-master ~]# yum -y install haproxy
[root@ha-proxy-master ~]# cp -rf /etc/haproxy/haproxy.cfg{,.bak}  #备份
[root@master ~]# sed -i -r '/^[ ]*#/d;/^$/d' /etc/haproxy/haproxy.cfg    #修改配置文件去掉注释,或者你可以直接复制我的代码
[root@ha-proxy-master ~]# vim /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2 info
    pidfile     /var/run/haproxy.pid
    maxconn     4000   #优先级低
    user        haproxy
    group       haproxy
    daemon          #以后台形式运行ha-proxy
    nbproc  1            #工作进程数量  cpu内核是几就写几
defaults
    mode                    http  #工作模式 http ,tcp 是 4 层,http是 7 层  
    log                     global
    retries  3       #健康检查。3次连接失败就认为服务器不可用,主要通过后面的check检查
    option      redispatch  #服务不可用后重定向到其他健康服务器。
    maxconn                 4000  #优先级中
    contimeout              5000  #ha服务器与后端服务器连接超时时间,单位毫秒ms
    clitimeout              50000 #客户端超时
    srvtimeout              50000 #后端服务器超时
listen stats
    bind            *:81
    stats                       enable
    stats uri               /haproxy  #使用浏览器访问 http://192.168.246.169/haproxy,可以看到服务器状态 
    stats auth              yjssjm:123  #用户认证,客户端使用elinks浏览器的时候不生效
frontend  web
    mode                    http 
    bind                            *:80   #监听哪个ip和什么端口
    option                  httplog     #日志类别 http 日志格式
    acl html url_reg  -i  \.html$  #1.访问控制列表名称html。规则要求访问以html结尾的url(可选)
    use_backend httpservers if  html #2.如果满足acl html规则,则推送给后端服务器httpservers
    default_backend    httpservers   #默认使用的服务器组
backend httpservers    #名字要与上面的名字必须一样
    balance     roundrobin  #负载均衡的方式
    server  http1 192.168.13.133:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2
    server  http2 192.168.13.137:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2

192.168.13.129
[root@ha-proxy-master ~]# yum -y install haproxy
[root@ha-proxy-master ~]# cp -rf /etc/haproxy/haproxy.cfg{,.bak}  #备份
[root@master ~]# sed -i -r '/^[ ]*#/d;/^$/d' /etc/haproxy/haproxy.cfg    #修改配置文件去掉注释,或者你可以直接复制我的代码
[root@ha-proxy-master ~]# vim /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2 info
    pidfile     /var/run/haproxy.pid
    maxconn     4000   #优先级低
    user        haproxy
    group       haproxy
    daemon               #以后台形式运行ha-proxy
    nbproc 1            #工作进程数量  cpu内核是几就写几
defaults
    mode                    http  #工作模式 http ,tcp 是 4 层,http是 7 层  
    log                     global
    retries                 3   #健康检查。3次连接失败就认为服务器不可用,主要通过后面的check检查
    option                  redispatch  #服务不可用后重定向到其他健康服务器。
    maxconn                 4000  #优先级中
    contimeout              5000  #ha服务器与后端服务器连接超时时间,单位毫秒ms
    clitimeout              50000 #客户端超时
    srvtimeout              50000 #后端服务器超时
listen stats
    bind            *:81
    stats                       enable
    stats uri               /haproxy  #使用浏览器访问 http://192.168.246.169/haproxy,可以看到服务器状态 
    stats auth              yjssjm:123  #用户认证,客户端使用elinks浏览器的时候不生效
frontend  web
    mode                    http 
    bind                            *:80   #监听哪个ip和什么端口
    option                  httplog     #日志类别 http 日志格式
    acl html url_reg  -i  \.html$  #1.访问控制列表名称html。规则要求访问以html结尾的url(可选)
    use_backend httpservers if  html #2.如果满足acl html规则,则推送给后端服务器httpservers
    default_backend    httpservers   #默认使用的服务器组
backend httpservers    #名字要与上面的名字必须一样
    balance     roundrobin  #负载均衡的方式
    server  http1 192.168.13.133:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2
    server  http2 192.168.13.137:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2

其中你需要修改的地方

Haproxy详解以及基于Haproxy的高可用实战

 

如果我们访问http://192.168.13.144:81/haproxy

Haproxy详解以及基于Haproxy的高可用实战

Haproxy详解以及基于Haproxy的高可用实战

页面主要参数解释
       Queue
       Cur: current queued requests //当前的队列请求数量       Max:max queued requests     //最大的队列请求数量       Limit:           //队列限制数量

Errors
Req:request errors             //错误请求
Conn:connection errors          //错误的连接

Server列表:
Status:状态,包括up(后端机活动)和down(后端机挂掉)两种状态
LastChk:    持续检查后端服务器的时间
Wght: (weight) : 权重
========================================================

      如果出现bind失败的报错,执行下列命令
      setsebool -P haproxy_connect_any=1

5.Keepalived实现调度器HA(两个节点都需要下载)

注:主/备调度器均能够实现正常调度

1.主/备调度器安装软件

192.168.13.128
[root@localhost ~]# yum install -y keepalived
[root@localhost ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak  #备份
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id directory1   #只是名字而已,辅节点改为directory2(两个名字一定不能一样)
}

vrrp_instance VI_1 {
    state MASTER        #定义主还是备,备用的话写backup
    interface ens33     #VIP绑定接口
    virtual_router_id 80  #整个集群的调度器一致(在同一个集群)
    priority 100         #(优先权)back改为50(50一间隔)
    advert_int 1         #发包
    authentication {
        auth_type PASS      #主备节点认证
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.13.144/24    #VIP(自己网段的)
    }
}

192.168.13.129
[root@backup ~]# yum install -y keepalived
[root@backup ~]# mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
[root@backup ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id directory2
}
vrrp_instance VI_1 {
    state BACKUP    #设置为backup
    interface ens33
    nopreempt        #设置到back上面,不抢占资源
    virtual_router_id 80
    priority 50   #辅助改为50
    advert_int 1    #检测间隔1s
    authentication {
        auth_type PASS
        auth_pass 1111            #认证类型和密码主备一样,要不然无法互相认证
    }
    virtual_ipaddress {
        192.168.13.144/24    #抢占的VIP也一样
    }
}

2.启动KeepAlived(主备均启动)

[root@master ~]# systemctl start keepalived
[root@backup ~]# systemctl start keepalived
开机自启(可以不设置)
[root@master ~]# systemctl enable keepalived
[root@backup ~]# systemctl enable keepalived

注意:

如果你网页访问不到,可能是配置文件出错了。如果你是直接复制本文章的代码,建议你将注释都去掉,有时候可能你的输入法的问题,导致配置文件出现一些多余的空格之类的。

访问你自己设置的VIP 192.168.13.144

Haproxy详解以及基于Haproxy的高可用实战

查看两个节点服务器,你会发现VIP在主节点

Haproxy详解以及基于Haproxy的高可用实战

如果这个时候主节点服务器宕机了(我们把服务停止了用来测试),VIP会自己漂移到备用节点上。

Haproxy详解以及基于Haproxy的高可用实战

但是用户访问时却感觉不到

Haproxy详解以及基于Haproxy的高可用实战

网页照样可以继续使用,这就是高可用性。

 

5.基于nginx的高可用性

 

以上我们只是实现了高可用,基于Haproxy的前提是Haproxy服务是正常。如果有突发情况使得nginx服务不能启动,但是我们的keepalived服务是正常,这个时候用户是访问不到的,VIP也不会自动漂移到备用的节点服务器上。所以我们需要写一些代码来判断一下Haproxy服务是不是正常,如果不正常的话我们就将Haproxy服务关掉,然后实现VIP的漂移,这个时候用户就不会出现无法访问的情况了。

思路:
让Keepalived以一定时间间隔执行一个外部脚本,脚本的功能是当Haproxy失败,则关闭本机的Keepalived
[root@master ~]# vim /etc/keepalived/check_haproxy_status.sh
#!/bin/bash
/usr/bin/curl -I http://localhost &>/dev/null  
if [ $? -ne 0 ];then                                                                    
#       /etc/init.d/keepalived stop
        systemctl stop keepalived
fi                                                                     
[root@localhost ~]# chmod a+x /etc/keepalived/check_haproxy_status.sh   #一定要加执行权限

 

(2)keepalived使用script
 [root@localhost ~]# vim /etc/keepalived/keepalived.conf
   ! Configuration File for keepalived

global_defs {
   router_id director1
}
vrrp_script check_haproxy {
   script "/etc/keepalived/check_haproxy_status.sh"
   interval 5  #每5秒执行一次
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 80
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.13.144/24
    }
    track_script {
        check_haproxy
    }
}
注:必须先启动Haproxy,再启动keepalived,建议备用节点也添加上.

测试访问:

将keepalived集群的主节点的nginx服务关闭,查看vip是否漂移,如果漂移,即成功

Haproxy详解以及基于Haproxy的高可用实战

Haproxy详解以及基于Haproxy的高可用实战

6.配置haproxy的日志

两台机器都配置haproxy的日志:需要打开注释并添加

[root@master ~]# vim /etc/rsyslog.conf
# Provides UDP syslog reception  #由于haproxy的日志是用udp传输的,所以要启用rsyslog的udp监听
$ModLoad imudp
$UDPServerRun 514
找到  #### RULES ####   下面添加
local2.*                       /var/log/haproxy.log

 


[root@master ~]# systemctl restart rsyslog
[root@master ~]# systemctl restart haproxy
[root@master ~]# tail -f /var/log/haproxy.log    #实时查看日志
Mar 19 12:53:27 localhost haproxy[73866]: Proxy stats started.
Mar 19 12:53:27 localhost haproxy[73866]: Proxy web started.
Mar 19 12:53:27 localhost haproxy[73866]: Proxy httpservers started.

 

链接:https://www.jianshu.com/p/1fab38472c04

热评好文: