LB 介绍

Nginx、LVS、HAProxy 是目前使用最广泛的三种负载均衡软件,HAProxy是一款功能强大、灵活好用的反向代理的开源软件,它提供了负载均衡、服务器代理的功能。HAProxy是Willy Tarreau使用C语言编写的,它支持SSL、压缩、keep-alive、自定义日志格式和header重写。HAProxy是轻量级的负载均衡和代理服务软件,占用系统资源较少

HAProxy可以使用两种模式运行:TCP 4层模式和HTTP 7层模式。TCP模式:HAProxy把原始TCP数据包从客户端转向到应用服务器;HTTP模式:解析http请求,然后转向到web服务器。我们将使用HTTP 7层模式

负载均衡拓扑图 load-balance

环境准备

| OS | 组件 | IP | | cetos7 | keepalived+haproxy | 192.168.101.251 | | cetos7 | keepalived+haproxy | 192.168.101.252 | | cetos7 | nginx | 192.168.101.253 | | cetos7 | nginx | 192.168.101.254 |

关闭防火墙
1
2
systemctl stop firewalld && systemctl disable firewalld
sed -i "#SELINUX=enforcing#SELINUX=disabled#" /etc/selinux/config

HAPROXY 负载均衡算法

  • HAProxy 也是支持虚拟主机的。
  • HAProxy 的优点能够补充 Nginx 的一些缺点,比如支持 Session 的保持,Cookie的引导;同时支持通过获取指定的 url 来检测后端服务器的状态。
  • HAProxy 跟 LVS 类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy 会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
  • HAProxy 支持 TCP 协议的负载均衡转发,可以对 MySQL 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,大家可以用 LVS+Keepalived 对 MySQL主从做负载均衡。
  • HAProxy 负载均衡策略非常多, HAProxy 的负载均衡算法现在具体有如下8种:
  • roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;
  • static-rr,表示根据权重,建议关注;
  • leastconn,表示最少连接者先处理,建议关注;
  • source,表示根据请求源 IP,这个跟 Nginx 的 IP_hash 机制类似,我们用其作为解决 session 问题的一种方法,建议关注;
  • ri,表示根据请求的 URI;
  • rl_param,表示根据请求的 URl 参数’balance url_param’ requires an URLparameter name;
  • hdr(name),表示根据 HTTP 请求头来锁定每一次 HTTP 请求;
  • rdp-cookie(name),表示根据据 cookie(name)来锁定并哈希每一次 TCP 请求。

Keepalived 简介

keepalived可提供vrrp以及health-check功能,可以只用它提供双机浮动的vip(vrrp虚拟路由功能),这样可以简单实现一个双机热备高可用功能

Keepalived是一个基于VRRP协议来实现的WEB 服务高可用方案,可以利用其来避免单点故障,对外表现为一个虚拟IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候,备份服务器就会接管虚拟IP

部署

在251、252上安装 Haproxy+keepalived

1
yum install haproxy keepalived -y
配置 Keepalived

配置 master 192.168.101.251上配置文件 /etc/keepalived/keepalived.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
! Configuration File for keepalived

global_defs {
   # 通知邮件服务器的配置
   notification_email {
     # 当master失去VIP或则VIP的时候,会发一封通知邮件到[email protected]
     [email protected]
   }
   # 发件人信息
   notification_email_from [email protected]
   # 邮件服务器地址
   smtp_server 127.0.0.1
   # 邮件服务器超时时间
   smtp_connect_timeout 30
   # 邮件TITLE
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    # 主机: MASTER
    # 备机: BACKUP
    state MASTER
    # 实例绑定的网卡, 用ip a命令查看网卡编号
    interface eth0
    # 虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样
    virtual_router_id 88
    # 优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器
    priority 100
    # 主备之间同步检查的时间间隔单位秒
    advert_int 1
    # 验证类型和密码
    authentication {
        # 验证类型有两种 PASS和HA
        auth_type PASS
        # 验证密码,在一个实例中主备密码保持一样
        auth_pass 123456
    }
    # 虚拟IP地址,可以有多个,每行一个
    virtual_ipaddress {
        192.168.101.250
    }
}

virtual_server 192.168.101.250 80 {
    # 健康检查时间间隔
    delay_loop 6
    # 调度算法
    # Doc: http://www.keepalived.org/doc/scheduling_algorithms.html
    # Round Robin (rr)
    # Weighted Round Robin (wrr)
    # Least Connection (lc)
    # Weighted Least Connection (wlc)
    # Locality-Based Least Connection (lblc)
    # Locality-Based Least Connection with Replication (lblcr)
    # Destination Hashing (dh)
    # Source Hashing (sh)
    # Shortest Expected Delay (seq)
    # Never Queue (nq)
    # Overflow-Connection (ovf)
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    # 通过调度算法把Master切换到真实的负载均衡服务器上
    # 真实的主机会定期确定进行健康检查,如果MASTER不可用,则切换到备机上
    real_server 192.168.101.253 80 {
        weight 1
        TCP_CHECK {
            # 连接超端口
            connect_port 80
            # 连接超时时间
            connect_timeout 3
        }
    }
    real_server 192.168.101.254 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
        }
    }
}

