HAproxy基础服务实现及相关参数讲解

HAproxy简单概述

HAProxy是免费极速且可靠的用于为TCP和基于HTTP应用程序提供代理服务的解决方案。是工做在应用空间的程序,跟Nginx同样受限于套接字。且只类同于Nginx四层和七层代理服务器仅此而已。但更多用在web反向代理上!!! 
HAProxy还能够将后端的服务器与网络隔离,起到保护后端服务器的做用。HAProxy的负载均衡能力虽不如LVS,但也是至关不错。并且因为其工做在7层,能够对http请求报文作深刻分析,按照本身的须要将报文转发至后端不一样的服务器(例如动静分离),这一点工做在4层的LVS没法完成。 
其中一点点不一样Nginx的是一个Master Worker模型负责接收用户请求,装载配置文件,平滑升级…可是更多的用户请求是经过worker来实现。而HAProxy是单一进程模型,支持多进程,但更多建议使用单一进程模型。使用单个进程直接响应用户多个请求,不启用子进程。也可以支持单进程巨大并发链接数,且必须支持事件驱动,若是不支持事件驱动,并发效率是可想而知。javascript

HAproxy工做模式

HAProxy的工做模式通常有两种 
tcp模式:实例运行于TCP模式,在客户端和服务器端之间将创建一个全双工的链接,且不会对7层报文作任何类型的检查,只能以简单模式工做。此为默认模式,一般用于SSL、SSH、SMTP等应用。 
http模式:实例运行于HTTP模式,客户端请求在转发至后端服务器以前将被深度分析,全部不与RFC格式兼容的请求都会被拒绝。 
注意:当实现内容交换时,前端和后端必须工做于同一种模式(通常都是HTTP模式),不然将没法启动实例。 
工做模式可经过mode参数在default,frontend,listen,backend中实现定义。 
两种模块分别是:经过mod_tcp来限定反代模式和mod_http来实现负载均衡 
帮助文档地址:http://cbonte.github.io/haproxy-dconv/,其它的地址就别想了css

HAproxy演示环境

实验平台:Windows10_64 
虚拟环境:基于Win系统搭建的VMware虚拟主机实现 
所须要的虚拟主机:三台,CentOS 7.2或者是CentOS 6.8,偏移CentOS 7.2 
虚拟主机各IP:node1–10.1.15.40, node2–10.1.15.41 node3–10.1.15.42 
node1节点–10.1.15.40,安装haproxy,其它两个节点作后端轮询。 
base收录版本1.5,可是立刻要废弃了。官方最新版是1.7开发板(演示1.5)html

HAproxy的安装

haproxy已经收录到了base仓库,因此咱们直接yum安装就能够了,由于我这里实验使用的Centos7系统,因此仍是使用YUM,其它发行版本可另行抉择。 
若是遇到yum安装报错You could try using –skip-broken to work around the problem 
可移除yum.repos.d目录下的全部文件,只留base.repo文件而后yum clean all 
再执行yum install前端

[root@localhost yum.repos.d]# yum install haproxy -y

HAproxy程序环境:

配置文件:/etc/haproxy/haproxy.cfg
Unit File: haproxy.service
主程序:/usr/sbin/haproxy
配置文件分两部分组成:
global:全局配置段
    进程及安全配置相关的参数
    性能调整相关的参数
    Debug相关的参数
proxies:代理配置段
    defaults:为frontend, backend以及listen提供默认配置;
    frontend:前端,至关于Nginx中的server{ ... };
    backend:后端,至关于nginx中的upstream { ...  };
    listen:先后端的直接组合;

简单实现用haproxy实现后端主机代理,简单均衡 
一、> vim /etc/haproxy.cfg 在haprxoy 10.1.15.40主机上修改如下内容 
frontend main 
bind *:80,*:8080 
default_backend web 
# static backend for serving up p_w_picpaths, stylesheets and such 
backend web 
balance roundrobin 
server web1 10.1.15.41:80 check 
server web2 10.1.15.42:80 check 
二、在后端两台主机安装httpd启动服务,给指定网页分别叫backend1和backend2 
10.1.15.41 
vim /var/www/html 
<h1> backend 1 <h1> 
10.1.15.42 
vim /var/www/html 
<h1> backend 2 <h1> 
java

HAproxy相关配置参数全局段:

