HAProxy
https://cbonte.github.io/haproxy-dconv/
简介
HAProxy是一个免费的负载均衡软件,可以运行于大部分主流的Linux操作系统上。HAProxy提供了L4(TCP)和L7(HTTP)两种负载均衡能力,具备丰富的功能。HAProxy具备媲美商用负载均衡器的性能和稳定性。
HAProxy的核心功能
- 负载均衡:L4和L7两种模式,支持RR/静态RR/LC/IP Hash/URI Hash/URL_PARAM Hash/HTTP_HEADER Hash等丰富的负载均衡算法
- 健康检查:支持TCP和HTTP两种健康检查模式
- 会话保持:对于未实现会话共享的应用集群,可通过Insert Cookie/Rewrite Cookie/Prefix Cookie,以及上述的多种Hash方式实现会话保持
- SSL:HAProxy可以解析HTTPS协议,并能够将请求解密为HTTP后向后端传输
- HTTP请求重写与重定向
- 监控与统计:HAProxy提供了基于Web的统计信息页面,展现健康状态和流量数据。基于此功能,使用者可以开发监控程序来监控HAProxy的状态
HAProxy的关键特性
性能好
单个HAProxy进程的处理能力突破了10万请求/秒,并轻松占满了10Gbps的网络带宽。HAProxy进程的消耗比其系统同类消耗的少20倍。
基于:
- A single-process:采用单线程、事件驱动、非阻塞模型,减少上下文切换的消耗,能在1ms内处理数百个请求。并且每个会话只占用几KB的内存。
- O(1) event checker:事件查看器允许其在高并发连接中对任何连接的任何事件实现即时探测。
- Delayed updates:使用惰性事件缓存对事件检查器进行的延迟更新可确保除非绝对必要,否则我们绝不会更新事件。
- Single-buffereing:单缓冲机制, 尽可能在读取和写入之间没有任何数据复制。这样可以节省大量CPU周期和有用的内存带宽。通常,瓶颈将是CPU和网络接口之间的I/O总线。在10-100 Gbps时,内存带宽也可能成为瓶颈。
- Zero-copy forwarding:零复制转发,使用Linux下的splice()系统调用来实现,在Linux kernel 3.5以上还支持零复制启动
- MRU:使用固定大小的内存池进行即时内存分配,这大大减少了创建新会话所需的时间。
- Tree-based storage:采用树型存储
- HAProxy大量利用操作系统本身的功能特性,使得其在处理请求时能发挥极高的性能,通常情况下,HAProxy自身只占用15%的处理时间,剩余的85%都是在系统内核层完成的。
稳定性好
作为单进程模式运行的程序,HAProxy对稳定性的要求是十分严苛的。HAProxy的大部分工作都是在操作系统内核完成的,所以HAProxy的稳定性主要依赖于操作系统,对sysctls参数进行精细的优化,并且确保主机有足够的内存。
负载均衡模式
无负载均衡
四层负载均衡
用户访问负载均衡器,负载均衡器将用户的请求转发给后端服务器的Web后端组。无论选择哪个后端服务器,都将直接响应用户的请求。通常,Web后端中的所有服务器应该提供相同的内容 - 否则用户可能会收到不一致的内容。
七层负载均衡
如果用户请求yourdomain.com/blog,则会将其转发到博客后端,后端是一组运行博客应用程序的服务器。其他请求被转发到web-backend,后端可能正在运行另一个应用程序。
安装
apt-get install haproxy
# 源码安装
# https://pkgs.org/download/haproxy
wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.2.tar.gz
tar -xzf haproxy-1.7.2.tar.gz
cd haproxy-1.7.2
make
make install
命令输出
Usage : haproxy [-f <cfgfile>]* [ -vdVD ] [ -n <maxconn> ] [ -N <maxpconn> ]
[ -p <pidfile> ] [ -m <max megs> ] [ -C <dir> ]
-v displays version ; -vv shows known build options.
-d enters debug mode ; -db only disables background mode.
-dM[<byte>] poisons memory with <byte> (defaults to 0x50)
-V enters verbose mode (disables quiet mode)
-D goes daemon ; -C changes to <dir> before loading files.
-q quiet mode : don't display messages
-c check mode : only check config files and exit
-n sets the maximum total # of connections (2000)
-m limits the usable amount of memory (in MB)
-N sets the default, per-proxy maximum # of connections (2000)
-L set local peer name (default to hostname)
-p writes pids of all children to this file
-de disables epoll() usage even when available
-dp disables poll() usage even when available
-dS disables splice usage (broken on old kernels)
-dV disables SSL verify on servers side
-sf/-st [pid ]* finishes/terminates old pids. Must be last arguments.
HAProxy基础配置
检查配置是否有错误:haproxy -c -f /etc/haproxy/haproxy.cfg
haproxy 配置/etc/haproxy/haproxy.cfg中分成五部分内容
- global: 设置全局配置参数,属于进程的配置,通常是和操作系统相关。
- defaults:配置默认参数,这些参数可以被用到frontend,backend,Listen组件;
- frontend:接收请求的前端虚拟节点(即HAProxy自身提供的服务),Frontend可以更加规则直接指定具体使用后端的backend;(一般直接使用listen)
- backend:后端服务集群的配置(即HAProxy后面接的服务),是真实服务器,一个Backend对应一个或者多个实体服务器;(一般直接使用listen)
- Listen :frontend和backend的组合体,示例如下
# HTTP listen nlb-8083 10.176.95.241:8083 mode http option httplog option httpclose balance roundrobin option redispatch option forwardfor server nlb6 10.176.11.59:8083 check inter 10s server nlb5 10.176.11.58:8083 check inter 10s # TCP listen old-nlb-server 10.176.15.241:18080 mode tcp balance roundrobin option redispatch server cyqnlb5 10.176.11.58:18080 check inter 10s server cyqnlb6 10.176.11.59:18080 check inter 10s
根据后端返回到结果调度ha
agent-check agent-inter 10s agent-port 19001
listen nrp-9002 10.195.0.251:9002
mode http
balance roundrobin
option redispatch
option httpchk GET /operation/internal/api/health/status
option httplog
server pub4-lxc4-nrp1 10.195.1.109:9001 check inter 10s rise 3 fall 3 agent-check agent-inter 10s agent-port 19001
server pub4-lxc5-nrp2 10.195.1.110:9001 check inter 10s rise 3 fall 3 agent-check agent-inter 10s agent-port 19001
| Text it sends back | Result |
|---|---|
| down | server is put into the down state |
| up | server is put into the up state |
| maint | server is put into maintenance mode |
| ready | server is taken out of maintenance mode |
| 50% | server’s weight is halved |
| maxconn:10 | server’s maxconn is set to 10 |
| drain | Set the weight to 0 and gradually drain the traffic from this server for maintenance |
| stop | Stop all traffic immediately, kill this backend server |
https://www.haproxy.com/blog/using-haproxy-as-an-api-gateway-part-3-health-checks/
配置参数讲解
global # 全局参数的设置
log 127.0.0.1 local0 info
# log语法:log [address] [device] [maxlevel] [minlevel]
# 如log 127.0.0.1 local0 info warning,即向本机rsyslog或syslog的local0输出info到warning级别的日志
# 其中[minlevel]可以省略。HAProxy的日志共有8个级别,从高到低为emerg/alert/crit/err/warning/notice/info/debug
user haproxy
group haproxy
# 设置运行haproxy的用户和组,也可使用uid,gid关键字替代之
daemon
# 以守护进程的方式运行
nbproc 16
# 设置haproxy启动时的进程数,默认启动1个进程
# 该值的设置应该和服务器的CPU核心数一致, ,创建多个进程数,可以减少每个进程的任务队列,但是过多的进程数也可能会导致进程的崩溃。
nbthread 4
# 线程数
maxconn 40960
# 定义每个haproxy进程的最大连接数,由于每个连接包括一个客户端和一个服务器端,所以单个进程的TCP会话最大数目将是该值的两倍。
# 会根据ulimit -n的值自动调整,不建议设置
pidfile /var/run/haproxy.pid
# 定义haproxy的pid
debug # debug mode
quiet # quiet mode
defaults # 默认部分的定义
mode http
# mode语法:mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测,返回OK
balance roundrobin
# 调度算法
# roundrobin 基于权重的轮询
# leastconn 最少连接数,适用于长连接的会话
# source 源地址hash,同一个客户端IP的请求始终被派发至某特定的服务器
# uri 基于uri生成hash表的算法,主要用于后端是缓存服务器
retries 3
# 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
option httpchk GET /bill/v1/health/status HTTP/1.0
# 开启对后端服务器的健康检测
option httplog
# 详细的记录http的请求信息,如果记录访问数据到文件的话。默认记录很简单,源目IP
option redispatch
# 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;\
而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
option abortonclose
# 当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option dontlognull
# 启用该项,日志中将不会记录空连接。
# 所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
option httpclose
# 表示在客户端和服务端完成第一次数据请求后,Haproxy将主动关闭此选项。
# 另外Haproxy在http mode下支持五种连接相应模式。默认是keep alive(option http-keep-alive),连接保持开放但是在相应结束之前和下一个新的请求来之间是空闲的
# 另外的tunnel ("option http-tunnel")在1.0-1.5-dev21的默认模式,只有第一个请求和响应才会出来,其他的只转发不做处理。不能用在http请求,问题很多
# 还有另外的两种:server close ("option http-server-close")、forced close ("option forceclose")
option forwardfor
# 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
timeout connect 5000
# haproxy连接RS最长时间,默认单位是毫秒
timeout client 3s
# 客户端发送数据时最长等待时间
timeout server 3s
# 服务器回应给客户端数据最长等待时间
##### server [name] [ip]:[port] [params]
server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
server php_server_2 10.12.25.72:80 cookie 2 check inter 2s rise 3 fall 3 weight 1
server php_server_bak 10.12.25.79:80 cookie 3 check inter 2s rise 3 fall 3 backup
# 使用server关键字来设置后端服务器
# 为后端服务器所设置的内部名称[php_server_1](该名称将会呈现在日志或警报中),
# 后端服务器的IP地址,支持端口映射[10.12.25.68:80]
# 指定该服务器的SERVERID为1[cookie 1]
# 接受健康监测[check]、监测的间隔时长,单位毫秒[inter 2000]、监测正常多少次后被认为后端服务器是可用的[rise 3]、监测失败多少次后被认为后端服务器是不可用的[fall 3]、\
# 分发的权重[weight 2]
# 最后为备份用的后端服务器,当正常的服务器全部都宕机后,才会启用备份服务器[backup]
##### acl [name] [criterion] [flags] [operator] [value]
acl white_list src 10.166.84.215 10.166.84.216
acl static_down nbsrv(static_server) lt 1
# 定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到
acl php_web url_reg /*.php$
# 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到
acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
# 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到
##### use_backend [backend] if\|unless [acl] 与ACL搭配使用,在满足/不满足ACL时转发至指定的backend
use_backend php_server if static_down
# 如果满足策略static_down时,就将请求交予backend php_server
use_backend php_server if php_web
# 如果满足策略php_web时,就将请求交予backend php_server
use_backend static_server if static_web
# 如果满足策略static_web时,就将请求交予backend static_server
listen status # 定义一个名为status的部分
bind 0.0.0.0:1080
# 定义监听的套接字
mode http
log global
stats refresh 30s
# stats是haproxy的一个统计页面的套接字,该参数设置统计页面的刷新间隔为30s
stats uri /admin?stats
# 设置统计页面的uri为/admin?stats
stats realm Private lands
# 设置统计页面认证时的提示内容
stats auth admin:password
# 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
stats hide-version
# 隐藏统计页面上的haproxy版本信息
haproxy+keepalived
haproxy配置主备需要保持一致,keepalived配置参考如下
主
vrrp_script chk_haproxy {
script "pidof haproxy" # 检查pid是否存在
interval 2
}
vrrp_instance VI_1 {
interface eth1
state MASTER
priority 200
virtual_router_id 33
unicast_src_ip primary_private_IP
unicast_peer {
secondary_private_IP
}
authentication {
auth_type PASS
auth_pass password
}
track_script {
chk_haproxy
}
notify_master /etc/keepalived/master.sh
}
备
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}
vrrp_instance VI_1 {
interface eth1
state BACKUP
priority 100
virtual_router_id 33
unicast_src_ip secondary_private_IP
unicast_peer {
primary_private_IP
}
authentication {
auth_type PASS
auth_pass password
}
track_script {
chk_haproxy
}
notify_master /etc/keepalived/master.sh
}
参考