Haproxy做7层负载均衡+动静分离

什么是四层负载均衡和七层负载均衡?

四层

所谓的四层就是ISO参考模型中的第四层。四层负载均衡也称为四层交换机,它主要是 通过分析IP层及TCP/UDP层的流量实现的基于IP加端口的负载均衡。常见的基于四层的负载均衡器有LVS、F5等。

以常见的TCP应用为例,负载均衡器在接收到第一个来自客户端的SYN请求时,会通过设定的负载均衡算法选择一个最佳的后端服务器,同时将报文中目标IP地址修改为后端服务器IP,然后直接转发给该后端服务器,这样一个负载均衡请求就完成了。

从这个过程来看,一个TCP连接是客户端和服务器直接建立的,而负载均衡器只不过完成了一个类似路由器的转发动作。在某些负载均衡策略中,为保证后端服务器返回的报文可以正确传递给负载均衡器,在转发报文的同时可能还会对报文原来的源地址进行修改。

七层

同理,七层负载均衡器也称为七层交换机,位于 OSI 的最高层,即应用层,此时负载均衡器支持多种应用协议,常见的有 HTTP、FTP、SMTP 等。七层负载均衡器可以根据报文内容,再配合负载均衡算法来选择后端服务器,因此也称为“内容交换器”。

比如,对于 Web 服务器的负载均衡,七层负载均衡器不但可以根据“IP+端口”的方式进行负载分流,还可以根据网站的 URL、访问域名、浏览器类别、语言等决定负载均衡的策略。

例如,有两台 Web 服务器分别对应中英文两个网站,两个域名分别是 A、B,要实现访问 A 域名时进入中文网站,访问 B 域名时进入英文网站,这在四层负载均衡器中几乎是无法实现的,而七层负 载均衡可以根据客户端访问域名的不同选择对应的网页进行负载均衡处理。


  
常见的七层负载均衡器有 HAproxy、Nginx 等。


HAProxy支持两种主要的代理模式:

1. TCP 即4层 (大多用于邮件服务器、内部协议通信服务器等)。在4层模式 下,HAProxy仅在客户端和服务器之间转发双向流量。

  

2. HTTP 即7层模式,HAProxy会分析协议,并且能通过允许、拒绝、交换、增加、修改或者***请求 (request)或者回应(response)里指定内容来控制协议,
  • 这种操作要基于特定规则。(新的1.3之后的版本引入了frontend,backend指令;frontend根据任意HTTP请求头内容做规则匹配,然后把请求定向到相关的backend.)

Haproxy概述:

  • Haproxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,他是免费、快速并可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。

  • Haproxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。Haproxy运行在当前的硬件上,完全可以支持数以万计的并发链接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。

  • 其支持从4层到7层的网络交换,即覆盖所有的TCP协议。就是说,Haproxy甚至还支持MySQL的负载均衡。

相同点:

  • 在功能上,Haproxy通过反向代理方式实现web负载均衡。和Nginx、ApacheProxy、lighttpd、Cheroke等一样。

不同点:

  • Haproxy并不是http服务器,以上提到所有带反向代理负载均衡的产品,都清一色是web服务器,简单说,就是他们能自己提供静态(html,jpg,gif……)或动态(php,cgi…..)文件的传输以及处理。而Haproxy仅仅,而且专门是一款用于负载均衡的应用代理,其自身并不能提供http服务。但其配置简单,拥有非常不错的服务器健康检查功能还有专门的系统状态监控页面,当其代理的后端服务器出现故障,Haproxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。

那是不是Haproxy就能取代Nginx了呢

  • 答案当然是不行,首先Haproxy不是web服务器,当然取代不了Nginx,其次是Nginx的缓存就是Haproxy所不具备的。Haproxy在负载均衡和动静分离方面,确实比Nginx更专业一些,比如session保持,cookie引导,url监测后端,MySQL负载均衡等,都是Nginx所不具备的。只能说各有各的优缺点,选择使用上,自己把握即可。

Haproxy官网:

1
2
http://www.haproxy.org/    (打不开,需要翻墙)
https://www.haproxy.com/ (收费)
  • 已经被墙了,无法进入官网下载源码包,我已经在官网提前下好了源码包,如果无法翻墙,以下网页也可以下载,但是不建议生产环境下去这下载(想办法翻墙去官网下吧)

  • http://pkgs.fedoraproject.org/repo/pkgs/haproxy/

动静分离拓扑:

Psekxe.png

  • 那本节我们要做的是动静分离+负载均衡,这个拓扑就不是那么全了,上边图只是为了更形象的说明动静分离的原理,那再多个负载均衡又是怎样的呢,顾名思义,就在后端服务器池中多添加3台服务器,各自两两做负载呗。