global配置参数: 
进程及安全配置相关的参数:user/uid, group/gid, nbproc, ulimit-n, ca-base, … 
log < address > [len < length >] < facility > [ max level [min level]] 
定义日志相关配置属性address是日志服务器的地址, [len < length >]是每行日志记录的最大长度 
举例:如何记录haproxy的日志呢? 
一、 让haproxy服务器启用接收远程主机所传来的日志信息 
二、 若是启用local2.,指明local2.日志记录于何处 
三、若是启用日志,使用udp和tcp均可以,咱们这里使用的udp,把注释去掉node

vim /etc/rsyslog.conf 第一步
#Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

指明日志记录到哪里去  第二步
#Save boot messages also to boot.log
local2.*   /var/log/haproxy.log
systemctl restart rsyslog.service,确保UDP 514端口被监听
[root@localhost log]# cat haproxy.log 
Nov 12 13:26:24 localhost haproxy[23610]: 10.1.15.85:6703 [12/Nov/2016:13:26:24.829] main web/web1 0/0/0/3/3 200 280 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"

性能调优相关参数 
maxconn < number>:设定单haproxy进程的最大并发链接数; 
maxconnrate < number>:设定单haproxy进程每秒所能接受的链接数; 
maxsslconn < number>:设定单haproxy进程的ssl链接最大并发链接数; 
maxsslrate < number>:单haproxy进程的ssl链接的建立速率上限; 
spread-checks <0..50, in percent> 
向后端主机作健康状态检测时,该如何散开检测机制 
tune.bufsize < number> 缓冲池大小 
tune.rcvbuf.client < number> 接收客户端请求时缓冲池大小 
tune.rcvbuf.server < number> 接收后端服务器的响应时缓冲池大小 
tune.sndbuf.client < number> 向客户端发送响应 
tune.sndbuf.server < number> 向服务端发送请求 
tune.ssl.cachesize < number> ssl的缓存大小 
tune.ssl.lifetime < timeout> ssl的缓存会话的有效时长 
Debugging: 
debug 尽可能输出详细信息 
quiet 不输出详细信息 
Userlists:定义用户、组及用户列表; 
userlist < listname > 
group < groupname > [users < user >,< user >,(…)] 
user < username > [password|insecure-password < password >] 
strong text[groups < group >,< group >,(…)] 
Peers:把多个haproxy定义构建为同步集群 
peer 
peers 
其它未尽详细的参数请参考官方帮助文档 
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#3.1mysql

HAproxy相关配置参数代理段:

关于代理段的详细参数在这里就很少说,仍是请参考官方文档,太多了看起来头疼 
简要说下HAproxy的工做模式”Mode” 
Mode能够工做在default,listen.backend和frontend中,用来定义HAproxy到底工做在应用层仍是传输层 
Mode主要用来定义haproxy的三种工做模型: 
tcp:基于layer4实现代理,可代理大多数基于tcp的应用层协议,例如ssh/mysql/pgsql等; 
http:工做在应用层,客户端的http请求会被深度解析; 
health:工做为健康状态检查响应模式,当请求到达时仅回应“OK”即断开链接;nginx

HAproxy调度算法:

定义负载均衡的算法除了listen和backend段中也能够放在defaults段中,定义格式: 
balance < algorithm > [ < arguments > ] 
balance url_param [check_post [< max_wait >]] 
常见的调度算法 
roundrobin: 
动态算法:支持权重的运行时调整,支持慢启动;仅支持最大4095个后端活动主机 
server后面使用weight来定义权重; 
static-rr: 
基于权重进行轮询与roundrobin相似静态算法:不支持权重的运行时调整及慢启动;但后端主机数量无限制; 
leastconn: 
新的链接请求被派发至具备最少链接数目的后端服务器,动态算法,适用于较长时间会话的场景。 
source: 
将请求的源地址进行hash运算,并与后端服务器的总权重做取模运算后调度至某台服务器;同一IP地址的请求将始终被调度至某特定的服务器,可使用hash-type修改此特性来肯定动态仍是静态算法 
hash表如何创建映射:除权重取模法,一致性hash 
hash-type: 
map-based:取模法,hash数据结构是静态数组; 
consistent:一致性哈希,哈希的数据结构是“树”; 
uri: 
对URI的左半部分(“?”以前的部分)或整个URI进行hash运算,并与后端服务器的总权重做取模运算后调度至某台服务器;同一URI的请求将始终被调度至某特定的服务器,静态算法,可使用hash-type修改此特性;git

hdr(< name >): 
根据用户请求报文中指定的http首部的值进行调度,经常使用于实现对同一个虚拟主机的请求始终发往同个backend server。 
first: 
先到先得,服务器名称标识字符最短的优先调用。一台用完才用第二台,忽略权重。github

**演示示例**

