分布式 高可用(Keepalived/HAProxy)

简介:高可用(High Avalilability)指两台或两台以上业务系统启动着相同的服务,如果其中一台有故障,另外一台自动接管工作,实现故障转移。

一、Keepalived

  简介:Keepalived是服务器一种高性能且轻量级的高可用或热备解决方案,通过VRRP协议(虚拟路由冗余协议)来防止服务器静态路由单点故障的发生,结合Nginx可以实现WEB前端服务的高可用。

  1. 基础

    A. 用途

      故障转移:实现负载均衡中MASTER主机BACKUP主机之间的故障转移和自动切换;

      心跳检测:负载均衡定期检查RS服务器的可用性决定是否给其分发请求;

    B. VRRP(Vritrual Router Redundancy Protocol)协议:是一种容错协议,为了解决静态路由的单点故障;是通过一种竞选协议机制来将路由任务交给某台VRRP路由器,通过优先级来确定MASTER和BACKUP;保证当主机的下一条路由器出现故障时,由另一台路由器来替代出现故障的路由器进行工作,从而保证网络通信的连续性和可靠性,而且自身使用了加密协议;

    C. 故障切换转移原理:在Keepalived正常工作时,MASTER节点会不断的向BACKUP节点发送心跳消息,用来告诉BACKUP节点自己还活着,当MASTER节点发生故障时,BACKUP节点就无法继续检测到MASTER节点的心跳,进而调用自身的接管程序,接管MASTER节点的IP资源和服务,当MASTER节点恢复故障时,BACKUP节点会释放MASTER节点故障时自身接管的IP资源和服务,恢复到原来的自身的备用角色;

    D. 工作方式分类

      抢占式(默认模式):MASTER以组播方式不断的向虚拟路由器组内发送自己的心跳报文,一旦BACKUP在设定时间内没有收到心跳信息的次数超过了限定次数,则会将MASTER的所有权转移到优先级最高的BACKUP;

      非抢占模式:指只有在主节点完全故障时才能将BACKUP变为MASTER。

  2. Keepalived搭建

    A. 安装keepalived:yum install keepalived -y;

     B. 修改/etc/keepalived/keepalived.conf配置文件,注意主备文件的区别在于router_id信息不一致、state状态描述信息不一致、priority优先级不一致;

     C. 启动keepalived:systemctl start keepalived;

     D. 查看日志:默认日志文件是var/log/messages;

     E. 查看虚拟IP状态:ip a;

    F. 测试nginx高可用

     nginx01和nginx02主机都正常开启,nginx01主机上keepalived为主,nginx02主机上keepalived为备,keepalived也都正常开启,访问http://10.12.113.88,正常返回nginx01主机上的内容;

     nginx01和nginx02主机都正常开启,nginx01主机上keepalived为主,但keepalived服务关闭,nginx02主机上keepalived为备且服务正常开启,访问http://10.12.113.88,正常返回nginx02主机上的内容;

  3. keepalived.conf 配置文件

! Configuration File for keepalived
global_defs {
  # 本节点的标识信息,即hostname
  router_id dcy01
} 

# 定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级
vrrp_script nginx_check {
  # 检测Nginx状态的脚本路径
  script "/etc/keepalived/nginx_check.sh" 
  # 检测时间间隔
  interval 5 
}

# 定义虚拟路由,VI_1为虚拟路由的自定义标示符
vrrp_instance VI_1 {
  # 主节点为MASTER, 对应的备份节点为BACKUP 
  state MASTER 
  # 绑定虚拟IP的网络接口,与本机IP地址所在的网络接口相同
  interface ens33
  # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,是决定多播的MAC地址
  virtual_router_id 1
  # 节点优先级,值范围 0-254,优先级高的就是主节点
  priority 100  
# 当转换为MASTER状态时,延迟多少秒发送第二组的免费ARP。默认为5s,0表示不发送第二组免的免费ARP
vrrp_garp_master_delay 10
# 当转换为MASTER状态时,在一组中一次发送的免费ARP数量。默认是5
vrrp_garp_master_repeat 10   # 组播信息发送间隔,两个节点设置必须一样,默认1s   advert_int 1   # 设置验证信息,两个节点必须一致   authentication {     # 认证方式     auth_type PASS     # 密码     auth_pass 123456   }   # 虚拟IP池,两个节点设置必须一样   virtual_ipaddress {     # 虚拟ip,可以定义多个,默认32位 mask     192.168.1.1   }   track_script {     # 执行Nginx监控     nginx_check   }

     # 当当前节点成为master时,通知脚本执行任务
     notify_master "/rhxy/keepalived/script/slave-to-master.sh"
     # 当当前节点成为backup时,通知脚本执行任务
     notify_backup "/rhxy/keepalived/script/master-to-slave.sh"
     # 当当前节点出现故障,执行的任务
     notify_fault "/rhxy/keepalived/script/master-to-slave.sh"
     # 设置keepalived的状态,传入这个脚本的参数为($1为GROUP或INSTANCE、$2为组名或实例名、$3为"MASTER"|"BACKUP"|"FAULT"

     notify "/rhxy/keepalived/script/notify-state.sh"

}

   4. keepalived脑裂现象

    A. 现象:脑裂指由于某些原因(如网络差、防火墙开启等),导致多台keepalived的服务器在指定时间内无法检测到对方存活心跳信息(事实上服务器还是存活状态),从而导致相互抢占对方的资源和服务所有权的现象;

    B. keepalived监控nginx:Nginx宕机会导致用户请求失败,但是keepalived不会进行切换,故需要编写检测nginx是否存活的脚本,shell脚本如下;

