haproxy简介
HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件。暂时不支持UDP协议
主要版本
版本1.8:多线程,HTTP / 2,缓存,动态服务器添加/删除,无缝重新加载,DNS SRV,硬件SSL引擎,...
版本1.7:增加了服务器热重新配置,内容处理代理,多种证书,... -
版本1.6:添加DNS解析支持,HTTP连接复用,完整的粘贴表复制,无状态压缩,...
版本1.5:添加SSL,IPv6,保持活着,DDoS保护,... -
1.4版:不需要SSL的人最稳定的版本。仍然提供客户端连接包活
高性能
- 单进程事件驱动的模型大大降低了上下文切换 和内存使用的成本 。在几毫秒内处理数百个任务是可能的,并且内存使用量是每个会话几千字节的数量级,而预先执行的或线程化的服务器中消耗的内存更多是每个进程的兆字节数量级。
- O(1)事件检查系统,允许它(Linux和FreeBSD),允许瞬间检测任何事件在成千上万的任何连接。
- 使用延迟事件缓存延迟对事件检查器的更新可确保我们绝不会在事件绝对需要的情况下更新事件。这节省了很多系统调用。
- 只要可能,在读写之间没有任何数据拷贝的单缓冲。这节省了大量的CPU周期和有用的内存带宽。通常,瓶颈将是CPU和网络接口之间的I / O总线。在10-100 Gbps时,内存带宽也可能成为瓶颈。
- 使用Linux下的splice()系统调用可以实现零拷贝转发,并且从Linux 3.5开始实现零拷贝。这允许一个小型3瓦设备(如希捷Dockstar)以千兆/秒的速度转发HTTP流量。
- MRU 内存分配器使用固定大小的内存池进行即时内存分配,有利于冷高速缓存中的热缓存区域。这大大缩短了创建新会话所需的时间。
- 工作分解(例如同时接受多个accept)以及在多进程模式下运行时限制每次迭代accept()的次数的能力,以便负载在进程间平均分配。
- 在多进程模式下运行时支持CPU亲和性,或者仅适应硬件,并尽可能靠近管理NIC的CPU内核,而不与其冲突。
- 基于树的存储,大量使用弹性二叉树我已经开发了好几年了。这用于保持定时器的有序性,以保持runqueue的有序性,以管理循环和最少连接队列,仅在O(log(N))成本中查找表中的ACL或密钥。
- 优化的定时器队列:如果定时器被推迟,定时器不会在树中移动,因为它们被满足的可能性接近于零,因为它们主要用于超时处理。这进一步优化了ebtree的使用。
- 优化的HTTP头分析:头文件被解析和动态解析,解析被优化以避免重新读取任何先前读取的内存区域。检查点用于当一个不完整的头部达到缓冲区的末端时,以便当更多的数据被读取时解析不会从头再次开始。在快速Xeon E5上解析平均HTTP请求通常需要半微秒。
- 仔细减少昂贵的系统调用的次数。大部分工作是在用户空间默认完成的,如时间读取,缓冲区聚合,文件描述符启用/禁用。
- 内容分析被优化为只携带指向原始数据的指针,并且除非数据需要被转换,否则不会复制。这确保了非常小的结构被转移,并且当不是绝对必要时内容不会被复制。
衡量负载平衡器性能有三个重要因素:
会话速率
会话并发性
数据转发速率
安全
建议使用root用户启动,因为可以使用chroot()提高提高系统安全性。
使用upd方式发送日志,提供较多排查信息。
配置文件格式
- 配置文件一行总是优先
- global,设置全过程参数
- 代理部分可以采取“default”,“listen”,
“frontend”和“backend”的形式。
测试配置命令:
$ haproxy -f configuration.conf -c
全局参数
-
Process management and security
- ca-base SSL CA证书目录,“ca-file”和“crl-file”指定的绝对位置为准
- chroot chroot目录
- crt-base 和ca-base类似
- daemon 守护进程方式
- gid 指定gid
- group
- log
- log-send-hostname
- nbproc
守护进程数量默认为1 - pidfile
- uid
- ulimit-n
- user
- stats
- ssl-server-verify
- node 此语句在两个或更多进程或服务器共享相同IP地址的HA配置中非常有用。通过在所有节点上设置不同的节点名称,很容易立即发现哪个服务器正在处理流量。
- description
- unix-bind
-
性能调整
- max-spread-checks
- maxconn 最大连接数
- maxconnrate
- maxcomprate
- maxcompcpuusage
- maxpipes
- maxsessrate
- maxsslconn
- maxsslrate
- noepoll 禁止在BSD上使用“kqueue”事件轮询系统。
- nokqueue
- nopoll 禁用在Linux上使用“epoll”事件轮询系统。
- nosplice 禁止在Linux上的套接字之间使用内核tcp连接。
- nogetaddrinfo
- spread-checks
- tune.bufsize
- tune.chksize
- tune.comp.maxlevel
- tune.http.cookielen
- tune.http.maxhdr
- tune.idletimer
- tune.maxaccept
- tune.maxpollevents
- tune.maxrewrite
- tune.pipesize
- tune.rcvbuf.client
- tune.rcvbuf.server
- tune.sndbuf.client
- tune.sndbuf.server
- tune.ssl.cachesize
- tune.ssl.lifetime
- tune.ssl.force-private-cache
- tune.ssl.maxrecord
- tune.ssl.default-dh-param
- tune.zlib.memlevel
- tune.zlib.windowsize
-
Debugging
- debug
- quiet
更多详细解释请参考官方文档
后端配置
“defaults”段用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定。
“frontend”段用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
“backend”段用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
“listen”段通过关联“frontend”和“backend”定义了一个完整的代理,通常只对TCP流量有用。
关键字段解析
1, balance
balance url_param [check_post []]
定义负载均衡算法,可用于“defaults”、“listen”和“backend”。用于在负载均衡场景中挑选一个server,其仅应用于持久信息不可用的条件下或需要将一个连接重新派发至另一个服务器时。支持的算法有:
roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;并支持慢启动。
static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;不支持慢启动,在高负荷的情况下,服务器重新上线时会立即被分配大量连接。
leastconn(WLC):适用于长连接的会话,新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;
source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;
对原地址hash,第一次调度时使用WLC
source:IP层,位于同一个NAT服务器背后的多个请求都会定向至同一个upstream server,不利于负载均衡,一般只有不支持使用cookie插入又需要保持会话时使用 cookie:应用层,有更好的负载均衡效果;
hash/weight%ip :除以权重取模
uri:对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性;
url_param:通过
hdr(
2, mode
tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;通常用于SSL、SSH、SMTP等应用;
http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;此为默认模式;
3, hash-type
map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。
consistent:“一致性哈希算法”,hash表是一个由各服务器填充而成的树状结构,将服务器散列在hash环上;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。
4,log address facility level
global:当前实例的日志系统参数同”global”段中的定义时,将使用此格式;每个实例仅能定义一次“log global”语句,且其没有任何额外参数;
5,maxconn
设定一个前端的最大并发连接数,因此,其不能用于backend区段。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出“global”段中的定义。此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,再加上其它的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护40000-50000并发连接。
如果为
6,server
后端声明一个server,因此,不能用于defaults和frontend区段。
:此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地址;
[:port]:指定将连接请求所发往的此服务器时的目标端口,其为可选项;未设定时,将使用客户端请求时的同一相端口;
[param*]:为此服务器设定的一系参数;其可用的参数非常多,具体请参考官方文档中的说明,下面仅说明几个常用的参数;
服务器或默认服务器参数:
backup:设定为备用服务器,仅在负载均衡场景中的其它server均不可用于启用此server;
check:启动对此server执行健康状态检查,其可以借助于额外的其它参数完成更精细的设定,如:
inter
rise
fall
cookie
maxconn
haproxy 有n个进程,每个支持m个连接,后端有x个服务器,每个最大支持y个连接,则 nm <= xy,如果后端服务器支持排队,则nm <= x(y+z),z为每个服务器的排队队列
maxqueue
observe
redir
weight
7,capture request header
capture request header
捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于frontend和listen区段。捕获的首部值使用花括号{}括起来后添加进日志中。如果需要捕获多个首部值,它们将以指定的次序出现在日志文件中,并以竖线“|”作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境中使用的“Host”、上传请求首部中的“Content-length”、快速区别真实用户和网络机器人的“User-agent”,以及代理环境中记录真实请求来源的X-Forward-For。
可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。
8, capture response header
capture response header
捕获并记录响应首部,其格式和要点同请求首部。
9,stats enable
示例:
stats enable
stats hide-version
stats scope .
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth statsadmin:password
stats auth statsmaster:password
10,option httplog
默认情况下,日志输入格式非常简陋,因为其仅包括源地址、目标地址和实例名称,而“option httplog”参数将会使得日志格式变得丰富许多,其通常包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部cookie、frontend、backend及服务器名称,当然也包括源地址和端口号等。
11,option forwardfor 添加X-forward-for,客户的真实IP地址。
option forwardfor [ except
if-none:仅在此首部不存在时才将其添加至请求报文问道中。
12,errorfile
在用户请求不存在的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中。
:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
13,ACL
haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两步,首先去定义ACL,譬如用来做动静分离,定义ACL的语法格式如下。
acl
[flags]:目前haproxy的acl支持的标志位有3个:
-i:不区分
-f:从指定的文件中加载模式;
--:标志符的强制结束标记,在模式中的字符串像标记符时使用;
整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;
字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在其之前使用“–”标志位;
正则表达式:其机制类同字符串匹配;
IP地址及网络地址
同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种:与(默认即为与操作)、或(使用||操作符)以及非(使用“!”操作符)。
hdr
hdr(header)
用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符。测试服务器端的响应报文时可以使用shdr()。例如下面的例子用于测试首部Connection的值是否为close。
hdr(Connection) -i close
method
method
测试HTTP请求报文中使用的方法。
path_beg
用于测试请求的URL是否以
acl url_static path_beg -i /static /images /javascript /stylesheets
path_end
用于测试请求的URL是否以
acl url_static path_end -i .jpg .gif .png .css .js
hdr_beg
用于测试请求报文的指定首部的开头部分是否符合
acl host_static hdr_beg(host) -i img. video. download. ftp.
hdr_end
用于测试请求报文的指定首部的结尾部分是否符合
定义独立日志
[root@hadoop01 haproxy]# vim /etc/sysconfig/rsyslog
SYSLOGD_OPTIONS="-r -c 2"
[root@hadoop01 haproxy]# vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514
local2.* /var/log/haproxy.log
Http代理示例:
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend web:
bind *:80
acl url_static path_beg -i /img
acl url_static path_end -i .jpg
use_backend web_static if url_static
default_backend webserver
backend web_static
balance roundrobin
server web_static 172.16.10.53:80 check maxconn 20000
backend webserver
balance roundrobin
server app1 172.16.10.53:80 check maxconn 20000
server app2 172.16.10.54:80 check maxconn 20000
listen statistics
bind *:8009
stats auth admin:admin # 统计页面用户名和密码设置
stats uri /admin?stats # 自定义统计页面的URL,默认为/haproxy?stats
stats hide-version # 隐藏统计页面上HAProxy的版本信息
stats refresh 30s # 统计页面自动刷新时间
stats admin if TRUE #如果认证通过就做管理功能,可以管理后端的服务器
stats realm Hapadmin # 统计页面密码框上提示文本,默认为Haproxy\ Statistics
MySQL代理示例:
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode tcp
log global
option tcplog
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend mysql
bind *:3306
mode tcp
log global
default_backend mysqlservers
backend mysqlservers
balance roundrobin
server ms1 172.16.10.53:3306 check inter 2 rise 1 fall 2 maxconn 400
server ms2 172.16.10.54:3306 check inter 2 rise 1 fall 2 maxconn 400
listen statistics
bind *:8009
mode http
stats auth admin:admin # 统计页面用户名和密码设置
stats uri /admin?stats # 自定义统计页面的URL,默认为/haproxy?stats
stats hide-version # 隐藏统计页面上HAProxy的版本信息
stats refresh 30s # 统计页面自动刷新时间
stats admin if TRUE #如果认证通过就做管理功能,可以管理后端的服务器
stats realm Hapadmin # 统计页面密码框上提示文本,默认为Haproxy\ Statistics
参考链接:
http://www.tianfeiyu.com/?p=1061
https://www.haproxy.org/download/1.5/doc/configuration.txt