更改调度算法为source,把同一IP地址的请求将始终被调度至某特定的服务器
vim /etc/haproxy/haproxy.cfg
backend web
    balance     roundrobin //修改成source
    server       web1 10.1.15.41:80 check
    server       web2 10.1.15.42:80 check
systemctl reload haproxy.service //测试:http://19.1.15.40 

更改调度算法为uri,把同一页面请求经过调度算法发往到后端指定服务器
vim /etc/haproxy/haproxy.cfg
backend web
    balance     roundrobin //修改成uri
    server       web1 10.1.15.41:80 check
    server       web2 10.1.15.42:80 check
for i in {1..10}; do echo "test page $i at BACKEND 1 " > /var/www/html/test$i.html; done
systemctl reload haproxy.service

测试:
for i in {1..10}; do curl http://10.1.15.40/test$i.html;done
结果:把同一个被请求到的页面始终发往到指定的后端服务器上

更改调度算法为hdr,把同一浏览器的请求,始终发往到后端指定服务器上
vim /etc/haproxy/haproxy.cfg
backend web
    balance     roundrobin //修改成hdr(User-Agent)
    server       web1 10.1.15.41:80 check
    server       web2 10.1.15.42:80 check
systemctl reload haproxy.service
测试:
for i in {1..10}; do curl http://10.1.15.40/test$i.html;done 
结果:只要浏览器同样,请求始终被调度到指定后端服务器上

调整服务器的最大并发链接数,并启用stats页面作认证

定义并发数有两种方法: 
一种,全局定义,一种默认定义 
vim /etc/haproxy/haproxy.cfg 
frontend main //在此下面定义maxconn 10000 
bind * :80, * :8080 
maxconn 10000 
定义stats页面,在代理配置段四项中均可以定义 
vim /etc/haproxy/haproxy.cfg 
frontend main 
bind :80,:8080 
maxconn 10000 //最大并发链接数 
stats enable // 开启stats页面 
stats uri /admin?stats //自定义stats页面 
default_backend web //默认的后端主机标识web 
stats realm stats\ page\ area //开启认证界面 
stats auth admin:admin //认证用户名密码 
stats hide-version //隐藏版本信息 
stats refresh 5s //指定stats页面5秒刷新一次 
stats admin if TRUE //内建访问控制列表 
测试:http://10.1.15.40/haproxy?stats

对后端服务器作健康情况检测

check为server的参数,可启动对此server执行健康状态的检测。check借助其额外的参数可实现更精细的监测机制。 
inter < delay>: 
健康状态检测的时间间隔,单位为毫秒,默认为2000,可使用fastinter和downinter来根据服务器端状态优化此时间延迟 
rise < count>: 
健康状态检测中某离线的server从离线状态转换至正常状态须要成功检查的次数 
fall < count>: 
确认server从正常状态转换为不可用状态须要检查的次数 
默认为传输层检测,即探测端口是否能响应。 
须要执行应用层检测,则须要 
httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk; 
vim /etc/haproxy/haproxy.cfg 
backend web //下面修改内容 
balance roundrobin 
server web1 10.1.15.41:80 weight 2 maxconn 5000 check inter 1 rise 1 fall 2 
server web2 10.1.15.42:80 weight 1 maxconn 3000 check inter 1 rise 1 fall 2 
测试:10.1.15.40/haproxy?stats

对后端服务器作加权轮询

vim /etc/haproxy/haproxy.cfg
backend web //在后端主机下列加入
balance roundrobin
server  web1 10.1.15.41:80 check weight 2 maxconn 5000 cookie web1
server  web2 10.1.15.42:80 check weight 1 maxconn 3000 cookie web2
systemctl reload haproxy.service

测试:
for i in {1..10}; do curl http://10.1.15.40/index.html;done 
结果:权重weight,并发maxconn,指定的值cookie 
注意:修改后端服务器的调度算法:必定要重启haproxy的服务,reload是不成功

基于cookie的session绑定

在响应报文中添加cookie信息,下一次的客户请求会带上这个cookie信息,服务器端根据cookie将请求始终定向至后端的某一台服务器,可用于保持session会话。 
而cookie信息该怎么插入进来 
rewrite: 从新改写原有的全部cookie 
insert: 在原有cookie信息当中插入 
prefix: 在原有cookie附加为前缀

举例:把基于浏览器的用户会话访问,对当前服务器讲第一次调度到某个主机,那么就调度某主机
vim /etc/haproxy/haproxy.cfg
backend web //在后端主机下列加入
balance roundrobin
cookie webserver insert nocache indirect
server  web1 10.1.15.41:80 check weight 2 maxconn 5000 cookie web1
server  web2 10.1.15.42:80 check weight 1 maxconn 3000 cookie web2
服务器第一次为某客户度挑选中的主机,会把webserver中的参数值赋值到web1上或者web2上
systemctl reload haproxy.service

