Keepalive + Haproxy + Nginx 实战高可用

 网络拓扑

 

 

 

 

haproxy1 192.168.19.121 haproxy、keepalived
haproxy2 192.168.19.122 haproxy、keepalived
nginx1 192.168.19.123 nginx
nginx2 192.168.19.124 nginx
VIP     192.168.19.120 keepalived VIP

 

(一)、配置主机hosts文件-每台都要配置 

[root@haproxy1 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.19.121 haproxy1
192.168.19.122 haproxy2
192.168.19.123 nginx1
192.168.19.124 nginx2

(二)、Nginx安装


【192.168.19.121】
[root@nginx1 ~]# systemctl stop firewalld && setenforce 0
[root@nginx1 ~]# cd /etc/yum.repos.d/
[root@nginx1 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@nginx1 yum.repos.d]# yum install yum-utils -y
[root@nginx1 yum.repos.d]# yum install nginx -y
[root@nginx1 yum.repos.d]# systemctl start nginx #启动
[root@nginx1 ~]# echo "real-server [Nginx 1]" > /usr/share/nginx/html/index.html #方便区分,看出效果
[root@nginx1 ~]# vim /etc/nginx/nginx.conf
keepalive_timeout 0; #设置长链接
[root@nginx1 ~]# nginx -s reload


【192.168.19.122】
[root@nginx2 ~]# systemctl stop firewalld && setenforce 0
[root@nginx2 ~]# cd /etc/yum.repos.d/
[root@nginx2 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@nginx2 yum.repos.d]# yum install yum-utils -y
[root@nginx2 yum.repos.d]# yum install nginx -y
[root@nginx2 yum.repos.d]# systemctl start nginx #启动
[root@nginx2 ~]# echo "real-server [Nginx 2]"> /usr/share/nginx/html/index.html
[root@nginx2 ~]# vim /etc/nginx/nginx.conf
keepalive_timeout 0;#默认keepalive_timeout 65;
[root@nginx2 ~]# nginx -s reload
#修改后端nginx服务器的长连接是为了方便测试

**安装时报错:缺少 pcre2 解决办法:wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 再进行安装

 

 

 (三)、调度器配置Haproxy(主/备)

【192.168.19.121】
[root@haproxy1 ~]# yum -y install haproxy
[root@haproxy1 ~]# cp -rf /etc/haproxy/haproxy.cfg{,.bak}  #备份
[root@master ~]# sed -i -r '/^[ ]*#/d;/^$/d' /etc/haproxy/haproxy.cfg    #修改配置文件去掉注释
[root@haproxy1 ~]# 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               
    nbproc 1            
defaults
    mode                    http    
    log                     global
    retries                 3   
    option                  redispatch  
    maxconn                 4000  
    contimeout              5000  
    clitimeout              50000 
    srvtimeout              50000 
listen stats
    mode                    http
    bind                    *:81
    stats                   enable
    stats uri               /haproxy-status
    stats auth              haadmin:sheca
frontend  web
    mode                    http
    bind                    *:80
    option                  httplog
    acl html url_reg  -i  \.html$
    use_backend httpservers if  html
    default_backend    httpservers
backend httpservers
    balance     roundrobin
    server  nginx1 192.168.19.123:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2
    server  nginx2 192.168.19.124:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2
    server  nginx3 192.168.19.125:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2   #这条是测试 没有这台服务器

【192.168.19.122】haproxy2
[root@haproxy2 ~]# yum -y install haproxy
[root@haproxy2 ~]# cp -rf /etc/haproxy/haproxy.cfg{,.bak}  #备份
[root@haproxy2 ~]# sed -i -r '/^[ ]*#/d;/^$/d' /etc/haproxy/haproxy.cfg    #修改配置文件去掉注释
[root@haproxy2 ~]# 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               
    nbproc 1            
defaults
    mode                    http    
    log                     global
    retries                 3   
    option                  redispatch  
    maxconn                 4000  
    contimeout              5000  
    clitimeout              50000 
    srvtimeout              50000 
listen stats
    mode                    http
    bind                    *:81
    stats                   enable
    stats uri               /haproxy-status
    stats auth              haadmin:sheca
frontend  web
    mode                    http
    bind                    *:80
    option                  httplog
    acl html url_reg  -i  \.html$
    use_backend httpservers if  html
    default_backend    httpservers
backend httpservers
    balance     roundrobin
    server  nginx1 192.168.19.123:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2
    server  nginx2 192.168.19.124:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2
    server  nginx3 192.168.19.125:80 maxconn 2000 weight 1  check inter 1s rise 2 fall 2   #这条是测试 没有这台服务器

 登陆Haproxy 检测页面

192.168.19.121:81/haproxy-status      账户密码 haadmin/sheca

 192.168.19.122:81/haproxy-status   账户密码 haadmin/sheca

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

192.168.19.121】
[root@haproxy1 ~]# yum install -y keepalived
[root@haproxy1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak  #备份
[root@haproxy1 ~]# 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.19.120/24    #VIP(自己网段的)
    }
}