动静分离+负载均衡拓扑:

Pse8MQ.png

  • 实验环境:
1
2
3
4
5
客户端:			    192.168.10.27
Haproxy: 192.168.10.20
Static server: 192.168.10.21、192.168.10.22
Php server: 192.168.10.23、192.168.10.24
Tomcat server: 192.168.10.25、192.168.10.26
  • 说明:
1
2
3
1.	总的实验环境如上图,一台客户端PC机,7台服务器。
2. 环境搭建的话这里不再多说,因为之前已经有写过LNMP、LAMP环境的搭建了
3. Static server静态页面服务器只安装nginx就行。Php server动态页面服务器要安装nginx+php,或者也可以使用Apache。Tomcat server其它页面服务器,比如.jsp,安装nginx就行,其实是要安装tomcat,但是笔者没有tomcat的快照,所以就使用nginx了,能看到实验效果就行, Haproxy安装centos6.5的干净系统即可。
  • 思路:
  • 当客户端访问Haproxy时,请求的是静态文件内容时,请求转交给static server,请求的是php内容时,请求转交给php server,请求的是jsp内容时,请求转交给tomcat server,以实现动静分离

一、Haproxy端部署:

1
2
mkdir -p /a01/apps/apps_src
cd /a01/apps/apps_src/
1. 解压:
1
2
tar -zxvf haproxy-1.7.9.tar.gz
cd haproxy-1.7.9
  • 注意: 这里不和别的源码包一样,没有./configure,而是直接make,可以make指定参数,也可以修改Makefile文件。

2. 查看内核参数:
1
2
uname -r
2.6.32-431.el6.x86_64
  • 安装方法一:
1
make TARGET=linux26 PREFIX=/a01/apps/haproxy && echo $?
  • 安装方法二:
1
vim Makefile

PseJqs.png

1
2
3
4
参数说明:
1、上图中的linux22等参数为linux内核参数,比如这台机器内核为2.6.32-431.el6.x86_64,那对应的就是linux26的,然后下边的TARGET写上TARGET = linux26即可,generic为通用。

2、还有PREFIX = /usr/local这个参数,改成自己想要的安装路径即可,比如本例的PREFIX = /a01/apps/haproxy
3. make install安装:
1
make install PREFIX=/a01/apps/haproxy && echo $?
  • (如果没有修改Makefile配置文件中的PREFIX变量的值,就必须在此重新对PREFIX重新赋值,否则直接make install会直接读取Makefile文件中的PREFIX的变量值)
4. 查看一下生成了什么:
1
ls /a01/apps/haproxy/

PseNaq.png

5. 创建软链接:
1
ln -s /a01/apps/haproxy/sbin/haproxy /usr/local/sbin/
6. 配置全局变量:
1
2
echo "PATH=$PATH:/a01/apps/haproxy/sbin" >> /etc/profile
source /etc/profile
7. 查看Haproxy版本:
1
haproxy -v

PsewGT.png

8. 创建Haproxy用户:
1
useradd -M -s /sbin/nologin haproxy
9. 配置Haproxy服务启动文件:
1
2
cp /a01/apps/apps_src/haproxy-1.7.9/examples/haproxy.init /etc/init.d/haproxy
chmod 755 /etc/init.d/haproxy
10. Haproxy加入系统服务开机自启:
1
2
chkconfig --add haproxy
chkconfig haproxy on
11. 手动编写Haproxy配置文件:
1
2
mkdir -p /etc/haproxy
vim /etc/haproxy/haproxy.cfg

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
global
log 127.0.0.1 local0
maxconn 204800
chroot /a01/apps/haproxy
user haproxy
group haproxy
daemon
nbproc 1
pidfile /var/run/haproxy.pid
stats socket /a01/apps/haproxy/stats
description haproxy server

defaults
log global
log 127.0.0.1 local3
mode http
maxconn 10000
option httplog
option httpclose
option dontlognull
option forwardfor except 127.0.0.0/8
retries 3
option redispatch
option abortonclose
balance roundrobin
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s

frontend Mr_nong
bind *:80
maxconn 5000
mode http
log global
option httplog
option httpclose
option forwardfor
default_backend php_pool
acl url_static path_beg -i /static /images /img /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html
acl host_static hdr_beg(host) -i img. video. download. ftp. imags. videos.
acl url_php path_end -i .php
acl url_jsp path_end -i .jsp .do
use_backend static_pool if url_static or host_static
use_backend php_pool if url_php
use_backend tomcat_pool if url_jsp