测试:
for i in {1..10}; do curl http://10.1.15.40;done 
[root@localhost haproxy]# curl -I 10.1.15.40

自定义haproxy错误页面

vim /etc/haproxy/haproxy.cfg
frontend  main 
bind *:80,*:8080
maxconn 10000
stats enable
default_backend web
stats realm stats\ page\ area
stats auth admin:admin
stats hide-version
stats refresh 5s
stats admin if TRUE
#errorfile 503 /etc/haproxy/errorfiles/503sorry.http //直接以文件形式显示错误页面
errorloc 503 http://10.1.15.40:9527/errorpagetest.html // 直接以url形式显示错误页面,重定向302
errorloc 503 http://www.baidu.com
mkdir /etc/haproxy/errorfiles      
vim  /etc/haproxy/errorfiles/503sorry/http
< h1 >sorry page home < h1 >
systemctl reload haproxy.service

测试:stop后端全部主机,而后请求haproxy前端主机地址 :10.1.15.40option forwardfor

客户端的请求经前端的代理服务器转发至后端的web服务器,代理服务器在转发时将目标地址改成后端的某台web服务器地址,将源地址由client ip(客户端地址)改成本身面向后端服务器的地址。后端的web服务器若使用默认格式记录日志,则记录的客户端IP地址都为前端的代理服务器地址。这时须要在发日后端的请求报文中添加内容为客户端IP地址的首部,以便后端的web服务器可以正确获取客户端地址。 
x-forwardfor 
在配置文件默认段里已经定义了转发,因此咱们直接用就能够了。 
vim /etc/haproxy/haproxy.cfg 
defaults 
option forwardfor except 127.0.0.0/8 
而后修改两台后端主机的httpd.conf文件,vim /etc/httpd/conf/httpd.conf 
把LogFormat %h修改成{X-forwarded-For}i 
重启服务systemctl restart httpd.service 
在haproxy前端主机上刷新下页面。而后在后端主机看日志是否记录的是客户端的真实地址就能够。 
tail /var/log/httpd/access.log看请求的是真实的客户端地址功能就实现了。

修改请求或响应报文首部相关:

增长响应报文相关信息 
frontend main 
rspadd X-Via:\ HAProxy/1,5 
rspidel Server.* 
rspadd X-Via:\ HAProxy/1,5 
客户端请求看一看在Response Headers报文里有没有值:X-Via:HAProxy/1,5 
删除响应报文Server相关信息 
rspidel Server.*

ACL basics

HAPAroxy的ACL可以经过检测请求报文的首部、响应报文的内容或其余的环境状态信息做出转发决策,加强了其配置弹性。 
配置分两步骤:首先定义ACL,即定义一个测试条件,再定义动做,即知足测试条件的状况下执行的某特定动做。 
语法格式: 
acl < aclname> < criterion> [flags] [operator] [< value>] … 
取值类型: 
– boolean 
– integer or integer range 
– IP address / network 
– string (exact, substring, suffix, prefix, subdir, domain) 
– regular expression 
– hex block 
匹配的操做符:数值匹配,字符串匹配,逻辑条件等… 
注意注意:语法太多,让人很蛋疼,简直太头疼,咋么那么多 
注意注意:自定义ACL所有都是小写

四层匹配,举例:
vim /etc/haproxy/haproxy.cfg
在 frontend  main 中定义
acl myhost src 10.1.15.85
acl myport dst_port 8080
block if !myhost myport
任何人试图去访问8080端口时,但不是来自于myhost主机就所有拒绝 
七层匹配,举例:
acl text_file  path_end  -i  .txt
block if text_file
任何人去试图访问txt文件,结尾不区分大小写的所有拒绝
举例:匹配某个浏览器类型
acl chrome hdr_reg(User-Agent) -i .*chrome.*$
block if chrome

HTTP层访问控制指令

acl valid_method method GET HEAD
http-request deny if ! valid_method 
举例:
acl myhost src 10.1.15.40
http-request deny if url_admin !myhost

动静分离

frontend main *:5000 
acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets 
acl url_static path_end -i .jpg .gif .png .css .js 
use_backend static if url_static //若是上面的条件知足调至backend static主机 
default_backend app //不然调至app主机 
backend static 
balance roundrobin 
server static 127.0.0.1:4331 check 
round robin balancing between the various backends 
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 

done!!!

相关文章
相关标签/搜索