haproxy是一个代理服务器,他是将用户的多个请求调度到后端服务器时,而不会因为一个后端服务器的故障而导致面向客户端的服务不可用,但是如果是haproxy自身故障了,服务依然不可用
haproxy是一个代理服务器,但是天然就是一个能在代理时做负载均衡调度的服务器
haproxy的特信有两个反代和调度器
1.反代,支持两种反代模式
1.如果工作在http模式下,这是一个七层反代
2.如果工作在tcp模式下,这是一个伪四层反代,之所以称为伪四层是因为还有工作在七层,来模拟四层调度
四层反代和七层反代的区别
1.要根据用户的请求的资源类型做分离调度,只有七层才有这样的功能
2.七层还可以做ssl/tls会话的卸载器。四层反代就无法实现这个功能
ssl/tls会话的卸载器就是,如果我们要构建一个ssl类型的应用,他可以实现客户端与调度器后端的RS服务器二者之间实现ssl会话的建立,拆除等功能
如果我们要做七层调度的话ssl会话可以只在客户端与调度器之间进行,调度器与反代服务器通常都是一个局域网之内的通信,而且是一个防范严密的局域网通信,因此他们之间的明文通常是没有问题的
由于ipvs工作在四层而ssl或tls工作在七层模型中的会话层或应用层,使得他没法卸载,这是七层反代时能获取的功能
七层反代只针对http和https服务
2.调度器
调度器有众多的调度算法
rr轮循 wrr加权轮循 lc最少连接 wlc加权最少连接
还支持七层模型中特有的调度算法,例如:URL
haproxy使用事件驱动模型单进程响应多请求的模式来工作,他也可以同时启用多进程,每个进程响并处理一部分用户请求,但是对haproxy不建议这么做,他们强烈建议将haproxy运行在单进程上,足以处理较大并发数量的用户请求,虽然他也能支持多进程的模式,但建议单进程,这样更容易排查和定义问题
四层和七层调度的区别
四层调度仅仅是一个管道,如果和ipvs一样仅仅工作在内核的话,ipvs不用监听套接字,它只是打开了一个管道,他是把请求原封不动的发到后端服务器上
七层反代是自己要监听在套接字上,所以客户端请求的时候,我们的代理服务器就是服务器端,客户端和代理服务器之间有一个完整的会话,代理服务器发现自己没有对方请求内容,自己在起一个客户端程序,然后向后端服务器发请求,这样一来面向后端服务器的是代理服务器端
所以这是完全独立的两路连接,各自独立
四层是不受套接字数量限制的
七层是受套接字数量限制的
timedatectl set-timezone Asia/Shanghai 更改时间区
haproxy的版本是1.5
haproxy 的配置主要分两段
global 全局配置段,这些都要工作在默认配置下,因为会动态调整
进程及安全配置相关的参数
性能调整相关参数
Debug参数
用户列表
peers 同等端点的其他兄弟服务器彼此间通信
proxies 代理配置段
defaults:为frontend ,backend,listen 提供默认配置
frontend前端 相当于nginx的server {}
backend 后端 相当于nginx的upstream {} 调度器
listen 相对frontend和backend的合体,但是只能实现一对一
安装haproxy
yum install haproxy -y
配置文件
vim /etc/haproxy/haproxy.cfg
在global全局中配置
定义前端
frontend main *:80 #要监听的端口
mode http #以http模型为主导
default_backend websrvs #要使用哪个默认后端,websrvs后端的名字自己定义
定义后端
backend websrvs
balance roundrobin #调度算法,roundrobin加强轮循
server websrv1 192.168.63.131:80 check websrv1 代表第一个后端,check代表健康检查
server websrv2 192.168.63.139:80 check websrv2 代表第一个后端,check代表健康检查
启动服务
systemctl restart haproxy
客户端测试
for i in {1..10} ;do curl 192.168.63.140; done
更改调用的权重
frontend main *:80
mode http
default_backend websrvs
backend websrvs
balance roundrobin
server static1 192.168.63.131:80 check weight 2 注:weight 2代表权重改为2
server static2 192.168.63.139:80 check
客户端测试 192.168.63.140是代理服务器haproxy的ip
for i in {1..10} ;do curl 192.168.63.140; done
global是haproxy的全局配置
配置日志文件
vim /etc/rsyslog.conf
在日志文件中加入这一行
local2.* /var/log/haproxy.log
取消两行注释,使用UDP协议,因为性能比较好
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
启动日志服务
systemctl restart rsyslog
用ss -unl查看udp协议的端口,查看514监听端口是否启用
查看日志
tail /var/log/haproxy.log
nbproc 要启动的haproxy的进程数量
默认是两个
ps aux 查看
可以用 ulimit-n修改,不过不建议修改,haproxy主控进程会根据子进程所需要打开的描述符自动调整
进程及安全管理:chroot切根,daemon是否以守护进程方式运行, user group uid gid
代理配置阶段
defaults <name>
frontend <name>
用来配置前端,就是接入客户端请求的,监听在某一个套接字上
backend <name>
后端有多少个服务器,我们把它规定成组,并配置调度算法,以便能被前端作为调度或者转 – 发请求目的端
listen <name>
listen包含frontend和backend的
可以的配置参数
bind:用来定义前端服务器用来接收用户请求的套接字
listen http
bind :80,:443 #可以监听两个套接字80,443 只能用在frontend和listen代理中
bind 10.0.0.:1080,10.0.0.1:10443 #也可以用ip加端口的格式
bind /var/run.ssl-frontend.sock user root mode 600 accept-proxy #亦可以说sock文件
监听两个套接字只能用在frontend和listen代理中
uri算法
后端服务器调度到缓存服务器的时候要用到的
vim /etc/haproxy/haproxy.cfg
backend websrvs
balance uri #算法
hash-type consistent # 用动态方式调度
server static1 192.168.63.131:80 check weight 2 #权重为2,是2比1的调度
server static2 192.168.63.139:80 check
在后端服务器创建测试页面
192.168.63.131 服务器
for i in {1..10};do echo "Test Page $i @Backend Server 1" >/var/www/html/test$i.html; done
192.168.63.139 服务器
for i in {1..10};do echo "Test Page $i @Backend Server 1" >/var/www/html/test$i.html; done
客户端测试
for i in {1..10};do curl http://192.168.63.140/test9.html; done
hdr(User-Agent)算法
把来自同一客户端的请求,始终绑到同一服务器上
vim /etc/haproxy/haproxy.cfg
backend websrvs
balance hdr(User-Agent)
hash-type consistent
server static1 192.168.63.131:80 check weight 2
server static2 192.168.63.139:80 check
将一台服务器标记为backup
下架一台服务器
vim /etc/haproxy/haproxy.cfg
backend websrvs
balance roundrobin
server static1 192.168.63.131:80 check backup
server static2 192.168.63.139:80 check
修改默认检测逻辑
backend websrvs
balance roundrobin
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 1秒钟检测一次,上架只要一次,下架要两次
server static2 192.168.63.139:80 check
redir 只要访问这个服务器都调度到其他服务器
如果这个服务器有问题。当客户端访问的时候我吗可以将这条服务器调度到其他可以用的服务器上
backend websrvs
balance roundrobin
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2
server static2 192.168.63.139:80 check redir https://www.baidu.com/
如果访问的是static2服务器就调度到baidu网站
在客户端浏览器测试
172.20.127.233 ip是haproxy的服务器外网ip
maxconn 定义最大并发连接数
backend websrvs
balance roundrobin
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000
server static2 192.168.63.139:80 check redir maxconn 1500
cookie 做会话绑定
当有请求报文的时候,进程请求报文,发现上一次已经例如到过static1服务器,就将这个报文调度到第一个服务器上
backend websrvs
balance roundrobin
cookie WEBSRV insert nocache indirect 注: WEBSRV名字随便指定,以insert的方式插入已有的cookie中,后面两是补充,nocache 非缓存响应的,以及indirect重定向的
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000 cookie static1
server static2 192.168.63.139:80 check maxconn 1500 cookie static2
在客户端浏览器测试
172.20.127.233 ip是haproxy的服务器外网ip
httpchk http的七层状态安全检测
vim /etc/haproxy/haproxy.cfg
backend websrvs
balance roundrobin
option httpchk GET /test9.html #GET是方法,test9.html是URL
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000
server static2 192.168.63.139:80 check maxconn 1500
检测test9.html网站,如果没有故障两个都调度,如果一个故障,就只调度一个服务器
统计接口的参数
显示web界面
在前端加入 stats enable
vim /etc/haproxy/haproxy.cfg
frontend main
bind :80,:8080
mode http
default_backend websrvs
stats enable
启动服务
systemctl restart haproxy
浏览器测试
我们打开的web界面没有安全装置非常的不安全。我们可以做以下几种安全设置
1.让web界面特定的端口打开,我的可以单独定义
listen stats *:9527 #端口是9527
stats enable
启动服务
systemctl restart haproxy
在客户端访问的时候要加端口
2.输入用户名密码
listen stats *:9527
stats enable
stats realm "HAProxy Stats" #提示用户输入用户名密码
stats auth admin:admin #用户名和密码是admin
启动服务
systemctl restart haproxy
客户端测试
3. 更改URL
vim /etc/haproxy/haproxy.cfg
listen stats *:9527
stats enable
stats uri /admin?mystats
stats realm "HAProxy Stats"
stats auth admin:admin
重新启动服务
systemctl restart haproxy
客户端测试
4.打开内建管理接口
vim /etc/haproxy/haproxy.cfg
listen stats *:9527
stats enable
stats uri /admin?mystats
stats realm "HAProxy Stats"
stats auth admin:admin
stats admin if TRUE
启动服务
systemctl restart haproxy
客户端测试
选择要在已检查的服务器上执行的操作
例将static1 设置为DRAIN
maxconn的参数
不建议打开
将ssh端口发布到互联网,这样互联网的客户端也可以访问
listen ssh
bind :22222
mode tcp
balance leastconn
server srv1 192.168.63.131 check
server srv2 192.168.63.139 check
option forwardfor 加入这个选项能获取到客户端的真实地址
1. 在haproxy服务器端加入选项
vim /etc/haproxy/haproxy.cfg
backend websrvs
balance roundrobin
option httpchk GET /test8.html
option forwardfor
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000
server static2 192.168.63.139:80 check maxconn 1500
启动服务
systemctl restart haproxy
2.在后端服务器修改httpd的配置
vim /etc/httpd/conf/httpd.conf
找到 LogFormat所在的行
在第一行开头把%h修改为 LogFormat "%{X-Forwarded-For}i
启动服务
systemctl start httpd
3 在日志文件中查看
tail /var/log/httpd/access_log
errorfile 错误页面
服务器有内建的错误页面,可以自定义。注:代理服务不能自定义错误页面404
但是能指定200, 400, 403, 408, 500, 502, 503, and 504.
errorloc
rspdel删除服务器端的一些信息 rspadd是添加信息
在响应报文可以看到server暴露了http的版本信息,非常危险,我们可以删除这个选项
删除server的首部
vim /etc/haproxy/haproxy.cfg
frontend main
bind :80,:8080
mode http
default_backend websrvs
rspidel ^Server:.*
我也可以自己定义一个server的首部
vim /etc/haproxy/haproxy.cfg
frontend main
bind :80,:8080
mode http
default_backend websrvs
rspidel ^Server:.*
rspadd Server:\ Feige
在客户端测试
和facl相关的选项
block 在满足条件的时候拒绝
定义某一个地址拒绝
frontend main
bind :80,:8080
mode http
default_backend websrvs
rspidel ^Server:.*
rspadd Server:\ Feige
acl bad_guys src 192.168.63.137 #拒绝ip
block if bad_guys #如果是bad_guys就拒绝
errorfile 403 /etc/haproxy/errorfiles/403.html #自定义返回一个错误403,访问指定的文件信息
创建指定的目录
mkdir -p /etc/haproxy/errorfiles/
vim /etc/haproxy/errorfiles/403.html
<h1>403 Forbidden</h1>
客户端浏览器测试
http-request 进行精确的访问控制,那些人可以访问,那些人不可以访问
frontend main
bind :80,:8080
mode http
default_backend websrvs
rspidel ^Server:.*
rspadd Server:\ Feige
acl mynet src 172.20.0.0/16 #定义一个网段
http-request allow if mynet #只要是mynet就可以访问
tcp-request 在三次握手的时候就拒绝掉
use_backend 当满足条件时使用指定的客户端,否则默认
ACL
path_beg 路径的前缀,以什么开头
path_end 以什么结尾的
path_reg ^/images.*\.jpeg$ 如果以/images开头,后面跟任何内容,以\.jpeg结尾
path_sub image 搜索字串,包含image
path_dir jpegs 子路径匹配包含 jpegs
path_dom ilinux 只要包含ilinux的字串,就符合条件
-i 不区分字符大小写
-m 使用特点的模式 ,一般不用
-n禁止DNS做用,域名解析
-u 要acl必须使用唯一的名称
多个ACL可以用同一个名字,通常用来做或逻辑
如果有多个ACL,当标准不一样
frontend main *:5000
acl url_static path_beg -i /static /images /javascript /stylesheets #只要是这些开头>的都归类为url_static
acl url_static path_end -i .jpg .gif .png .css .js #以这些结尾的都归类为url_static
use_backend static if url_static #只要满足url_static这些条件就调度到static
default_backend app
backend static #只要满足url_static这些条件就调度到static
balance roundrobin
server static 127.0.0.1:4331 check
进行动态和具体的分离调用
vim /etc/haproxy/haproxy.cfg
frontend main
bind :80,:8080
mode http
acl url_img path_beg /images #以/images开头的文件夹,这个文件夹下面放的是图片
acl url_img path_end .jpg .png .jpeg .gif #以这些格式结尾
use_backend imgsrvs if url_img #如果访问的是图片就访问这个服务器
default_backend websrvs
rspidel ^Server:.*
backend imgsrvs #如果访问的是图片就访问这个服务器
balance roundrobin 轮循算法
server imgsrv1 192.168.63.139:80 check 注:check 健康检测
backend websrvs
balance roundrobin
option httpchk GET /test8.html
option forwardfor
server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000
server static2 192.168.63.139:80 check maxconn 1500
在后端192.168.63.139服务器查找图片
find /usr/share -iname "*.jpg" -exec cp {} ./ \; 查找图片并拷贝到当前目录
find /usr/share -iname "*.png" -exec cp {} ./ \; 查找图片并拷贝到当前目录
通过首部报文控制
frontend main
bind :80,:8080
mode http
acl bad_agent hdr_sub(User-Agent) -i curl wget # 用hdr_sub做字串匹配,如果对User-Agen去检测的时候 -i不区分大小写 ,发现curl和wget
block if bad_agent #如果匹配就拒绝访问
default_backend websrvs
rspidel ^Server:.*
后端服务器测试
显示无法访问
[root@RS1 ~]# curl http://172.20.127.233/test1.html
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
[root@RS1 ~]# wget -O – -q http://172.20.127.233/test1.html
连接超时时长
timeout client 面向客户端的超时时长
timeout server 面向服务端的超时时长,建立连接以后要多少时间断开的时长
timeout http-keep-alive 持久连接的持久时长
timeout http-request http客户端请求报文传完的时长
timeout connect 客户端发起连接请求时的超时时长
timeout client-fin 在客户端设置半关闭连接的非活动超时
timeout server-fin 在服务器端设置半关闭连接的非活动超时
原文链接:https://blog.51cto.com/u_10957928/2159940