【192.168.19.122】
[root@haproxy2 ~]# yum install -y keepalived
[root@haproxy2 ~]# mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
[root@haproxy2 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
​
global_defs {
   router_id directory2
}
vrrp_instance VI_1 {
    state 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.19.120/24    #抢占的VIP也一样
    }
}

[root@haproxy1~]# systemctl start keepalived
[root@haproxy2~]# systemctl start keepalived
[root@haproxy1~]# systemctl enable keepalived
[root@haproxy2~]# systemctl enable keepalived
测试访问 VIP地址 :192.168.19.120

 

 

 

 查看VIP地址在哪台服务器上:在haproxy1上

 

 测试haproxy1宕机,VIP会自己漂移到备用节点haproxy2上.(采用停止keepalived),继续访问测试VIP地址 :192.168.19.120,实现了高可用性。
 systemctl stop keepalived

 

 

(五)、Keepalived 检测 Haproxy 实现高可用

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

让Keepalived以一定时间间隔执行一个外部脚本,脚本的功能是当Haproxy失败,则关闭本机的Keepalived
[root@haproxy1 ~]# 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@haproxy1 ~]# chmod a+x /etc/keepalived/check_haproxy_status.sh   #一定要加执行权限
keepalived使用script
[root@haproxy1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   router_id directory1
}

vrrp_script check_haproxy {
   script "/etc/keepalived/check_haproxy_status.sh"
   interval 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.19.120/24
    }

    track_script {
        check_haproxy
    }
}

必须先启动Haproxy,再启动keepalived,建议haproxy2点也添加

测试访问: 将haproxy停止,查看keepalived是否检测到haproxy1的应用是否杀掉 ,vip是否漂移。

systemctl stop haproxy

 

(六)、配置haproxy的日志

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

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

 

[root@haproxy1 ~]# systemctl restart rsyslog
[root@haproxy1 ~]# systemctl restart haproxy
[root@haproxy1 ~]# 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.

补充:解析Haprpxy 配置文件

示例1:转发

global
    log 127.0.0.1 local3 info
    maxconn 4096
        uid nobody
#       uid 99
        gid nobody
#       gid 99
    daemon
    nbproc 1
    pidfile /run/haproxy.pid
defaults
    log           global
    mode       http
    maxconn 2048
    retries     3
    option    redispatch
    contimeout    5000
    clitimeout        50000
    srvtimeout        50000
#timeout connect 5000
#timeout client 50000
#timeout server 50000
    option abortonclose

    stats uri /admin?stats
    stats realm Private lands
    stats auth admin:password
    stats hide-version
    
frontend http-in
    bind 0.0.0.0:80
    mode http
    log global
    option httplog
    option httpclose
     acl html url_reg  -i  \.html$
     use_backend html-server if  html
     default_backend html-server

backend html-server
    mode http
    balance roundrobin
    option httpchk GET /index.html
    cookie SERVERID insert indirect nocache
    server html-A web1:80 weight 1 cookie 3 check inter 2000 rise 2 fall 5
    server html-B web2:80 weight 1 cookie 4 check inter 2000 rise 2 fall 5
gloab:全局配置
log:日志配置
maxconn:最大连接限制(优先级低)
uid:用户
gid:组用户
deamon:守护进程运行
nbproc :haproxy进程数,该值的设置应该和服务器的CPU核心数一致,比如设置为 16,即常见的2颗8核心CPU的服务器,即共有16核心,则可以将其值设置为:<=16 ,创建多个进程数,可以减少每个进程的任务队列,但是过多的进程数也可能会导致进程的崩溃。
pidfile /run/haproxy.pid :haproxy进程ID存储位置
defaults:针对(listen和backend块进行设置没如果块中没设置,则使用默认设置)默认配置
log:日志使用全局配置
mode:模式7层LB
maxconn:最大连接数(优先级中)
retries:健康检查。3次连接失败就认为服务不可用
option:服务不可用后的操作,重定向到其他健康服务器
contimeout    :(重传计时器)定义haproxy将客户端!!!请求!!!转发至后端服务器,所等待的超时时长
clitimeout:(向后长连接)haproxy作为客户,和后端服务器之间!!!空闲连接!!!的超时时间,到时候发送fin指令
srvtimeout    :(向前长连接)haproxy作为服务器,和用户之间空闲连接的超时时间,到时候发送fin指令
option abortonclose  :当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接


stats uri /admin?stats:设置统计页面的uri为/admin?stats
stats realm Private lands:设置统计页面认证时的提示内容
stats auth admin:password:设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
stats hide-version:隐藏统计页面上的haproxy版本信息

