一.HAproxy的简单介绍
1.HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件;适用于负载大的web站点,这些站点通常又需要会话保持或七层处理。它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上
2.HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接;事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。
3.HAProxy 支持连接拒绝 : 因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害,这也是其他负载均衡没有的优点
4.HAProxy 支持全透明代理(已具备硬件防火墙的典型特点): 可以用客户端IP地址或者任何其他地址来连接后端服务器.
二.HAproxy配置文件详解
1.配置文件主要分为5部分
global:全局变量的参数,属于进程配置,通常与操作有关
defaults:配置默认参数,这些参数可以被用到frontend,backend,Listen组件
frontend:接收请求的前端虚拟节点,Frontend可以更加规则直接指定具体使用后端的backend:后端服务集群的配置,是真实服务器,一个Backend对应一个或者多个实体服务器
Listen :frontend和backend的组合体
2.主配置文件详解
global ##全局参数的设置
log 127.0.0.1 local2
##log语法:log <address_1>[max_level_1] ##全局的日志配置,使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备,记录日志等级为info的日志
user haproxy
group haproxy
##设置运行haproxy的用户和组,也可使用uid,gid关键字替代之
daemon
##以守护进程的方式运行
nbproc 16
##设置haproxy启动时的进程数,根据官方文档的解释,我将其理解为:该值的设置应该和服务器的CPU核心数一致,即常见的2颗8核心CPU的服务器,即共有16核心,则可以将其值设置为:<=16 ,创建多个进程数,可以减少每个进程的任务队列,但是过多的进程数也可能会导致进程的崩溃。这里我设置为16
maxconn 4096
##定义每个haproxy进程的最大连接数 ,由于每个连接包括一个客户端和一个服务器端,所以单个进程的TCP会话最大数目将是该值的两倍。
#ulimit -n 65536
##设置最大打开的文件描述符数,在1.4的官方文档中提示,该值会自动计算,所以不建议进行设置
pidfile /var/run/haproxy.pid
##定义haproxy的pid
defaults # 默认部分的定义
mode http
##mode语法:mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测,返回OK
log 127.0.0.1 local3 err
##使用127.0.0.1上的syslog服务的local3设备记录错误信息
retries 3
##定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
option httplog
##启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[Jan 5 13:23:46] 日志服务器[127.0.0.1] 实例名已经pid[haproxy[25218]] 信息[Proxy http_80_in stopped.]”,日志格式很简单。
option redispatch
##当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
option abortonclose
##当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option dontlognull
##启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
option httpclose
##使用该参数,每处理完一个request时,haproxy都会去检查http头中的Connection的值,如果该值不是close,haproxy将会将其删除,如果该值为空将会添加为:Connection: close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该参数类似的另外一个参数是“option forceclose”,该参数的作用是强制关闭对外的服务通道,因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,如果客户端也不关闭,连接就会一直处于打开,直到超时。
contimeout 5000
##设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout connect替代,该参数向后兼容
clitimeout 3000
##设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用timeout client替代。该参数向后兼容
srvtimeout 3000
##设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用timeout server替代。该参数向后兼容
listen status ##定义一个名为status的部分
bind 0.0.0.0:1080
##定义监听的套接字
mode http
##定义为HTTP模式
log global
##继承global中log的定义
stats refresh 30s
##stats是haproxy的一个统计页面的套接字,该参数设置统计页面的刷新间隔为30s
stats uri /admin?stats
## 设置统计页面的uri为/admin?stats
stats realm Private lands
## 设置统计页面认证时的提示内容
stats auth admin:password
## 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
stats hide-version
## 隐藏统计页面上的haproxy版本信息
frontend http_80_in # 定义一个名为http_80_in的前端部分
bind 0.0.0.0:80
##http_80_in定义前端部分监听的套接字
mode http
## 定义为HTTP模式
log global
## 继承global中log的定义
option forwardfor
## 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
acl static_down nbsrv(static_server) lt 1
## 定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到
acl php_web url_reg /*.php$
#acl php_web path_end .php
## 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,上面两种写法任选其一
acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
#acl static_web path_end .gif .png .jpg .css .js .jpeg
## 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到,上面两种写法任选其一
use_backend php_server if static_down
## 如果满足策略static_down时,就将请求交予backend php_server
use_backend php_server if php_web
## 如果满足策略php_web时,就将请求交予backend php_server
use_backend static_server if static_web
## 如果满足策略static_web时,就将请求交予backend static_server
backend php_server #定义一个名为php_server的后端部分
mode http
## 设置为http模式
balance source
## 设置haproxy的调度算法为源地址hash
cookie SERVERID
## 允许向cookie插入SERVERID,每台服务器的SERVERID可在下面使用cookie关键字定义
option httpchk GET /test/index.php
## 开启对后端服务器的健康检测,通过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 php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup
## server语法:server [: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]
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 3
三.Haproxy的配置
1.HAproxy的环境配置
三台虚拟机:
server1:172.25.4.111 HAproxy主机
server2:172.25.4.112 后端服务器
server3:172.25.4.113 后端服务器
2.HAproxy的安装
(1)安装
[root@server1 ~]# yum install haproxy -y
[root@server1 ~]# systemctl start haproxy
[root@server1 ~]# systemctl status haproxy ##开启状态则正常
(2)查看进程
[root@server1]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2065 0.0 0.1 44172 1676 ? Ss 03:39 0:00 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
haproxy 2066 0.0 0.3 47896 3272 ? S 03:39 0:00 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
haproxy 2067 0.0 0.1 47896 1780 ? Ss 03:39 0:00 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
root 2070 0.0 0.0 0 0 ? S< 03:44 0:00 [kworker/0:0H]
root 2072 0.0 0.1 151056 1828 pts/0 R+ 03:49 0:00 ps aux
由此可知:haproxy有三个进程,1个由root开启,2个由haproxy开启
3.主配置文件的修改
将60-85行注释
[root@server1 ~]# cd /etc/haproxy/
[root@server1 haproxy]# ls
haproxy.cfg
[root@server1 haproxy]# vim haproxy.cfg
[root@server1 haproxy]# systemctl restart haproxy
[root@server1 haproxy]# systemctl status haproxy
##监控的页面
listen admin *:8080
stats enable
stats uri /status ##监控页面的地址
stats auth admin:westos ##监控页面的帐号和密码
stats refresh ##刷新的频率
4.测试haproxy是否可用
浏览器输入:http://172.25.4.111:8080/status
5.haproxy实现负载均衡
(1)开启后端apache服务
[root@server2 ~]# vim /var/www/html/index.html
[root@server2 ~]# systemctl start httpd
[root@server2 ~]# cat /var/www/html/index.html
server2
[root@server3 ~]# vim /var/www/html/index.html
[root@server3 ~]# systemctl start httpd
[root@server3 ~]# cat /var/www/html/index.html
server3
(2)主配置文件的修改
[root@server1 haproxy]# vim haproxy.cfg
[root@server1 haproxy]# systemctl restart haproxy
[root@server1 haproxy]# systemctl status haproxy
listen westos *:80 ##监听的实例名称 地址 端口
balance roundrobin ##负载均衡的算法
server web1 172.25.4.112:80 check
server web2 172.25.4.113:80 check
物理机测试–实现负载均衡
[root@foundation4 kiosk]# curl 172.25.4.111
server2
[root@foundation4 kiosk]# curl 172.25.4.111
server3
[root@foundation4 kiosk]# curl 172.25.4.111
server2
[root@foundation4 kiosk]# curl 172.25.4.111
server3
[root@foundation4 kiosk]# curl 172.25.4.111
server2
[root@foundation4 kiosk]# curl 172.25.4.111
server3
四.HAproxy的动静分离
1.主配置文件的修改
2.服务器的配置
因为此时haproxy也作为一台服务器使用所以需要安装阿帕奇服务
[root@server1 haproxy]# yum install httpd -y
[root@server1 haproxy]# vim /var/www/html/index.html
[root@server1 haproxy]# systemctl restart httpd
[root@server1 haproxy]# cat /var/www/html/index.html
local:server1
[root@server1 haproxy]# vim /etc/httpd/conf/httpd.conf ##更改端口为8000
在静态服务器server3上
[root@server3 html]# mkdir images
[root@server3 html]# cd images
[root@server3 images]# scp root@172.25.4.250:'/home/kiosk/Desktop/1.png' .
[root@server3 images]# ls
1.png
[root@server3 images]# systemctl restart httpd
当浏览器访问:172.25.4.111时
当浏览器访问:172.25.4.111/images时
当两台后端服务器阿帕奇模拟损坏时,访问172.25.4.111
五.HAproxy重定向
1.重定向的分类
重定向分为永久重定向与临时重定向
在许多应用环境中,可能需要将访问的站点请求跳转到指定的站点上,比如客户单端访问xx.a.com需要将请求转发到xx.b.com或将http请求重定向到https请求,又例如当客户端访问出错,我们需要将错误code代码提示请求到指定的错误页面,诸如此类需求实现,就需要利用haproxy的重定向功能来达到此目的
[root@foundation4 kiosk]# curl -I taobao.com
HTTP/1.1 302 Found ##临时重定向
Server: Tengine
Date: Thu, 27 Jun 2019 01:31:55 GMT
Content-Type: text/html
Content-Length: 258
Connection: keep-alive
Location: http://www.taobao.com/
[root@foundation4 kiosk]# curl -I www.taobao.com
HTTP/1.1 301 Moved Permanently ##永久重定向
Server: Tengine
Date: Thu, 27 Jun 2019 01:32:07 GMT
Content-Type: text/html
Content-Length: 278
Connection: keep-alive
Location: https://www.taobao.com/
Via: cache2.cn522[,0]
Timing-Allow-Origin: *
EagleId: 6f14fb4215615991277367997e
2.HAproxy的重定向
(1)配置文件的修改
[root@server1 ~]# vim /etc/haproxy/haproxy.cfg
[root@server1 ~]# systemctl restart haproxy
[root@server1 ~]# systemctl status haproxy
listen admin *:8080
stats enable
stats uri /status
stats auth admin:westos
stats refresh
#listen westos *:80
# balance roundrobin
# server web1 172.25.4.112:80 check
# server web2 172.25.4.113:80 check
frontend main *:80
acl url_static path_beg -i /images
acl url_static path_end -i .jpg .gif .png
acl badhost src 172.25.4.250 ##拒绝172.25.4.250访问
redirect location http://172.25.4.111:8000 if badhost ##当172.25.4.250访问时自动重定向到172.25.4.111的8000端口,不管什么错误均重定向
use_backend static if url_static
default_backend app
backend static
server web2 172.25.4.113:80 check
backend app
server web1 172.25.4.112:80 check
server local 172.25.4.111:8000 backup
(2)开启172.25.4.111的http
[root@server1 ~]# systemctl start httpd
[root@server1 ~]# cat /var/www/html/index.html
sorry!!本站暂时不能访问
(3)172.25.4.250的浏览器访问:172.25.4.111
3.域名访问的重定向
(1)配置文件的修改
[root@server1 ~]# vim /etc/haproxy/haproxy.cfg
frontend main *:80
acl url_static path_beg -i /images
acl url_static path_end -i .jpg .gif .png
acl westos.org hdr_beg(host) -i westos.org
acl 172.25.4.111 hdr_beg(host) -i 172.25.4.111
# acl badhost src 172.25.4.250
# redirect location http://172.25.4.111:8000 if badhost
redirect code 301 location http://www.westos.org if westos.org ##当以westos.org访问时,自动重定向到www.westos.org
redirect code 301 location http://www.westos.org if 172.25.4.111 ##当以172.25.4.111访问时重定向为www.westos.org
use_backend static if url_static
default_backend app ##默认为app动态
backend static
server web2 172.25.4.113:80 check
backend app
server web1 172.25.4.112:80 check
# server local 172.25.4.111:8000 backup
[root@server1 ~]# systemctl restart haproxy
(2)浏览器访问:westos.org
六.HAproxy的读写分离
1.后端服务器的配置
在静态服务器端将要读的文件放在共享目录中
[root@server3 ~]# cd /var/www/html
[root@server3 html]# ls
images index.html
[root@server3 html]# cd images/
[root@server3 images]# ls
1.png
两个后端服务器安装php,准备一个目录upload,里面有着关于上传图片的配置脚本
[root@server2 html]# yum install php -y
[root@server2 html]# scp -r root@172.25.4.250:/home/kiosk/Desktop/upload .
[root@server2 html]# ls
index.html upload
[root@server2 html]# chmod 777 upload/* ##给与满权限任何人可写
[root@server2 html]# mv upload/* .
[root@server2 html]# ls
index.html index.php upload upload_file.php
[root@server2 html]# vim upload_file.php
?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 200000)) ##上传文件大小限制为2M
[root@server2 html]# systemctl restart httpd
[root@server3 html]# yum install php -y
[root@server3 html]# scp -r root@172.25.4.250:/home/kiosk/Desktop/upload .
[root@server3 html]# ls
index.html upload
[root@server3 html]# chmod 777 upload/* ##给与满权限任何人可写
[root@server3 html]# mv upload/* .
[root@server3 html]# ls
index.html index.php upload upload_file.php
[root@server3 html]# vim upload_file.php
?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 200000)) ##上传文件大小限制为2M
[root@server3 html]# systemctl restart httpd
2.主配置文件的修改
frontend main *:80
acl url_static path_beg -i /images
acl url_static path_end -i .jpg .gif .png
acl read method GET
acl read method HEAD
acl write method PUT
acl write method POST
# acl badhost src 172.25.4.250
# redirect location http://172.25.4.111:8000 if badhost
use_backend app if write
default_backend static
backend static
server web2 172.25.4.113:80 check
backend app
server web1 172.25.4.112:80 check
server local 172.25.4.111:8000 backup
3.浏览器测试
当访问172.25.4.111/images/1.png时,自动转到172.25.4.113上读取图片
当访问172.25.4.111时