backend static_pool
option httpchk GET /index.html
balance roundrobin
server static1 192.168.10.21:80 check inter 2000 rise 2 fall 3 weight 1
server static2 192.168.10.22:80 check inter 2000 rise 2 fall 3 weight 1


backend php_pool
option httpchk GET /index.php
balance roundrobin
server static1 192.168.10.23:80 check inter 2000 rise 2 fall 3 weight 1
server static2 192.168.10.24:80 check inter 2000 rise 2 fall 3 weight 1


backend tomcat_pool
option httpchk GET /index.jsp
balance roundrobin
server static1 192.168.10.25:80 check inter 2000 rise 2 fall 3 weight 1
server static2 192.168.10.26:80 check inter 2000 rise 2 fall 3 weight 1

listen admin_stats
bind *:9188
mode http
log 127.0.0.1 local3 err
stats refresh 60s
stats uri /haproxy_status
stats realm welcome login\ Haproxy
stats auth nong:123456
stats hide-version
stats admin if TRUE

12. 启动Haproxy:
1
service haproxy start

Pse0RU.png

13. 报错了,我们去修改一下这些变量:
1
vim /etc/init.d/haproxy

PsessJ.png

  • 修改为:

PseyL9.png

  • 重新启动一下试试:

Pse2Ix.png

  • 报别的错了,看这情况应该是配置文件写错了……

PsefJK.png

  • 单词写错了,应该是stats

PseIQe.png

  • 应该写成nbproc 1

PseosH.png

  • 单词写错,符号写错….应该为bind *:9188

PseTLd.png

  • 符号写错,应该为*:80
  • 都修改完成之后启动一下:
1
service haproxy start

PsebdI.png

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
92
93
94
global		全局参数,以全局定义为主
defaults 默认参数,在全局的前提下,默认跟局部的配置,如果局部没说,那就按默认走,如果局部有定义,那就按局部走,意思是可以被frontend、backend、listen段继承使用
frontend 前端参数,监听地址,监听端口,该如何处理(转发)…….
backend 后端服务器,定义哪些真正处理业务的服务器
listen 将frontend和backend整合的一种方案

HAProxy负载均衡器算法
    roundrobin,表示简单的轮询,基于权重负载均衡基础算法(支持慢速启动,运行时调整)
    static-rr,表示根据权重
    leastconn,表示最少连接者先处理(不适用web)
    source,表示根据请求源IP(会话保持,此方法动静还要取决于hash-type,map-based静态,consistent动态)
    uri,表示根据请求的URI;(用于缓存服务器)
    url_param,表示根据请求的URl参数来进行调度
    hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
    rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

maxconn 204800 #定义每个haproxy进程的最大连接数
chroot /a01/apps/haproxy #haproxy主目录
user haproxy #haproxy运行用户
group haproxy #haproxy运行组
daemon #以守护进程的方式运行
nbproc 1 #设置haproxy启动时的进程数,该值应设置为服务器的cpu线程数,但是大于16则不能提高太多,建议<=16
mode http #mode语法:mode {http|tcp|health}。http是七层模式,tcp是四层模式,health是健康检测。
option httplog #启用日志记录http请求,默认haproxy日志是不记录http请求的,只记录“时间[Jan 5 13:23:46] 日志服务器[127.0.0.1]”
option httpclose #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式来实现
option dontlognull #不记录空链接产生的日志
option forwardfor except 127.0.0.0/8 #如果后端服务器需要获得客户端真是ip需要配置的参数,可以从Http Header中获得客户端ip
retries 3 #3次连接失败就认为后端服务器不可用
option redispatch #当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的连接
balance roundrobin #负载均衡算法

#定义前端部分,规则,如何转发等等……
frontend Mr_nong
bind *:80
maxconn 5000
mode http
log global
option httplog
option httpclose
option forwardfor
default_backend php_pool #没有任何匹配的情况下,默认指定后端服务器的php_pool

#定义当请求的内容是静态内容时,将请求转交给static server的acl规则
acl url_static path_beg -i /static /images /img /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html
acl host_static hdr_beg(host) -i img. video. download. ftp. imags. videos.

#定义当请求的内容是php内容时,将请求转发给php server的acl规则
acl url_php path_end -i .php

#定义当请求的内容是.jsp或.do内容时,将请求转发给tomcat server的acl规则
acl url_jsp path_end -i .jsp .do

#引用上边的acl规则
use_backend static_pool if url_static or host_static
use_backend php_pool if url_php
use_backend tomcat_pool if url_jsp

