Jusene's Blog

HAProxy 高性能负载均衡器

字数统计: 2.9k阅读时长: 13 min
2017/05/31 Share

HAProxy

最常见的负载均衡软件有:lvs、nginx、haproxy,而这三种中数lvs性能最好,能够负载的能力也最强,但提供的功能相对较少,且需结合keepalived来进行监控状态检查,在高并发的流量负载的生产环境下,lvs是不二的选择,而相对的nginx和haproxy,整体性能上都差不多,但haproxy提供的功能比nginx多的多,也更容易让我们管理集群和监控集群。

HAProxy提供了两种调度模式,tcp和http,相对的这也就是它可以完成四层调度和七层调度,整个haproxy的工作模型都是基于用户空间的socket进行完成的,所以haproxy受到了socket数的制约,它的并发量也就收到了限制,四层传输层调度也是通过socket模拟完成。

安装

官方网站: http://www.haproxy.org

haproxy已经被收入了base源,所以我们可以可以通过yum直接安装,haproxy版本较多,我这里安装的是1.5:

1
~]# yum install -y haproxy

配置文件

haproxy的配置参数有很多,可以提供丰富的定制代理,所以相对的配置文件也是可以千变万化,但整体构造如下:

global
proxies:

  • defaults
  • listen
  • frontend
  • backend

global

log:定义全局的syslog服务器,最多可以定义2个
chroot:安全设置
pidfile
maxconn 设定haproxy单个进程最大可以接受的并发数
user
group
daemon: 守护进程
stats: haproxy提供的socket文件来输出stats统计页
nbproc {number}:指明要启动的haproxy进程的数量
ulimit-n {number}: 每个haproxy进程所能够打开的最大文件数,haproxy会自动计算此数据

性能调整:
maxconn
maxpipes: haproxy使用pipe机制实现内核tcp报文重组,每进程所能使用的最大pipe数量,默认为maxconn/4

noepoll/nokqueue/nopoll/nosepoll:禁用事件机制
nosplice:禁用内核级tcp报文重组功能

spread-checks {0..50} 百分比,调动健康状态检测时间

debug配置参数:
debug
quiet

proxies

  • defaults: 为listen/frontend/backend提供默认值
  • frontend {name}: 定义监听的套接字,用于接受客户端请求并与之建立连接
  • backend {name}: 定义后端服务器组,用于处理frontend转发来的用户请求
  • listen {name}: 通过关联“前端”和“后端”定义一个完整proxy server
bind

bind [address]:port_range [, …] [param]bind
bind /path [, …] [param
]

1
listen http_proxy
2
    bind :80,:443
3
    bind 10.0.0.1:10080,10.0.0.1:10443
4
    bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy
balance

balance {algorithm} [ arguments ]
balance url_param param [check_post]

algorithm:

  • roundrobin: 动态算法,支持权重的运行时调整及慢查询机制,最大支持4095个后端主机
  • static-rr: 静态算法,不支持权重的运行时调整及慢查询机制,后端主机无上限
  • leastconn: 最少连接,推荐使用在较长时间会话的场景中;例如ldap,mysql等协议
  • first: 根据服务器中的位置,自上而下进行调度,前面的主机服务器达到上限,新请求将调度至下一个服务器
  • source: 源地址hash:
    取模法:将源地址hash计算后除以服务器总权重,服务器变动会影响全局调度效果,静态调度
    一致性hash:服务器变动仅影响局部调动,动态调度
    hash_type:指明hash计算方法,map-based:取模,consistent:一致性hash
  • uri:对uri的左半部分活着整个uri做hash计算,并由服务器的总权重相除后派发至挑选出后端主机,作用在于能够将对同一个uri请求始终法网发往同一个backend server,适合做缓存服务器的场景
  • url_param: 对用户请求的url中params中参数的值做hash计算,并由服务器的总权重相除后派发至某挑选出的后端主机,此算法常用于追踪标识,以确保来自同一用户的请求始终发往同一个backend server
  • hdr(name)对于每个http请求,通过name指定的http首部会被取出;此首部如果没有有效值,则轮询调度,否则,对其值进行hash计算,并由服务器的总权重相除后派发至某一挑选出的后端主机
  • rdp-cookie
  • rdp-cookie(name)
