一,haproxy简介
HAProxy是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件 是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计。
实验环境部署
haproxy: 172.25.254.100 webserver1:172.25.254.10 webserver2: 172.25.254.20
防火墙,selinux关闭
[server1]
[root@server1 ~]# dnf install nginx -y
[root@server1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index.html
[root@server1 ~]# systemctl enable --now nginx
[server2]
[root@server1 ~]# dnf install nginx -y
[root@server1 ~]# echo webserver1 - 172.25.254.20 > /usr/share/nginx/html/index.html
[root@server1 ~]# systemctl enable --now nginx
测试
[haproxy]
[root@haproxy ~]# curl 172.25.254.10
webserver1 - 172.25.254.10
[root@haproxy ~]# curl 172.25.254.20
webserver2 - 172.25.254.20
二,haproxy基本配置
环境准备
[root@haproxy ~]# dnf install haproxy -y
[root@haproxy ~]# rpm -qc haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
use_backend webcluster-host
backend webcluster-host
balance rountrobin
server web1 172.25.254.10:80
server web2 172.25.254.20:80
[root@haproxy ~]# systemctl restart haproxy.service
测试
[root@haproxy ~]# curl 172.25.254.100
webserver1 - 172.25.254.10
[root@haproxy ~]# curl 172.25.254.100
webserver2 - 172.25.254.20
#当我们停止时nginx时,就不能访问
[root@webserver1 ~]# systemctl stop nginx
[root@haproxy ~]# curl 172.25.254.100
webserver1 - 172.25.254.20
多进程
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
nbproc 2
cpu-map 1 0
cpu-map 2 1
[root@haproxy ~]# systemctl restart haproxy.service
查看进程数量
[root@haproxy ~]# pstree -p | grep haproxy
|-haproxy(3187)-+-haproxy(3190)
| -haproxy(3191)
启用多线进程
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
nbthread 2
[root@haproxy ~]# systemctl restart haproxy
日志文件配置
[root@haproxy ~]# vim /etc/rsyslog.conf
module(load="lmudp") #取消注释
input(type="imudp" port="514") #取消注释
local2.* /var/log/haproxy.log
[root@haproxy ~]# systemctl restart rsyslog.service
[root@haproxy ~]# systemctl enable --now rsyslog
server配置
[root@haproxy ~]# vim /etc/haproxy/conf.d/serverclient.cfg
listen webserver
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80
server web2 172.25.254.20:80
[root@haproxy ~]# systemctl restart haproxy.service
测试
[root@client ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
sorry_server 效果
[root@haproxy ~]# vim /etc/httpd/conf/httpd.conf
Listen 8080
[root@haproxy ~]# echo sorry > /var/www/html/index.html
[root@haproxy ~]# cat /etc/haproxy/conf.d/serverclient.cfg
listen webserver
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
server web_sorry 172.25.254.100:8080 backup
[root@haproxy ~]# curl 172.25.254.100
sorry
网页重定向
[root@haproxy ~]# cat /etc/haproxy/conf.d/serverclient.cfg
listen webserver
bind *:80
mode http
balance roundrobin
redirect prefix http://www.baidu.com
#server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
#server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
#server web_sorry 172.25.254.100:8080 backup
[root@haproxy ~]# systemctl restart haproxy.service
热处理
[root@haproxy ~]# dnf install socat -y
[root@haproxy ~]# echo get weight webcluster/web1 | socat stdio /var/lib/haproxy/stats
2 (initial 2)
[root@haproxy ~]# echo get weight webcluster/web2 | socat stdio /var/lib/haproxy/stats
1 (initial 1)
[root@haproxy ~]# echo "set weight webcluster/web1 1" | socat stdio /var/lib/haproxy/stats
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
热处理下线某台服务器
[root@haproxy ~]# echo "disable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
[root@client ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver2 172.25.254.20
webserver2 172.25.254.20
webserver2 172.25.254.20
webserver2 172.25.254.20
热处理开启某台服务器
[root@haproxy ~]# echo "enable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
[root@client ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver2 172.25.254.20
webserver1 172.25.254.10
webserver2 172.25.254.20
webserver1 172.25.254.10
webserver2 172.25.254.20
三, haproxy算法
静态算法
1.static-rr
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance static-rr
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
2.first
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance first
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
[root@webserver1 ~]# while true ; do curl 172.25.254.100; sleep 0.1 ; done
动态算法
1.roundrobin
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
测试
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
2.leastconn(连接数最少的服务器优先接收连接)
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
#balance roundrobin
balance leastconn
server web1 172.25.254.10:80 maxconn 1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
测试
[root@haproxy ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
webserver1 - 172.25.254.10
webserver2 - 172.25.254.20
其他算法
1.source
[root@haproxy ~]# cat /etc/haproxy/conf.d/serverclient.cfg
listen webserver
bind *:80
mode http
balance source
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
测试
[root@client ~]# for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
webserver1 - 172.25.254.10
2.uri
[root@haproxy ~]# cat /etc/haproxy/conf.d/serverclient.cfg
listen webserver
bind *:80
mode http
balance uri
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 2
webserver1配置
[root@webserver1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index1.html
[root@webserver1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index2.html
[root@webserver1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index3.html
webserver2配置
[root@webserver2 ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index3.html
[root@webserver2 ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index1.html
[root@webserver2 ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index2.html
测试
[root@haproxy ~]# curl 172.25.254.100/index1.html
webserver1 - 172.25.254.10
[root@haproxy ~]# curl 172.25.254.100/index2.html
webserver2 - 172.25.254.20
[root@haproxy ~]# curl 172.25.254.100/index3.html
webserver1 - 172.25.254.10
3.url_param
root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
balance url_param name,userid
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
4.hdr
root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
balance hdr(User-Agent)
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
四,haproxy的高级功能
1.haproxy的状态页
[root@haproxy ~]# cat /etc/haproxy/conf.d/status.cfg
listen stats:
mode http
bind *:9999
stats enable
log global
stats uri /status
stats auth byh:byh
2.基于cookie的会话保持
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
balance roundrobin
cookie WEBCOOKIE insert nocache indirect
server web1 172.25.254.10:80 cookie lee1 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 cookie lee2 check inter 2 fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
[root@haproxy ~]# curl -b WEBCOOKIE=lee1 172.25.254.100
webserver1 - 172.25.254.10
[root@haproxy ~]# curl -b WEBCOOKIE=lee2 172.25.254.100
webserver2 - 172.25.254.20
3. IP透传
四层IP透传
[root@webserver1 ~]# vim /etc/nginx/nginx.conf
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request"'
' "$proxy_protocol_addr"'
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80 proxy_protocol;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
修改haproxy配置
vim /etc/haproxy/serverclient.cfg
listen webserver_80
bind *:80
mode tcp
balance roundrobin
server webserver1 172.25.254.10:80 send-proxy weight 1 check inter 3s fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 3 fall 3 rise 5 weight 1
七层IP透传
[root@web1 ~]# cat /etc/nginx/nginx.conf
http {
log_format main '"$proxy_add_x_forwarded_for" - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
vim /etc/haproxy/serverclient.cfg
listen webserver_80
bind *:80
mode tcp
balance http
server webserver1 172.25.254.10:80 send-proxy weight 1 check inter 3s fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 3 fall 3 rise 5 weight 1
4. ACL
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
bind *:80
mode http
acl test hdr_dom(host) -i www.timinglee.org
use_backend webcluster-host if test
default_backend default-host
backend webcluster-host
mode http
server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
backend default-host
mode http
server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@haproxy ~]# systemctl restart haproxy.service
测试
[root@haproxy ~]# curl 172.25.254.100
webserver2 - 172.25.254.20
[root@haproxy ~]# curl www.timinglee.org
webserver1 - 172.25.254.10
结尾匹配:
frontend webcluster
bind *:80
mode http
acl test hdr_end(host) -i .org
use_backend webcluster-host if test
default_backend default-host
开头匹配:
frontend webcluster
bind *:80
mode http
acl test hdr_beg(host) -i byh
use_backend webcluster-host if test
default_backend default-host
搜索匹配(包含就行)
frontend webcluster
bind *:80
mode http
acl test base_sub -m sub byh #只要包含byh就是匹配成功
use_backend webcluster-host if test
default_backend default-host
基于源IP或子网调度访问
frontend webcluster
bind *:80
mode http
acl domain hdr_dom(host) -i www.timinglee.org
use_backend webcluster-host if domain
default_backend default-host
测试
[root@haproxy ~]# curl www.test.com
webserver2 - 172.25.254.20
[root@haproxy ~]# curl www.timinglee.org
webserver1 - 172.25.254.10
基于源地址的访问控制
frontend webcluster
bind *:80
mode http
acl ctrl_ip src 172.25.254.1 172.25.254.20
use_backend webcluster-host if ctrl_ip
default_backend default-host
匹配浏览器类型
frontend webcluster
bind *:80
mode http
acl badwebrowers hdr_sub(User-Agent) -i curl wget
#use_backend webcluster-host if webrowers
http-request deny if badwebrowers
default_backend default-host
动静分离
[root@webserver1 ~]# dnf install php -y
[root@webserver1 ~]# systemctl restart httpd
[root@webserver1 ~]# vim /var/www/html/index.php
[root@webserver1 ~]# cat /var/www/html/index.php
<?php
phpinfo();
?>
haproxy:
frontend webcluster
bind *:80
mode http
acl static path_end -i .html .jpg .png .css .js
acl php path_end -i .php
use_backend webcluster-host if php
default_backend default-host
五,自定义HAProxy错误界面
webserver主机上
system stop httpd/nginx
haproxy主机上
[root@haproxy ~]# mkdir /etc/haproxy/errorpage -p
[root@haproxy ~]# vim /etc/haproxy/errorpage/503.http
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8
<html><body><h1>你好!!!!</h1>
我不好!!!
</body></html>
六,HAProxy 四层负载
在webserver主机上
yum install mariadb-server -y
[root@webserver1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=1
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid
配置数据库认证远程登陆
mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
测试
mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 1 |
mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 2 |
七,HAProxy https 实现
[root@haproxy ~]# cat /etc/haproxy/conf.d/https.cfg
frontend webserver
bind *:80
redirect scheme https if !{ ssl_fc }
mode http
use_backend webcluster
frontend webserver-https
bind *:443 ssl crt /etc/haproxy/timinglee.org.pem
mode http
use_backend webcluster
backend webcluster
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 3s fall 3 rise 5
server web2 172.25.254.20:80 check inter 3s fall 3 rise 5
[root@haproxy ~]# mkdir /etc/haproxy/certs
[root@haproxy ~]# openssl req -newkey rsa:2048 \
> -node -sha256 -keyout /etc/haproxy/certs/baga.org.key \
> -x509 -days 365 -out /etc/haproxy/certs/baga.org.crt
.+.....+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*............+..+...............+..........+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+....+.....+......+..........+..+.+...........+.........+....+...+........+.+.....+........................+....+.....+............+.+...+.....+............+....+..............+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
............+........+...+.......+...+.....+......+.........+.+....................+.+.....+...+.+...+...+..............+.+..+...+.........+....+.........+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+......+............+..+...............+......+.......+........+.......+...+..+.........+.............+........+.........+.+...+......+......+...+..+...+.+.....+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+..+....+...+..+..........+........+......+......+.+..+...+...+.......+............+...............+..+....+..+.......+........+.......+.....+.+...........+...+......+.+..................+..+.+.....+.............+..+............+.+..+...+.+...+........+.......+...+.........+......+...+.....+......+......+....+...+........+.........+.+..............+...+...+...+.......+..+...+....+......+........+...............+.+...+..+.+.....+....+......+........+..........+..+....+...........+.......+......+......+......+..+......+................+...+..+...+......+.......+.....+.......+..+...+..........+..+...+......+.+......+............+...+..+......+..........+.....+.......+........+.+......+...+............+.....+............+.............+..+.+.....................+.....+...+..........+..+.........+....+..+.+...+.....+....+............+..............+....+...+.....+....+...+...+.........+......+...+.....+.......+..+.......+.....+....+...........+......+............+.+....................+...............+......+......+....+...+...+........+......+.+.....+...........................+...+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:byh
State or Province Name (full name) []:shanxi
Locality Name (eg, city) [Default City]:xi`an
Organization Name (eg, company) [Default Company Ltd]:baiweilong
Organizational Unit Name (eg, section) []:hujiake
Common Name (eg, your name or your server's hostname) []:yangwensai
Email Address []:admin@163.com