#!/bin/sh

# 判断nginx是否关闭 if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then #systemctl stop keepalived pkill keepalived fi

  5. 主备切换时间原理

    A. 将自身设置为MASTER节点后,立刻发送GARP广播包,默认发送两次,每次发送5个GARP数据包,每次间隔5s,GARP数据包中包含自身的优先级和工作状况数据,BACKUP服务器通过接收到的VRRP报文的情况判断MASTER路由器是否正常工作;

     B. MASTER路由器主动放弃MASTER地位时,会先发送优先级为0的VRRP报文,使BACKUP路由器快速切换变为MASTER路由器,切换时间Skew_Time=(256 - BACUP路由器的优先级) / 256 秒;

     C. MSTER路由器因故障不能发送VRRP报文时,BACKUP路由器并不能立即知道其工作状况,当BACKUP路由器等待一段时间后,如果还没接收到VRRP报文,那么会认为MASTER路由器无法正常工作,而把自己升级为MASTER路由器,周期性发送报文,如果此时多个BACKUP路由器竞争MASTER路由器的位置,将通过优先级来选举MASTER路由器,BACKUP路由器默认等待时间称为Master_Down_Interval=(3 * advert_int)+ Skew_Time;

    D. 在性能不够稳定的网络中,Backup路由器可能因为网络堵塞而在Master_Down_Interval期间没有收到Master路由器的报文而主动抢占为Master位置,如果此时原Master路由器的报文又到达了,就会出现虚拟路由器的成员频繁的进行Master抢占现象,为了缓解这种现象的发生,特制定了延迟等待定时器(preempt_delay:设置抢占延迟。单位是秒,范围是0---1000,默认是0.发现低优先级的MASTER后多少秒开始抢占),它可以使得Backup路由器在等待了Master_Down_Interval后,再等待延迟等待时间,如在此期间仍然没有收到VRRP报文,此时Backup路由器才会切换为Master路由器,对外发送VRRP报文.

 

  6.  其他

    A. Keepalived防火墙策略:防火墙规则主从机器都要配置,双向打开vrrp服务,firewall-cmd --permanent --add-protocol=vrrp;firewall-cmd --reload;

    B. 常见问题

      问题一:WARNING - script '/etc/keepalived/nginx_check.sh' is not executable for uid:gid 0:0 - disabling;

      原因:keepalived上监控脚本没有执行权限;

      解决方案:chomd +x /etc/keepalived/nginx_check.sh。

     C. 服务莫名不能启动:比如找不到配置文件,子进程无法启动等,可以执行:sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config && reboot;

 

二、HAProxy

  简介:HAProxy提供高可用、负载均衡以及反向代理服务,支持虚拟主机,是免费、快速并且可靠的一种解决方案。

  1. 基础

    A. 特性

      基于TCP(第四层)和HTTP(第七层)应用的代理,特别适合负载大的WEB站点,保护WEB服务器不会暴露在公网上;

      是一种单进程、事件驱动模型,支持非常大的并发连接数;

      拥有服务器健康检查功能和系统状态监控页面,当代理服务出现故障会自动剔除,可以减少程序增加健康检测功能,如果恢复又重新加入进来

    B. 负载均衡客户端与服务器识别方式

      用户IP识别;

      cookie识别;

      session识别;

    C. 负载均衡算法

      roundrobin(默认算法):轮询算法,根据权重进行服务器轮流使用,适合短连接场景;

      leastconn:最近最少算法,使用最近最少使用的服务器,适合长连接场景;

      source:哈希算法,对请求源IP地址进行哈希。

    D. http协议健康检查方式

      option httpchk:通过监听端口进行健康检查,注意haproxy只会去检查后端server的端口,并不能保证服务的真正可用;

      option httpchk GET /index.html:通过URI获取进行健康检测,这是用发送GET请求到后端的WEB界面,基本上可以代表后端服务的可用性;

      option httpchk HEAD /index.jsp HTTP/1.1\r\nHost:\ www.xxx.com:通过request获取的头部信息进行匹配进行健康检测,这种检测方式,则是基于高级,精细的一些监测需求,通过对后端服务访问的头部信息进行匹配检测;

  2. HAProxy搭建

    A. 安装haproxy:yum install haproxy -y;

    B. 修改/etc/haproxy/haproxy.cfg配置文件;

    C. 启动haproxy:systemctl start haproxy;

    D. 访问haproxy监控平台:http://127.0.0.1:1080。

  3. haproxy.cfg 配置文件