1
balance roundrobin
2
balance url_param userid
3
balance url_param session_id check_post 64
4
balance hdr(User-Agent)
5
balance hdr(host)
log

log global
log address [len (length)] facility [level[minlevel]]
no log
为每个实例启用事件和流量日志,可用于所以区段;每个实例最多指定两个log目标

compression

compression algo algoriyhm …
compression type mime type …
compression offload

支持的algo:

  • identity:通常仅debug时使用
  • gzip:
  • deflate:
  • type:压缩的mime类型,通常仅压缩文本类型的资源
1
compression algo gzip
2
compression type text/html text/plain
server

server name address[:[port]] [param*]
定义后端主机的服务器及其参数:

  • name:服务器的内部名称;如果设定了http-send-server-name,它还将被添加至发往此服务器的请求首部当中
  • address:服务器的地址,支持使用主机名
  • port:端口映射
  • params:参数
    • backup:设定备用服务器
    • check:对后端服务器做健康状态检查,无check时表示后端主机始终可用,同时可以使用很多辅助参数
  • – addr:通过此地址进行健康状态检查
  • – port:通过此端口进行健康状态检查
  • – inter (delay): 连续两次检测之间的时间间隔,默认2000ms
  • – fall (count): 连续多少次检测失败标记为失败
  • – rise (count): 连续多少次检测成功标记为成功
    • cookie (value): 当当前server指定cookie值,用于实现基于cookie的会话黏性
    • maxconn (maxconn): 当前服务器支持的最大并发连接数,超出此值将会被放入队列中
    • maxqueue (maxqueue): 当前服务器的队列上限
    • redir: 发往此服务器的所以get和head请求全部重定向至指定的地址
    • weight: 权重
1
server first  10.1.1.1:1080 cookie first  check inter 1000 maxconn 2000 maxqueue 200 weight 2
2
server second 10.1.1.2:1080 cookie second check inter 1000 fall 2 rise 1
option httpchk

option httpchk [method]
option httpchk [method] [uri]

定义基于7层健康状态检测

1
backend https_relay
2
    mode tcp
3
    option httpchk 
4
    server apache1 192.168.1.1:443 check port 80
maxconn

定义实例的最大并发连接数

mode

mode {tcp|http|health}
定义实例的工作模式:

  • tcp:当代理的为ssl,ssh,mysql等非http协议的使用;默认即为tcp
  • http:仅当代理的为http协议时使用
  • health:工作健康状态检查响应模式,当仅收到请求仅回应‘ok’即断开连接