frontend:前端配置块。面对用户侧
bind:面对用户监听地址和端口
mode:http模式的LB
log:日志使用全局配置

option httplog:默认日志格式非常简陋,仅包括源地址、目标地址和实例名称,而“option httplog参数将会使得日志格式变得丰富许多,其通常包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部及cookie、“frontend”、“backend”及服务器名称,当然也包括源地址和端口号等。

option http close: 每次请求完毕后,关闭http通道

 acl html url_reg  -i  \.html$  :1. 访问控制列表名称html。规则要求访问以html结尾的url时
 use_backend html-server if  html   :2.如果满足acl html规则,则推送给后端服务器 html-server
 default_backend html-server  3:默认的后端服务器是 html-server

backend html-server:后端服务器名称为  html-server
mode http:模式为7层代理
balance roundrobin:算法为轮训
option httpchk GET /index.html     :允许用http协议检查server 的健康
cookie SERVERID insert indirect nocache:轮询的同时,根据插入的cookie SERVERID  的值来做会话保持,将相同的用户请求,转发给相同的真实服务器。
server html-A web1:80 weight 1 cookie 3 check inter 2000 rise 2 fall 5:cookie 3 服务器ID,避免rr算法将客户机请求转发给其他服务器 ,对后端服务器的健康状况检查间隔为2000毫秒,连续2次健康检查成功,则认为是有效的,连续5次健康检查失败,则认为服务器宕机
server html-B web2:80 weight 1 cookie 4 check inter 2000 rise 2 fall 5

示例2:根据文件后缀名字进行转发

######## 全局配置信息 #########
######参数是进程级的,通常和操作系统相关#######

	global
		log 127.0.0.1 local3 info	   #日志服务器
		maxconn 4096				   #最大连接数
		uid nobody					   #用户身份
		gid nobody					   #组身份
		daemon						   #守护进程方式后台运行
		nbproc 1						   #工作进程数量
		
####### ###########默认设置 ###################
#####这些参数是配置 frontend,backend,listen 组的 ###########		
	defaults                    #这些参数可以被利用配置到frontend,backend,listen组件   
		log		   global
		mode	   http	    #工作模式 http ,tcp 是 4 层,http是 7 层	
		maxconn 2048		#最大连接数
		retries 	3			    #3 次连接失败就认为服务器不可用
		option	redispatch	#如果 cookie 写入了 serverId 而客户端不会刷新 cookie,当serverId 对应的服务器挂掉后,强制定向到其他健康的服务器
		stats	uri  /haproxy	#使用浏览器访问 http://192.168.122.254/haproxy,可以看到服务器状态
		stats auth           wing:123     #用户认证,客户端使用elinks浏览器的时候不生效
		contimeout	5000          #连接超时时间,单位毫秒ms
		clitimeout	    50000        #客户端超时
		srvtimeout	    50000        #服务器超时
		
		
	frontend http-in
		bind 0.0.0.0:80                           #监听端口
		mode http
		log global
		option httplog			                 #日志类别 http 日志格式
		option httpclose		                 #打开支持主动关闭功能,每次请求完毕后主动关闭http通道	,ha-proxy不支持keep-alive,只能模拟这种模式的实现	
	    acl php url_reg  -i  \.php$			 #acl <ACL名字>  <类型>  <大小写>  <规则>
	    acl html url_reg  -i  \.html$		  	 #use_backend  <服务器组>  if  <ACL名字>
	    use_backend php-server if  php
	    use_backend html-server if  html
	    default_backend html-server		 #默认使用的服务器组
	

	backend php-server
		mode http
		balance roundrobin			            #负载均衡的方式
		option httpchk GET /index.php		#健康检查
		cookie SERVERID insert indirect nocache	#客户端的 cookie 信息,允许插入serverid到cookie中,此处cookie号不同
		server php-A 192.168.122.30:80 weight 1 cookie 1 check inter 2000 rise 2 fall 5
		server php-B 192.168.122.40:80 weight 1 cookie 2 check inter 2000 rise 2 fall 5
		#cookie 1 标识 serverid 为 1
		#check inter 2000          检测心跳频率
		#rise 2     2 次正确认为服务器可用
		#fall 5      5 次失败认为服务器不可用
	
	backend html-server
		mode http
		balance roundrobin
		option httpchk GET /index.html
		cookie SERVERID insert indirect nocache
		server html-A 192.168.122.10:80 weight 1 cookie 3 check inter 2000 rise 2 fall 5
		server html-B 192.168.122.20:80 weight 1 cookie 4 check inter 2000 rise 2 fall 5		

  

 

posted @ 2023-02-28 16:10  しみずよしだ  阅读(506)  评论(0)    收藏  举报