配置 BACKUP 192.168.101.252 上配置文件 /etc/keepalived/keepalived.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
! Configuration File for keepalived

global_defs {
   # 通知邮件服务器的配置
   notification_email {
     # 当master失去VIP或则VIP的时候,会发一封通知邮件到[email protected]
     [email protected]
   }
   # 发件人信息
   notification_email_from [email protected]
   # 邮件服务器地址
   smtp_server 127.0.0.1
   # 邮件服务器超时时间
   smtp_connect_timeout 30
   # 邮件TITLE
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    # 主机: MASTER
    # 备机: BACKUP
    state BACKUP
    # 实例绑定的网卡, 用ip a命令查看网卡编号
    interface eth0
    # 虚拟路由标识,这个标识是一个数字(1-255),在一个VRRP实例中主备服务器ID必须一样
    virtual_router_id 88 ## ID必须与master一样,重要的说二次
    # 优先级,数字越大优先级越高,在一个实例中主服务器优先级要高于备服务器
    priority 99   # 备服务必须要小于master
    # 主备之间同步检查的时间间隔单位秒
    advert_int 1
    # 验证类型和密码
    authentication {
        # 验证类型有两种 PASS和HA
        auth_type PASS
        # 验证密码,在一个实例中主备密码保持一样
        auth_pass 123456
    }
    # 虚拟IP地址,可以有多个,每行一个
    virtual_ipaddress {
        192.168.101.250
    }
}

virtual_server 192.168.101.250 80 {
    # 健康检查时间间隔
    delay_loop 6
    # 调度算法
    # Doc: http://www.keepalived.org/doc/scheduling_algorithms.html
    # Round Robin (rr)
    # Weighted Round Robin (wrr)
    # Least Connection (lc)
    # Weighted Least Connection (wlc)
    # Locality-Based Least Connection (lblc)
    # Locality-Based Least Connection with Replication (lblcr)
    # Destination Hashing (dh)
    # Source Hashing (sh)
    # Shortest Expected Delay (seq)
    # Never Queue (nq)
    # Overflow-Connection (ovf)
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    # 通过调度算法把Master切换到真实的负载均衡服务器上
    # 真实的主机会定期确定进行健康检查,如果MASTER不可用,则切换到备机上
    real_server 192.168.101.251 80 {
        weight 1
        TCP_CHECK {
            # 连接超端口
            connect_port 80
            # 连接超时时间
            connect_timeout 3
        }
    }
    real_server 192.168.101.252 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
        }
    }
}
启动keepalived 服务

systemctl start keepalived && systemctl enable keepalived

配置 Haproxy

Haproxy 负载算法
  • 定义负载均衡算法,可用于“defaults”、“listen”和“backend”。用于在负载均衡场景中挑选一个server,其仅应用于持久信息不可用的条件下或需要 将一个连接重新派发至另一个服务器时。支持的算法有:
  • roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时> 进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;并支持慢启动。
  • static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限 制;不支持慢启动,在高负荷的情况下,服务器重新上线时会立即被分配大量连接。
  • leastconn(WLC):适用于长连接的会话,新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,> 如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,
  • 可以在运行时调整其权重;
  • source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至> 某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器> ;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;
  • 对原地址hash,第一次调度时使用WLC
  • source:IP层,位于同一个NAT服务器背后的多个请求都会定向至同一个upstream server,不利于负载均衡,一般只有不支持使用cookie插入又需要> 保持会话时使用
  • cookie:应用层,有更好的负载均衡效果;
  • hash/weight%ip :除以权重取模
  • uri:对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个UR I的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算 法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性;
  • url_param:通过为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此 值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一> 个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认> 为静态的,不过其也可以使用hash-type修改此特性;
  • hdr():对于每个HTTP请求,通过指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进 行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.feiyu.com来说,仅计算feiyu字符串的has h值)以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性;
  • rdp-cookie(name)
  • 表示根据据cookie(name)来锁定并哈希每一次TCP请求

二台 Haproxy 配置文件完全一样,这里配置好一处,直接发送到另外一台服务上

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
global
    log         127.0.0.1 local2 info

    chroot      /var/lib/haproxy 
    # haproxy 工作目录
    pidfile     /var/run/haproxy.pid
    maxconn     4000  
    # 最大并发连接数
    user        haproxy
    group       haproxy
    daemon
    # 让haproxy以守护进程方式工作于后台

    stats socket /var/lib/haproxy/stats