listen admin_stats #定义Haproxy监控页面
bind *:9188
mode http
log 127.0.0.1 local3 err
stats refresh 60s #Haproxy监控页面统计自动刷新书剑
stats uri /haproxy_status #设置监控页面URL路径,可通过http://IP:9188/haproxy_status来访问
stats realm welcome login\ Haproxy #统计页面密码框提示信息
stats auth nong:123456 #登录统计页面用户和密码
stats hide-version #隐藏Haproxy版本信息
stats admin if TRUE #设置TRUE后可在监控页面手工启动关闭后端真实服务器

#定义后端的服务器池
backend static_pool
option httpchk GET /index.html #开启对后端服务器的健康检测,通过GET /index.html这个页面来判断后端服务器的健康情况,实际工作中测试时,应该下载某一个页面来进行测试,因为这个页面应该是个小页面,而不要用首页,这里是每隔一秒检查一次页面。
balance roundrobin
server static1 192.168.10.21:80 check inter 2000 rise 2 fall 3 weight 1
server static2 192.168.10.22:80 check inter 2000 rise 2 fall 3 weight 1

backend php_pool
option httpchk GET /index.php
balance roundrobin
server static1 192.168.10.23:80 check inter 2000 rise 2 fall 3 weight 1
server static2 192.168.10.24:80 check inter 2000 rise 2 fall 3 weight 1
#balance roundrobin负载均衡算法
#check启用后端执行健康检测
#inter 2000健康状态检测时间间隔
#rise 2 从故障状态转换至正常状态需要成功检测次数
#fall 3 从正常状态转换至故障需要失败检测次数
#weight 1 权重

backend tomcat_pool
option httpchk GET /index.jsp
balance roundrobin
server static1 192.168.10.25:80 check inter 2000 rise 2 fall 3 weight 1
server static2 192.168.10.26:80 check inter 2000 rise 2 fall 3 weight 1

二、后端服务器部署:

static_pool部署:

1
2
rm -rf /a01/apps/nginx/html/*
vim /a01/apps/nginx/html/index.html
1
This is 192.168.10.21 static_pool

Pseqot.png

1
2
rm -rf /a01/apps/nginx/html/*
vim /a01/apps/nginx/html/index.html
1
This is 192.168.10.22 static_pool

PseXJf.png

php_pool部署:

1
2
rm -rf /a01/apps/nginx/html/*
vim /a01/apps/nginx/html/index.php
1
2
3
4
5
6
7
8
This is 192.168.10.23 php_pool


<?php

phpinfo();

?>

PsejW8.png

1
2
rm -rf /a01/apps/nginx/html/*
vim /a01/apps/nginx/html/index.php
1
2
3
4
5
6
7
This is 192.168.10.24php_pool

<?php

phpinfo();

?>

PsexSS.png

tomcat_pool部署:

1
2
rm -rf /a01/apps/nginx/html/*
vim /a01/apps/nginx/html/index.jsp
1
This is 192.168.10.25 tomcat_pool

PsezQg.png

1
2
rm -rf /a01/apps/nginx/html/*
vim /a01/apps/nginx/html/index.jsp
1
This is 192.168.10.26 tomcat_pool

PsmSyQ.png

三、测试

1. 静态页面转到192.168.20.21和192.168.10.22服务器处理

PsmPwn.png

Psmioq.png

2. 动态页面转到192.169.10.23和192.168.10.24服务器处理

PsmkF0.png

PsmEWT.png

3. jsp页面转到192.168.10.25和192.168.10.26服务器处理

PsmZSU.png

PsmelF.png

4. 访问Haproxy健康检测页面

Psmmy4.png

四、配置Haproxy日志收集

  • Haproxy通过rsyslog来收集日志,我们需要去配置一下开启udp514的日志收集
1
2
3
4
vim /etc/rsyslog.conf
取消注释:
$ModLoad imudp
$UDPServerRun 514

PsmnOJ.png

  • 新增以下两行:
1
2
local3.*                                                /var/log/haproxy.log
local0.* /var/log/haproxy.log

Psm1Fx.png

  • local3和local0是我们在配置文件中定义的日志,可以看看:

Psm8fK.png

  • 重启rsyslog服务:
    service rsyslog restart

PsmJSO.png

  • 我们去动态查看一下Haproxy的日志:
1
tail -f /var/log/haproxy.log

PsmNOH.png

Psmamd.png

Psmd0A.png

PsmBkt.png

  • 我记得在配置文件中我们设置了,如果访问的内容匹配不到acl,不知道分配给哪台服务器,则默认分配给php_pool的服务器,接下来我们来访问一个没有的页面,看看Haproxy到底是不是默认给我们分配到php_pool的服务器

PsmDtP.png

博主QQ:1012405802
技术交流QQ群:830339411
版权声明:网站内容有原创和转载,如有侵权,请联系删除,谢谢!!
感谢打赏,93bok因你们而精彩!!(支付宝支持花呗)
0%