cookie [name [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain domain ]

name: cookie的那段被监控修改或插入
rewrite:重写
insert:插入
prefix:加入前缀

基于cookie的黏性

1
cookie WEBSRV insert indirect nocache
2
server srv1 10.211.55.38 check cookie websrv1
3
server srv2 10.211.55.39 check cookie websrv2
stats
  • stats enable
    启用统计页:基于默认参数启用统计页
    stats url:/haproxy?stats
    stats realm: “HAProxy Statistics”
    stats scope: no restriction
  • stats uri 【prefix】
    统计页的访问uri
  • stats realm 【realm】
    设定认证时使用的realm
  • stats auth 【user】:【passwd】
    认证的账号和密码,可以使用多个
  • stats refresh 【delay】
    统计页的自动刷新事件间隔
  • stats show-desc 【str】
  • stats hide-version
  • stats admin {if | unless} 【cond】
    在指点的条件下启用admin功能
option forwardfor

把发往backend server的请求报文中添加X-Forwarded-For

option forwardfor [ except {network} ] [ header ] [ if-none ]
except network:来自于此网络的请求不添加
header name: 不使用默认的X-Forward-For,而使用此处定义的首部名称

reqadd reqdel rspadd rspdel rspidel

reqadd string [{if | unless} cond]
在请求报文尾部添加自定义的header

reqdel [search] [{if|unless} [cond]
reqdel [search] [{if|unless} (ignore case)]
基于模式删除匹配到的header即其值

rspadd rspdel rspidel
响应报文

errorfile
  • errorfile
    error code file
  • errorloc
  • errorloc302
    error code file
acl

acl [aclname] [criterion] [flags] [operator] [value] …

ceriterion:

1
dest ip
2
dest_port port
3
src ip
4
src_port port
5
6
path: string
7
	path     : exact string match
8
			path_beg : prefix match
9
			path_dir : subdir match
10
			path_dom : domain match
11
			path_end : suffix match
12
			path_len : length match
13
			path_reg : regex match
14
			path_sub : substring match
15
16
		url: string
17
			url     : exact string match
18
			url_beg : prefix match
19
			url_dir : subdir match
20
			url_dom : domain match
21
			url_end : suffix match
22
			url_len : length match
23
			url_reg : regex match
24
			url_sub : substring match
25
26
		urlp(<name>[,<delim>]) : string
27
url_param(<name>[,<delim>]) : string
28
	检查请求url中指定param的值
29
		urlp(<name>[,<delim>])     : exact string match
30
				urlp_beg(<name>[,<delim>]) : prefix match
31
				urlp_dir(<name>[,<delim>]) : subdir match
32
				urlp_dom(<name>[,<delim>]) : domain match
33
				urlp_end(<name>[,<delim>]) : suffix match
34
				urlp_len(<name>[,<delim>]) : length match
35
				urlp_reg(<name>[,<delim>]) : regex match
36
				urlp_sub(<name>[,<delim>]) : substring match
37
38
		req.hdr ([<name>[,<occ>]]) : string
39
			检查请求报文指定的首部的值
40
				hdr([<name>[,<occ>]])     : exact string match
41
				hdr_beg([<name>[,<occ>]]) : prefix match
42
			hdr_dir([<name>[,<occ>]]) : subdir match
43
				hdr_dom([<name>[,<occ>]]) : domain match
44
				hdr_end([<name>[,<occ>]]) : suffix match
45
				hdr_len([<name>[,<occ>]]) : length match
46
				hdr_reg([<name>[,<occ>]]) : regex match
47
				hdr_sub([<name>[,<occ>]]) : substring match
48
		method
49
		status
use_backend

use_backend [backend] [{if | unless} [condition]]

default_backend

default_backend backend

1
backend phpserv
2
  		balance roundrobin
3
  		cookie PHP insert indirect nocache
4
  		server phpsrv1 10.211.55.38 check weight 1 cookie phpsrv1 maxconn 300
5
  		server phpsrv2 10.211.55.39 check weight 2 cookie phpsrv2 maxconn 600
6
7
  	backend websrv
8
  		balance roundrobin
9
  		server websrv1 10.211.55.40 check maxconn 10000
10
  		server websrv2 10.211.55.41 check maxconn 10000
11
12
  	frontend mysrv
13
  		bind *:80
14
  		acl php path_end -i .php
15
  		use_backend phpserv if php
16
  		default_backend websrv
block

block {if | unless}

http-request http-response

http-request {deny|allow|auth} {if | unless} condition
http-response {deny|allow|auth} {if | unless} condition

tcp-request

tcp-request content [action] [{if | unless} condition]

1
acl is_host_com hdr(Host) -i example.com
2
tcp-request content accept if is_host_name
3
tcp-request content reject

实例

实例1

统计页

1
~]# cat /etc/haproxy/haproxy.cfg
2
glocal
3
	log 127.0.0.1 local2
4
	chroot /var/lib/haproxy
5
	pidfile /var/run/haproxy.pid
6
	maxconn 4000
7
	user haproxy
8
	group haproxy
9
	daemon
10
	stats socket /var/lib/haproxy/stats
11
12
default
13
	mode http
14
	log global
15
	option httplog
16
	option dontlognull
17
	option http-server-close
18
	option forwardfor except 127.0.0.0/0
19
	retries                 3
20
    timeout http-request    10s
21
    timeout queue           1m
22
    timeout connect         10s
23
    timeout client          1m
24
    timeout server          1m
25
    timeout http-keep-alive 10s
26
    timeout check           10s
27
    maxconn                 3000
28
29
listen stats
30
	bind :9001
31
	stats uri /haproxyadmin?stats
32
	stats realm Haproxy\ Stats
33
	stats auth admin:admin
34
	stats show-desc test
35
	stats admin if TRUE
36
	stats hide-version
37
	stats refresh 5s

实例2

listen反向代理,基于七层健康状态检测

1
listen web *:80
2
        balance roundrobin
3
        option httpchk GET /
4
        maxconn 5000
5
        server srv1 10.211.55.43 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200
6
        server srv2 10.211.55.48 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200

1
~]# curl 10.211.55.39
2
nginx1
3
~]# curl 10.211.55.39
4
nginx2