defaults
    # default段用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定
    mode                    http
    log                     global
    # 启用事件和流量日志
    option                  httplog
    option                  dontlognull
    option http-server-close
    # 使用长链接时,避免客户端超时没有关闭连接,可以使服务端关闭长连接
    option forwardfor       except 127.0.0.0/8
    # 允许在发往服务器的请求首部中插入“X-Forwarded-For”首部
    option                  redispatch
    # 在使用基于cookie定向时,一旦后端某server宕机时,会将会话重新定向到某一上游服务器
    retries                 3
    # 三次连接失败,则判断服务不可用
    timeout http-request    10s
    # 在客户端建立连接但不请求数据时,关闭客户端连接
    timeout queue           1m
    # 等待最大时长
    timeout connect         10s
    # 定义haproxy将客户端请求转发至后端服务器所等待的超时时长
    timeout client          1m
    # 客户端非活动状态的超时时长
    timeout server          1m
    # 客户端与服务端建立连接后,等待服务端的超时时长
    timeout http-keep-alive 10s
    # 定义保持连接的超时时长
    timeout check           10s
    # 健康状态监测的超时时间,过短会误判,过长资源消耗
    maxconn                 3000
    # 每个server的最大连接数

listen stats
    # listen 段通过关联“frontend”和“backend”定义了一个完整的代理,通常只对TCP流量有用
    bind *:8080
    # 自定义监听端口
    mode http
    option forwardfor
    option httpclose
    stats enable
    # 启用基于程序编译时默认设置的统计报告
    stats show-legends
    stats refresh 10s
    # 统计页面刷新时间
    stats uri /admin?stats
    # 自定义统计页面的URL,默认为/haproxy?stats
    stats realm Haproxy-status
    # 统计页面输入密码框提示信息
    stats haide-version
    # 隐藏统计页面上haproxy版本信息
    stats auth admin:admin
    # 用户的访问密码
    stats admin if TRUE
    # 如果认证通过就做管理功能,可以管理后端的服务器

frontend webserver
    # 用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接
    bind *:80
    # 监听端口
    option httpclose
    # 每次请求完毕主动关闭 http通道
    option httplog
    mode http
    # 模式 tcp:运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;通常用于SSL、SSH、SMTP等应用
    # http:运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;此为默认模式
    log global
    default_backend nginx
    # 指定负载到下面backend

backend nginx
    # 用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器
    balance     roundrobin
    # 设置负载均衡模式,source 保存 session 值,roundrobin 轮询模式
    server  nginx01 192.168.101.253:80 weigt 1 cookie 3 check inter 2000 rise 2 fall
    server  nginx02 192.168.101.254:80 weigt 1 cookie 3 check inter 2000 rise 2 fall
    # inter 2000 心跳检测时间;rise 2 三次连接成功,表示服务器正常;fall 5 三次连接失败,表示服务器异常; weight 1 权重设置

设置haproxy日志

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
vim /etc/rsyslog.conf

$ModLoad imudp   # 取消注释
$UDPServerRun 514   # 取消注释

# 设置haproxy日志存储文件
# save haproxy log
local2.*    /var/log/haproxy/haproxy.log

# 创建 haproxy日志文件目录
mkdir /var/log/haproxy

# 启动haproxy服务
systemctl start haproxy && systemctl enable haproxy
1
2
3
4
5
6
vim /etc/sysconfig/rsyslog
# 接受远程服务器日志
SYSLOGD_OPTIONS="-r -m 0 -c 2"

# 启动服务
systemctl restart rsyslog

BACKUP 192.168.101.252同样配置

Nginx 部署

在253、254二台后端服务上安装nginx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
vim /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key

yum-config-manager --enable nginx-mainline

yum install nginx -y

1
2
3
4
echo "hello nginx01" /usr/share/nginx/html/index.html

# 启动服务
nginx

第二台上同样方法安装nginx

1
2
3
4
echo "hello nginx02" /usr/share/nginx/html/index.html

# 启动nginx
nginx

测试haproxy+keepalived

打开浏览器输入 haproxy主机ip+port/stats 或者vipIP+port/stats 访问haproxy监控页面,输入配置文件设置的用户名和密码,如admin:admin haproxy

在游览器输入VIP地址,访问请求负载到后端服务 lb-nginx

主备切换
1
2
3
在192.168.101.251停止keepalived,查看是否可以访问VIP,如果成功,则表明VIP切换成功
在192.168.101.252上查看网卡是否绑定VIP,ip a
启动192.168.101.251上keepalived,验证VIP是否切回MASTER主机,配置文件中优先级

可以自己试试 停止keepalived|haproxy|nginx,看看都有什么变化