haproxy 实现集群
实验环境,haproxybridge eth0 172.16.26.6 VMnet2 eth1 192.168.1.11
httpd node1 VMnet2 eth0 192.168.1.21
httpd node2 VMnet2 eth0 192.168.1.22
192.168.1.21192.168.1.22 两个节点都装上 httpd服务
192.168.1.21index.html主页内容
httpd node1 192.168.1.21
192.168.1.22主页内容
httpd node2 192.168.1.22
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_14111046782P7G.png
haproxy的配置:
: 全局配置段
主要用于定义haproxy进程自身的工作特性;
[proxies[: 代理配置段
backend: 后端服务器组
frontend: 定义面向客户端的监听的地址和端口,以及关联到的后端服务器组;
[一般是frontend调用backend]
listen: 组合方式直接定义frontend及相关的backend的一种机制;
defaults: 定义默认配置; =>不管哪种机制,都需要用到某些通用的配置,可以在defaults中定义
spread-checks50, ==>[这个数值是%比,如果是每隔3秒检查一次,那么,会分散到前1.5秒或后1.5秒检查,可以防止服务器突然压力过大]
下面开启配置haproxy 的日志信息
** /etc/haproxy/haproxy.cfg =>配置haproxy的工作机制
log 127.0.0.1 local2 ==>配置文件中定义了本机的日志记录在 local2上
切记这仅仅是定义具体实现在/etc/rsyslog.conf
**/etc/rsyslog.conf
要让haproxy记录系统日志 要确保/etc/rsyslog.conf 中的
$InputTCPServerRun 514 这一行开启,让其监听在 TCP的514端口上
local2.* /var/log/haproxy.log =>在/etc/rsyslog.conf 中添加这一项,记录 local2的所有级别的日志
配置好/etc/rsyslog.conf后 重启系统日志服务
service rsyslog restart
# ss -tnl=>检查, 系统tcp514端口已启动,能记录系统日志了
LISTEN 0 25 :::514 :::*
LISTEN 0 25 *:514 *:*
我们来了解一下,配置文件中的原有配置示例
frontend main *:5000 ==>前端定义了一个main的方法
acl url_static path_beg -i /static /images /javascript /stylesheets 定义usr_static 的目录法则
acl url_static path_end -i .jpg .gif .png .css .js 定义usr_static 的后缀法则
use_backend static if url_static =>如果满足条件则转发到一个名叫 static 的backend上,
default_backend app 否则默认发送到一个叫app的backend上
backend static
balance roundrobin =>轮询方式
server static 127.0.0.1:4331 check
backend app =>此处定义了app中,接受分发请求的主机ip地址
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
有了以上的知识和概念,我们可以依照博文开头处的实验环境,配置haproxy的分发机制了
设定frontend 为main 的所有ip都监听在80端口
frontend main *:80
default_backend app =>所有来的请求,一律交由 app 处理
backend app 定义backend 为app
balance roundrobin =>以轮询方式工作
server app 192.168.1.21 =>里面拥有两个可分发的主机
server app 192.168.1.22
重启服务 service haproxy restart
测试
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_14111046802nQ7.png
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_1411104682eaZI.png
已轮询成功
上面是haproxy 的基本用法, haproxy还有许多可定制的参数,如下
用绑定端口的方法,指定绑定要监听的端口
bind :80,443 ==>一般用在frontend中, 如果要指定多个监听端口的话,可以用" , " 分隔开
haproxy的轮询配置参数
balance=>一般用在backend中, 有各种轮询的方法 以下是各方法的详解
roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;
static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;
leastconn:新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重,支持慢启动; 短连接就不建议用了
source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;
建议用于tcp模式使用, 因为http模式,还有更高级的算法
相当于ipvs的sh算法, nginx的ip_hash算法
uri:对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性;
url_param:通过为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用hash-type修改此特性;
hdr():对于每个HTTP请求,通过指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.magedu.com来说,仅计算magedu字符串的hash值)以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性;
use_domain_only =>意思是只hash域名, 如
www.mageedu.com
mail.mageedu.com
ftp.mageedu.com 都只hash , mageedu.com
rdp-cookie
rdp-cookie(name):
frontend main
bind :80 ==>如果要指定多个监听端口的话,可以用" , " 分隔开
default_backend app =>所有来的请求,一律交由 app 处理
backend app 定义backend 为app
balance roundrobin =>以轮询方式工作
server app 192.168.1.21 =>里面拥有两个可分发的主机
server app 192.168.1.22
tune.maxaccept一批接受的最大请求数,默认单线程为100个,多线程为8个
“defaults”段用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定。
“frontend”段用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
“backend”段用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
“listen”整合frontend,backend 定义了一个完整的代理,通常只对TCP流量有用。
另附 haproxy的其它参数
1.1 cookiecookie_name
rewrite =>重写
insert =>插入
prefix =>作为前缀
indirect
nocache =>不缓存敏感信息
postonly
preserve
httponly
secure
domain
maxidle
maxlife
基本cookie的session绑定实现
backend webapp
balance roundrobin
cookie webappck insert nocache =>此处加上cookie参数 insert 插入方式写入cookie,并且不保存用户的敏感信息
server app1 192.168.1.21 cookie app1 并且标识cookie名
server app2 192.168.1.22 cookie app2
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_1411104689khvJ.png
打开chrome的调试器,可以看到, Set-Cookie:webappck=app2; 说明基于cookie的sesssion绑定已实现
1.2 mode
HAProxy有两种工作模式; 即调度时发生的协议层次 . 两种工作模式所能提供的功能是各不相同的, tcp只能以简单模式工作.
http:仅用于调度http协议的服务器
会对应用层数据做深入分析,因此支持7层过滤、处理、转换等机制
tcp:非http协议的服务器调度,包括https
默认模式,不会对应用层协议做任何检查;
通过在客户端和backend server之间建立一个全双工的连接 =>
hash-type
定义用于将hash码映射至后端服务器的方法;其不能用于frontend区段;可用方法有map-based和consistent,在大多数场景下推荐使用默认的map-based方法。
map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。
consistent:hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。
当所有的后端轮询主机都不可用时,又不希望用户看到不友好的错误信息,我们还可以设定一个sorryserver
只需要在要轮询的主机列表后,加一个主机ip, 并指明是backup属性即可
backend webapp
balance roundrobin
cookie webappck insert nocache
server app1 192.168.1.21 cookie app1 check port 80=>都检查节点的健康状态 必须检查端口,因为下面的backup server监听的是非80端口
server app2 192.168.1.22 cookie app2 check port 80
server sorry1 127.0.0.1:8080 backup =>因为haproxy已经监听在80端口上了,所以改不同的端口
保存配置文件, 重启 haproxy 服务
service haproxy restart
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_14111046918QCt.png
backup server 已然工作
1.4
我们还可以加最大连接请求限制
frontend main
bind :80
maxconn 6000 => 最大连接请求限制为6000个
default_backend webapp
backend webapp
balance roundrobin
cookie webappck insert nocache
server app1 192.168.1.21 cookie app1 check port 80 maxconn 4000 weight 2 可以自行安排, 如 app1性能好,可以多安排些,权重也可以设置高一些
server app2 192.168.1.22 cookie app2 check port 80 maxconn 2000 weight 1
server s1 127.0.0.1:8080 backup
附check有很多种, 还有mysql-check , http-check等方法
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.robert.com指明用httpchk检查
1.5 启动haproxy 状态页
backend webapp
balance roundrobin
cookie webappck insert nocache
server app1 192.168.1.21 cookie app1 check port 80 maxconn 4000 weight 2
stats enable =>在任一server后面 添加 stats enable
=>当然这些页面不是希望所有人都能看到的,要有验证机制
stats hide-version =>隐藏版本
stats scope . =>表示作用范围 仅为当前页面
stats uri /haproxyadmin?stats =>自定义状态页地址
stats realm Haproxy\ Statistics 配合 用户名和口令做认证
stats auth statsadmin:abcd1234 =>定义认证信息和口令
stats admin if TRUE =>开启管理功能 [如果认证通过的话] 如果希望 statsmaster也有这功能得在它后面的那行也加这一行内容
stats auth statsmaster:1234abcd
server app2 192.168.1.22 cookie app2 check port 80 maxconn 2000 weight 1
server s1 127.0.0.1:8080 backup
访问上述定义的地址,输入正确的用户名和口令即可访问
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_1411104694XznI.png
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_1411104700ciGc.png
还有一种定义的方法这种方法相对安全,但是可以提供的功能也少很多,看生产环境取舍吧
listen statss
bind:2009 =>指定监听的端口
stats enable =>在任一server后面 添加 stats enable
=>当然这些页面不是希望所有人都能看到的,要有验证机制
stats hide-version =>隐藏版本
stats scope . =>表示作用范围 仅为当前页面
stats uri /haproxyadmin?stats =>自定义状态页地址
stats realm Haproxy\ Statistics 配合 用户名和口令做认证
stats auth statsadmin:abcd1234 =>定义认证信息和口令
stats admin if TRUE =>开启管理功能 [如果认证通过的话] 如果希望 statsmaster也有这功能得在它后面的那行也加这一行内容
stats auth statsmaster:1234abcd
实现动静分离
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets定义为静态资源的目录
acl url_static path_end -i .jpg .gif .png .css .js .html 定义为静态资源的后缀
use_backend static if url_static =>如果满足静态资源特征,则分发到定义的 static 的backend
maxconn 6000
default_backend webapp
backend static
balance roundrobin
server static 192.168.1.21 =>定义静态资源主机ip
配置完成重启haproxy服务
#service haproxy restart
在两个节点的根目录下,都创建一个 images的目录,里面写入一个test.html的文件
节点1的内容为21test.html
节点2的内容为22test.html
http://robert1joy.blog.运维网.com/attachment/201409/19/4489523_1411104703Xqfx.png
从结果得知,很明显的,haproxy将其分发到 192.168.1.21的节点上了
如果遭到***了,怎么办呢?
backend dynamic
mode http
acl being_scanned be_sess_rate gt 50 =>如果每秒发起讲求超过50个,那么就认为遭到***了
redirect location /error_pages/denied.html if being_scanned =>将其引导到另一个显示页面
tcp-request inspect-delay 50ms => 如果不想使用上面的直接将其粗暴的引导到另一个显示内容 可以让请求在后边等待
tcp-request content accept if ! too_fast =>如果请求速率没超过,允许接入
tcp-request content accept if WAIT_END =>等待完成,可以接入
还可以基于请求的url头部来做分发条件,如
acl http url_beg http://
acl https url_beg https://
use_backend backend_http if http=>如果url满足http://开头则分发到定义的backend_http
use_backend backend_https if https=>如果url满足http://开头则分发到定义的 backend_https
页:
[1]