# 全局参数
global   
    # 日志配置,指定使用127.0.0.1上的syslog服务中的local0日志设备,记录日志等级为info的日志
    log 127.0.0.1 local0 info
	# 设置运行haproxy的用户,可以使用uid替代
	user haproxy
    # 设置运行haproxy的组,可使用gid替代
    group haproxy
    # 以守护进程的方式运行
    daemon
    # 启动时的进程数,设置多个有助提高处理效率,但是过多的进程数也可能会导致进程的崩溃
    nbproc 16
    # 每个进程的最大连接数 ,由于每个连接包括一个客户端和一个服务器端,所以单个进程的TCP会话最大数目将是该值的两倍
    maxconn 4096
    # 设置最大打开的文件描述符数,在1.4的官方文档中提示,该值会自动计算,所以不建议进行设置
    #ulimit -n 65536
    # 将所有进程写入pid文件
    pidfile /var/run/haproxy.pid

# 默认参数
defaults 
    # 运行模式有http、tcp(默认值)、health
    mode http
    # 使用127.0.0.1上的syslog服务的local3设备记录错误信息
    log 127.0.0.1 local3 err
    # 定义连接后端服务器的失败重连次数,判断服务不可用
    retries 3
    # 启用HTTP请求日志记录,默认haproxy日志格式很简单
    option httplog
    # 如果后端有服务器宕机,强制切换到正常服务器
    option redispatch
    # 丢弃由于客户端等待时间过长而关闭连接但还在harpoxy等待队列中的请求
    option abortonclose
    # 不记录健康检查的日志信息
    option dontlognull
    # 每次请求完毕后主动关闭http通道
    option http-server-close
    # 连接超时
    contimeout 5000
    # 客户端超时
    clitimeout 3000
    # 服务器超时
    srvtimeout 3000

# frontend和backend的组合体,定义一个名为status的部分
listen status 
    # 定义监听的套接字
    bind 0.0.0.0:1080
    # 定义为HTTP模式
    mode http
    # 继承global中log的定义
    log global
    # stats是haproxy的一个统计页面的套接字,该参数设置统计页面的刷新间隔为30s
    stats refresh 30s
    # 统计页面URL路径
    stats uri /admin-stats
    # 设置统计页面认证时的提示内容
    stats realm Private lands
    # 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
    stats auth admin:123456
    # 隐藏统计页面上的haproxy版本信息
    stats hide-version

# 接收请求的前端虚拟节点
frontend web 
    # 监听80端口
    bind 0.0.0.0:80
    # 定义为HTTP模式
    mode http
    # 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
    option forwardfor
    # 定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到
    acl static_down nbsrv(static_server) lt 1
    # 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,上面两种写法任选其一
    acl php_web url_reg /*.php$
    # 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到,上面两种写法任选其一
    acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
    # 如果满足策略static_down时,就将请求交予backend web_server
    use_backend web_server if static_down
    # 如果满足策略php_web时,就将请求交予backend web_server
    use_backend web_server if php_web
    # 如果满足策略static_web时,就将请求交予backend static_server
    use_backend static_server if static_web

# 配置后端服务集群
backend web_server 
    # 设置为http模式
    mode http
    # 设置haproxy的调度算法为源地址hash
    balance source
    # 允许向cookie插入SERVERID,每台服务器的SERVERID可在下面使用cookie关键字定义
    cookie SERVERID
    # 开启对后端服务器的健康检测,通过GET /test/index.php来判断后端服务器的健康情况
    option httpchk GET /test/index.php
    server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
    server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
    # server语法:server <name> <address>[:port] [param*] # 使用server关键字来设置后端服务器;为后端服务器所设置的内部名称[php_server_1],该名称将会呈现在日志或警报中、后端服务器的IP地址,支持端口映射[10.12.25.68:80]、指定该服务器的SERVERID为1[cookie 1]、接受健康监测[check]、监测的间隔时长,单位毫秒[inter 2000]、监测正常多少次后被认为后端服务器是可用的[rise 3]、监测失败多少次后被认为后端服务器是不可用的[fall 3]、分发的权重[weight 2]、最后为备份用的后端服务器,当正常的服务器全部都宕机后,才会启用备份服务器[backup]
    server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup
 
backend static_server
    mode http
    option httpchk GET /test/index.html
    server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 

 

可参考:keepalived实现服务高可用

    HAProxy + Keepalived的配置

    HAProxy官方文档参数配置

    HAProxy用法详解

 

posted @ 2021-05-21 09:01  如幻行云  阅读(554)  评论(0编辑  收藏  举报