重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
HAproxy
专注于为中小企业提供成都网站设计、成都网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业富阳免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上1000家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
LB Cluster (负载均衡 集群)
四层
lvs、nginx(stream模块)、haproxy
七层
http:nginx(http、ngx_http_upstream)、haproxy(mode http),httpd,ats、perlbal,pound
官方文档:http://cbonte.github.io/haproxy-dconv/
使用yum安装 haproxy 光盘收录的版本即可
以HAProxy 1.5为例
主程序:/usr/sbin/haproxy
主配置文件:/etc/haproxy/haproxy.cfg
配置端分为2段·
global:全局配置段
进程及安全配置相关的参数
性能调整相关参数
Debug参数
proxies:代理配置段
default:frontend,listen,backend提供默认配置:
其中
frontend:前端,相当于nginx,server{ }
backend:后端,相当于nginx,upstream { }
listen: 同时用于前端和后端
实现1.1使用haproxy配制简单的负载均衡集群
这里使用三台主机
172.18.10.10,使用yum安装httpd,并配置基本网页内容,启动httpd服务
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# vim /var/www/html/index.html
root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 100 127.0.0.1:25
172.18.10.11,使用yum安装httpd,并配置基本网页内容,启动httpd服务
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# vim /var/www/html/index.html
root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 100 127.0.0.1:25
172.18.200.100,使用yum安装haproxy,编辑haproxy.cfg文件
[root@localhost haproxy]# vim haproxy.cfg
将frontend断和backend段做如下修改
frontend web
bind *:80
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 172.18.10.10:80 check
server srv2 172.18.10.11:80 check
启动haproxy服务
[root@localhost haproxy]# service haproxy start
使用curl命令访问测试
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100;done
结论,实现haproxy简单的LB Cluster。调度规则默认为rr(轮询)调度
实验1.2在原来基础上添加MySQL服务,并实现负载均衡调度
首先在两台后端backend服务器上安装mysql,并启动服务,配置mysql相关参数,测试mysql链接是否正常
[root@BYQ ~]#service mysqld start
Starting mysqld: [ OK ]
mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> grant all on mydb.* to 'test'@'%' identified by 'testpass';
Query OK, 0 rows affected (0.00 sec)
在客户端主机上测试mysql的的链接是否正常
[root@localhost ~]# mysql -utest -ptestpass -h272.18.10.10
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.1.73 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
[root@localhost ~]# mysql -utest -ptestpass -h272.18.10.11
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.1.73 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
两台后端主机mysql连接均正常
接下来在haproxy服务器端进行配置
[root@localhost ~]# cd /etc/haproxy/
[root@localhost haproxy]# ls
haproxy.cfg haproxy.cfg.bak
[root@localhost haproxy]# cp haproxy.cfg{,.web}
[root@localhost haproxy]# ls
haproxy.cfg haproxy.cfg.bak haproxy.cfg.web
[root@localhost haproxy]# vim haproxy.cfg
frontend web
mode tcp
bind *:3306
default_backend websrvs
backend websrvs
balance leastconn
server mysql1 172.18.10.10:3306 check
server mysql2 172.18.10.11:3306 check
简单配置完毕
实验1.3配置haproxy rslog
[root@localhost ~]# vim /etc/rsyslog.conf
# Save boot messages also to boot.log
local7.* /var/log/boot.log
local2.* /var/log/haproxy.log
# Provides UDP syslog reception ##表示载入UDP模式,并监听在514端口
$ModLoad imudp
$UDPServerRun 514
保存退出并重启动rsyslog服务,查看日志监听端口是否启动
[root@localhost ~]# service rsyslog restart
Shutting down system logger: [ OK ]
Starting system logger: [ OK ]
[root@localhost ~]# ss -unl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 *:514 *:*
UNCONN 0 0 *:57263 *:*
UNCONN 0 0 :::514 :::*
实验1.4配置source算法实现hash-type绑定
编辑haproxy.cfg,更改添加如下配置
backend websrvs
balance source
server srv1 172.18.10.10:80 check
server srv2 172.18.10.11:80 check
hash-type map-based
重启服务
[root@localhost haproxy]# service haproxy restart
Stopping haproxy: [ OK ]
Starting haproxy: [ OK ]
在客户端测试
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100;done
实验1.5配置uri算法提高命中。绑定一致性hash consistent
编辑haproxy.cfg文件
backend websrvs
balance uri
server srv1 172.18.10.10:80 check
server srv2 172.18.10.11:80 check
hash-type consistent
保存退出重启服务,结论不管哪台服务器,只要uri相同,便访问同一个后端主机,若uri不同也另当别论
例如随机在两台后端主机生成20个页面文件
[root@localhost ~]# for i in {1..20};do echo "Test Page $i (BE 1)" > /var/www/html/test$i.html;done
[root@localhost ~]# for i in {1..20};do echo "Test Page $i (BE 2)" > /var/www/html/test$i.html;done
在客户端请求,则发现test1在BE1,而test2在BE2
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100/test1.html;done
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
Test Page 1 (BE 1)
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100/test2.html;done
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
Test Page 2 (BE 1)
因此得出结论和绑定的客户端没关系,只和绑定的uri有关系,因此能够极大的提高缓存命中率
实验1.6采用roundrobin调度规则,且增加权重 进行测试
编辑haproxy.cfg
backend websrvs
balance roundrobin
server srv1 172.18.10.10:80 check weigth 2
server srv2 172.18.10.11:80 check weigth 1
hash-type consistent
保存并退出
重启服务
[root@localhost haproxy]# service haproxy restart
Stopping haproxy: [ OK ]
Starting haproxy: [ OK ]
在客户端访问同一个URL
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100/test5.html;done
Test Page 5 (BE 2)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 2)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 2)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 2)
将其中一个服务器下线,等3秒 实现fall (默认三秒)
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100/test5.html;done
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
再将下线的服务器上线,等2秒,实现rise (默认两秒)恢复轮询
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100/test5.html;done
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 2)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 2)
Test Page 5 (BE 1)
Test Page 5 (BE 1)
Test Page 5 (BE 2)
Test Page 5 (BE 1)
结论:实现健康状态检查
也可以自己设置 check inter(时间间隔) rise 次数 fall 次数 和 maxconn(最大并发连接数)、 以及backlog(后援队列不指定值的话,就用maxconn的值代替),如下所示
backend websrvs
balance roundrobin
server srv1 172.18.10.10:80 check inter 1000 rise 1 fall 2 maxconn 2000 weight 2
server srv2 172.18.10.11:80 check weight 1
hash-type consistent
实验1.7,将第一个后端主机标记为backup或者disabled,在第二个后端主机上使用redir重定向到百度的url上去
backend websrvs
balance roundrobin
server srv1 172.18.10.10:80 check inter 1000 rise 1 fall 2 maxconn 2000 weight 2 disabled
server srv2 172.18.10.11:80 check weight 1 redir http://www.baidu.com/
hash-type consistent
访问172.18.200.100.页面跳转至百度主页
实验1.8 开启haproxy stats 页面,并且调试各参数
开启stats页面,在backend 配置段添加 stats enable
backend websrvs
balance roundrobin
server srv1 172.18.10.10:80 check inter 1000 rise 1 fall 2 maxconn 2000 weight 2 backup
server srv2 172.18.10.11:80 check weight 1 redir http://www.baidu.com/
hash-type consistent
stats enable
重启服务
这样便开启了stats页面
其中stats页面是有默认值的,默认值如下
- stats uri : /haproxy?stats
- stats realm : "HAProxy Statistics"
- stats auth : no authentication
- stats scope : no restriction
在浏览器输入http://172.18.200.100/haproxy?stats,则登录状态页面显示
修改stats uri的默认值
frontend web
bind *:80
default_backend websrvs
stats enable
stats uri /haadim?admin
backend websrvs
balance roundrobin
server srv1 172.18.10.10:80 check inter 1000 rise 1 fall 2 maxconn 2000 weight 2
server srv2 172.18.10.11:80 check weight 1
hash-type consistent
保存退出重启服务
在浏览器输入http://172.18.200.100/haadmin?admin,才能再次显示状态页面
实验1.9 为stats页面添加用户名密码访问认证
frontend web
bind *:80
default_backend websrvs
stats enable
stats uri /haadmin?admin
stats realm "Stats\ Web" ##(提示标题)
stats auth admin1:admin1
stats auth admin2:admin2
stats auth admin3:admin3
保存退出并重启服务
在浏览器输入http://172.18.200.100/haadmin?admin,需要输入用户名和密码才能使用
而且可以启用登录用户管理
frontend web
bind *:80
default_backend websrvs
stats enable
stats uri /haadmin?admin
stats realm "Stats\ Web"
stats auth admin1:admin1
stats auth admin2:admin2
stats auth admin3:admin3
stats admin if TRUE
表示如果验证成功,就可以一直设置相应的参数
保存,并且退出
重启haproxy服务
刷新刚才的页面,则会现在后端的模块下面显示可操作的会话框
Choose the action to perform on the checked servers : Apply
在Apply的下拉框中会有许多选项,可以控制后端的服务器状态
也可以直接专门定义一个端口,让stats监听在一个端口上,以后只能通过该端口访问stats页面
frontend web
bind *:80
default_backend websrvs
listen stats :10086
stats enable
stats uri /haadmin?admin
stats realm "Stats\ Web"
stats auth admin1:admin1
stats auth admin2:admin2
stats auth admin3:admin3
stats admin if TRUE
在浏览器输入http://172.18.200.100:10086/haadmin?admin 通过用户验证,访问
还可以隐藏haproxy版本信息
stats hide-version
还可以自动刷新,以及显示具体信息
stats refresh
stats show-desc
stats show-legends
stats show-node
实验2.0,显示前端最大连接数maxconn
frontend web
bind *:80
maxconn 4000
default_backend websrvs
实验2.1,代理ssh服务 实现mode tcp模式的验证
backend app
balance roundrobin
server app1 127.0.0.1:5001 check
server app2 127.0.0.1:5002 check
server app3 127.0.0.1:5003 check
server app4 127.0.0.1:5004 check
listen sshsrvs :10088
mode tcp
maxconn 20
balance leastconn
server sshsrv1 172.18.10.10:22 check
server sshsrv2 172.18.10.11:22 check
在客户端使用[root@localhost ~]# ssh -p 10088 root@172.18.200.100
刷新页面
发现在页面中sshsrvs栏中,sshsrv1页面有连接处理显示,说明代理成功
实验2.2,代理mysql,实现mode tcp模式的验证
listen sshsrvs :3306
mode tcp
maxconn 20
balance leastconn
server sshsrv1 172.18.10.10:3306 check
server sshsrv2 172.18.10.11:3306 check
查看端口是否监听
[root@localhost haproxy]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:10086 *:*
LISTEN 0 20 *:3306 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 100 127.0.0.1:25
在客户端测试连接mysql
[root@localhost ~]# mysql -utest -ptestpass -h272.18.200.100
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.1.73 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
结论:代理成功 ,实现mode tcp模式的验证
实验2.3 实现基于ookie的粘性处理,即基于cookie的session sticky的实现:
backend websrvs
balance roundrobin
cookie WEBSRV insert nocache indirect
server srv1 172.18.10.10:80 check cookie web1
server srv2 172.18.10.11:80 check cookie web2
hash-type consistent
使用浏览器访问http://172.18.200.100/,开启F12,查看浏览器记录的Request Headers,如下
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,p_w_picpath/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
Authorization:Basic YWRtaW4zOmFkbWluMw==
Cache-Control:max-age=0
Connection:keep-alive
Cookie:WEBSRV=web1
Host:172.18.200.100
If-Modified-Since:Wed, 03 May 2017 06:23:57 GMT
If-None-Match:"1e0599-27-54e98b3828057"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
可以看出Cookie:WEBSRV=web1,已经基于cookie黏性绑定web1服务器,因此再次不敢访问多少次都是web1
实验2.4 实现option forward发往后端主机的请求报文中添加“X-Forwarded-For”首部
首先进入后端服务器,修改httpd关于日志段的配置
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
从启httpd服务,再次在客户端访问
[root@localhost ~]# for i in {1..10};do curl http://172.18.200.100/index.html;done
并查看访问日志,
[root@localhost ~]# tail /var/log/httpd/access_log
172.18.249.57 - - [10/May/2017:08:08:22 +0800] "GET /index.html HTTP/1.1" 200 39 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh3/1.4.2"
172.18.249.57 - - [10/May/2017:08:08:22 +0800] "GET /index.html HTTP/1.1" 200 39 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh3/1.4.2"
则在日志中会显示真实访问的客户端地址
实验2.5 实现rspadd
frontend web
bind *:80
rsadd X-Via:\ HAProxy
maxconn 4000
default_backend websrvs
从启haproxy服务
刷新浏览器
在响应报文首部发现添加的指定首部
Response Headers
Date:Wed, 03 May 2017 16:24:04 GMT
ETag:"1e0599-27-54e98b3828057"
Server:Apache/2.2.15 (CentOS)
Vary:Accept-Encoding
X-Via:HAProxy
实验2.6 实现rspidel
frontend web
bind *:80
rspadd X-Via:\ HAProxy
rspidel Server.*
maxconn 4000
default_backend websrvs
Date:Wed, 03 May 2017 16:28:59 GMT
ETag:"1e0599-27-54e98b3828057"
Vary:Accept-Encoding
X-Via:HAProxy
对比之前,server已经被删除
实验2.7 log
[root@localhost haproxy]# tail /var/log/haproxy.log
May 10 12:46:47 localhost haproxy[6628]: 172.18.254.240:59220 [10/May/2017:12:46:47.769] web websrvs/srv1 0/0/0/1/1 304 173 - - --VN 1/1/0/1/0 0/0 "GET / HTTP/1.1"
实验2.8 实现内容 类型压缩compression
frontend web
bind *:80
rspadd X-Via:\ HAProxy
rspidel Server.*
maxconn 4000
default_backend websrvs
compression type text/html
compression algo gzip
浏览器访问http://172.18.200.100/test12.html
在响应报文首部response headers
Accept-Ranges:bytes
Content-Encoding:gzip
Content-Length:40
Content-Type:text/html; charset=UTF-8
Date:Wed, 03 May 2017 16:46:10 GMT
ETag:"1e059d-14-54e9c272c1b5f"
Last-Modified:Wed, 03 May 2017 10:31:02 GMT
Vary:Accept-Encoding
X-Via:HAProxy
发现内容压缩,且格式为gzip
实验2.9 对后端服务器http协议的健康状态监测
backend websrvs
balance roundrobin
cookie WEBSRV insert nocache indirect
server srv1 172.18.10.10:80 check cookie web1
server srv2 172.18.10.11:80 check cookie web2
option httpchk /test20.html
hash-type consistent
在stats页面可以查看,正常通过检测
实验3.0 http-check检测
backend websrvs
balance roundrobin
cookie WEBSRV insert nocache indirect
server srv1 172.18.10.10:80 check cookie web1
server srv2 172.18.10.11:80 check cookie web2
option httpchk /test20.html
http-check expect rstatus ^2
hash-type consistent
在stats页面可以查看,正常通过检测
实验3.1 实现基于acl的各种访问控制
acl只检查不控制,控制还需其他条件实现
acl要先配置,再调用
frontend web
acl invalid_src src 172.18.254.240
block if invalid_src
保存退出重启服务,使用浏览器访问http://172.18.200.100/
403 Forbidden
Request forbidden by administrative rules.
客户端地址正好为172.18.254.240,因此访问被拒绝
而且403页面可以重定向到我们自己定义的错误页面去,操作如下
[root@localhost haproxy]# mkdir /etc/haproxy/errorfiles
[root@localhost haproxy]# vim /etc/haproxy/errorfiles/403.html
编辑haproxy配置文件
frontend web
acl invalid_src src 172.18.254.240
block if invalid_src
errorfile 403 /etc/haproxy/errorfiles/403.html
保存退出,并重启haproxy服务
使用浏览器访问http://172.18.200.100/,显示内容如下
OoOo,VIP Source
或者使用errorloc重定向uri到百度
frontend web
acl invalid_src src 172.18.254.240
block if invalid_src
errorloc 403 http://www.baidu.com
使用浏览器访问http://172.18.200.100/,显示内容如下
百度主页。。。。。
如果acl是 curl_agent,则使用如下的服务器172.18.10.11:8080
frontend web
acl invalid_src src 172.18.254.240
block if invalid_src
errorloc 403 http://www.baidu.com
acl curl_agent hdr_sub(User-Agent) -i curl
use_backend curlbe if curl_agent
bind *:80
rspadd X-Via:\ HAProxy
rspidel Server.*
maxconn 4000
default_backend websrvs
compression type text/html
compression algo gzip
backend curlbe
balance roundrobin
server curlsrv1 172.18.249.57:80 check
并在后端172.18.249.57上开启80端口
[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
[root@localhost ~]# service httpd restart
打开浏览器,出输入http://172.18.200.100:10086/haadmin?admin,输入用户名和密码验证
发现curlbe模块正常运行,并且通过四层检测
使用curl命令
[root@localhost ~]# curl http://172.18.249.57
实验3.2实现简单的动静分离
在172.18.249.57端。使用yum安装php
在将编辑index.php页面
phpinfo();
?>
使用浏览侧访问测试页面,成功显示php信息
在haproxy端配置haproxy.cfg文件。添加如下内容
frontend web
# acl invalid_src src 172.18.254.240
# block if invalid_src
errorloc 403 http://www.baidu.com
# acl curl_agent hdr_sub(User-Agent) -i curl
# use_backend curlbe if curl_agent
acl phpapp path_end -i .php ##定义acl条件
use_backend dynsrvs if phpapp ##定义使用的后端服务标识
bind *:80
rspadd X-Via:\ HAProxy
rspidel Server.*
maxconn 4000
default_backend websrvs
compression type text/html
compression algo gzip
#backend curlbe
# balance roundrobin
# server curlsrv1 172.18.249.57:80 check
backend dynsrvs ##定义后端的代理服务及标识
balance source
server dynsrv1 172.18.249.57:80 check
保存并退出,重启服务,
使用浏览器分别访问
http://172.18.200.100/index.php
Curl server 172.18.249.57
PHP Logo
PHP Version 5.3.3
http://172.18.200.100/test1.html
Test Page 1 (BE 1)
实现简单的动静分离