实例3

基于cookie的会话黏性

1
listen web *:80
2
        balance roundrobin
3
        option httpchk GET /
4
        maxconn 5000
5
        cookie WEBSRV insert indirect nocache
6
        server srv1 10.211.55.43 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200 cookie websrv1
7
        server srv2 10.211.55.48 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200 cookie websrv2

实例4

基于fortend和backend的动静分离

1
backend phpserver
2
	balance roundrobin
3
	cookie PHP insert indirect nocache
4
	server php1 10.211.55.48 check cookie php1 maxconn 300
5
	server php2 10.211.55.49 check cookie php2 maxconn 300
6
7
backend webserver
8
	balance roundrobin
9
	option httpchk GET /
10
	server web1 10.211.55.50 check maxconn 10000
11
	server web2 10.211.55.51 check maxconn 10000
12
13
backend jsserver
14
	balance roundrobin
15
	option httpchk GET /
16
	server js1 10.211.55.52 check maxconn 5000
17
	server js2 10.211.55.53 check maxconn 5000
18
19
frontend myweb 
20
	bind *:80
21
	acl php path_end -i .php
22
	acl js path_reg -i \.js|\.css|\.jpeg|\.png|\.swf
23
	use_backend phpserver if php
24
	use_backend jsserver if js
25
	default_backend webserver

实例5

删除响应报头的信息泄漏

1
listen web *:80
2
        balance roundrobin
3
        option httpchk GET /
4
        maxconn 5000
5
        rspidel X-Powered-BY:.*|Server:.*
6
        cookie WEBSRV insert indirect nocache
7
        server srv1 10.211.55.43 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200 cookie websrv1
8
        server srv2 10.211.55.48 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200 cookie websrv2

实例6

阻断请求,并重定向错误页

1
listen web *:80
2
        balance roundrobin
3
        option httpchk GET /
4
        maxconn 5000
5
        rspidel X-Powered-BY:.*|Server:.*
6
        acl bad_ip src 192.168.31.0/24 10.211.55.0/24
7
        block if bad_ip
8
        errorfile 403 /tmp/sorry.html
9
        cookie WEBSRV insert indirect nocache
10
        server srv1 10.211.55.43 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200 cookie websrv1
11
        server srv2 10.211.55.48 check inter 1000 fall 2 rise 1 maxconn 2000 maxqueue 200 cookie websrv2
CATALOG
  1. 1. HAProxy
    1. 1.1. 安装
    2. 1.2. 配置文件
      1. 1.2.1. global
      2. 1.2.2. proxies
        1. 1.2.2.1. bind
        2. 1.2.2.2. balance
        3. 1.2.2.3. log
        4. 1.2.2.4. compression
        5. 1.2.2.5. server
        6. 1.2.2.6. option httpchk
        7. 1.2.2.7. maxconn
        8. 1.2.2.8. mode
        9. 1.2.2.9. cookie
        10. 1.2.2.10. stats
        11. 1.2.2.11. option forwardfor
        12. 1.2.2.12. reqadd reqdel rspadd rspdel rspidel
        13. 1.2.2.13. errorfile
        14. 1.2.2.14. acl
        15. 1.2.2.15. use_backend
        16. 1.2.2.16. default_backend
        17. 1.2.2.17. block
        18. 1.2.2.18. http-request http-response
        19. 1.2.2.19. tcp-request
  2. 2. 实例
    1. 2.1. 实例1
    2. 2.2. 实例2
    3. 2.3. 实例3
    4. 2.4. 实例4
    5. 2.5. 实例5
    6. 2.6. 实例6