1. HAProxy命令
HAProxy程序是通过将多个参数传递给haproxy命令启动的。
参数
-f: 加载的配置文件 , 或者后面跟文件所在的目录;如果后面接目录时,会自动加载非隐藏的.cfg结尾的文件。-D:程序以守护进程的方式运行。-V: 启用详尽模式(禁用静态模块)。-p: 指定pid文件位置-c: 运行前校验配置文件-d: 启用debug模式-m <limit>:限制所有程序占用的内存-n <limit>: 限制每个进程占用的连接数-sf <pid>*: 发送结束信号(SIGUSR1)给指定pid所在进程,接收到结束信号后原程序会结束现有任务之后再启动该进程。类似于重载配置文件。-st *: 发送立即结束信号(SIGTERM)。类似于重启软件-Ws:master-worker模式 , 支持notify类型的systemd服务。此选项仅在使用USE_SYSTEMD构建HAProxy时可用 , 构建选项已启用。-q: 启用安静模式,不会输出内容-v:显示版本和编译时间-vv: 显示版本,编译选项,库版本信息
常用命令如下:
# 检查配置文件语法
haproxy -c -f /etc/haproxy/haproxy.cfg
# 以daemon模式启动 , 以systemd管理的daemon模式启动
haproxy -D -f /etc/haproxy/haproxy.cfg [-p /var/run/haproxy.pid]
haproxy -Ds -f /etc/haproxy/haproxy.cfg [-p /var/run/haproxy.pid]
# 启动调试功能 , 将显示所有连接和处理信息在屏幕
haproxy -d -f /etc/haproxy/haproxy.cfg
# restart。需要使用st选项指定pid列表
haproxy -f /etc/haproxy.cfg [-p /var/run/haproxy.pid] -st `cat /var/run/haproxy.pid`
# graceful restart , 即reload。需要使用sf选项指定pid列表
haproxy -f /etc/haproxy.cfg [-p /var/run/haproxy.pid] -sf `cat /var/run/haproxy.pid`
# 显示haproxy编译和启动信息
haproxy -vv需要注意的是 , restart会直接关掉旧进程并建立新进程 , 所以会丢弃大量已建立的连接 , 而reload会启动新进程 , 但旧进程会先处理完当前已建立连接然后再关闭。但是,reload仍然会丢弃极少量的连接 , 虽然大多数情况下这足够完美了 , 但是在极度严格的环境下 ,这是不允许的。在haproxy 1.8中 , 提供了完全不丢弃连接的无损重启 , 要求haproxy启动命令中加入-x选项 , 同时要求haproxy配置文件的"stats socket"配置中加入expose-fd listeners , 比如:
stats socket /var/run/haproxy.sock mode 600 expose-fd listeners level user使用-x选项以及expose-fd listeners之后 , reload haproxy的时候 , 会将已建立TCP连接(TCP套接字)转移到Unix Domain状态套接字中进行处理。
2. 基础配置详解
HAPrpxy的配置文件haproxy.cfg由两大部分组成 , 分别是global和proxies部分。
global: 全局配置段进程及安全配置相关的参数
性能调整相关参数
Debug参数
proxies: 代理配置段default: 为frontend,backend,listen提供默认配置frontend: 前端,相当于nginx中的server{}backend: 后端,相当于nginx中的upsteam{}listen:同时拥有前端和后端配置
2.1 global配置
chroot: 锁定运行目录。daemon: 以守护进程运行user,group,uid,gid: 指定运行haproxy的用户,组,uid,gidnbproc: 开启的haproxy进程数,与CPU保持一致。在守护进程状态下默认值创建一个进程。当设置的值大于1时,线程将会自动禁用。但是多进程状态更难调试。2.5版本以后已经禁用该选项,全部功能迁移到到nbthread上。nbthread: 指定每个haproxy进程开启的线程数,默认为每个进程一个线程cpu-map: 绑定haproxy进程至指定的CPU核心上。cpu-map [auto:]<process-set>[/<thread-set>] <cpu-set>all | odd | even | number[-[number]] odd : 奇数 even :偶数 cpu-map 1-4 0-3 # bind processes 1 to 4 on the first 4 CPUs cpu-map 1/all 0-3 # bind all threads of the first process on the # first 4 CPUs cpu-map 1- 0- # will be replaced by "cpu-map 1-64 0-63" # or "cpu-map 1-32 0-31" depending on the machine's # word size. # all these lines bind the process 1 to the cpu 0, the process 2 to cpu 1 # and so on. cpu-map auto:1-4 0-3 cpu-map auto:1-4 0-1 2-3 cpu-map auto:1-4 3 2 1 0 # all these lines bind the thread 1 to the cpu 0, the thread 2 to cpu 1 # and so on. cpu-map auto:1/1-4 0-3 cpu-map auto:1/1-4 0-1 2-3 cpu-map auto:1/1-4 3 2 1 0 # bind each process to exactly one CPU using all/odd/even keyword cpu-map auto:all 0-63 cpu-map auto:even 0-31 cpu-map auto:odd 32-63 # invalid cpu-map because process and CPU sets have different sizes. cpu-map auto:1-4 0 # invalid cpu-map auto:1 0-3 # invalid # invalid cpu-map because automatic binding is used with a process range # and a thread range. cpu-map auto:all/all 0 # invalid cpu-map auto:all/1-4 0 # invalid cpu-map auto:1-4/all 0 # invalidmaxconn: 每个haproxy进程的最大并发连接数maxsslconn:SSL每个haproxy进程ssl最大连接数maxconnrate: 每隔进程每秒最大连接数spread-checks: 后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,成百上千个后端服务器可加此选项pidfile: 指定pid文件路径log 127.0.0.1 local3 info:定义全局的syslog服务器;最多可以定义两个log <address> <facility> [max level [min level]]stats:stats socket [<address:port>|<path>] [param*], 将UNIX套接字绑定到指定文件上,或者直接绑到<address:port>。连接此套接字将返回各种统计数据,甚至允许发出一i额命令来更改某些运行时的设置。paramgid <gid>/group <group>/uid <uid>/user <user>:设置套接字文件的gid/group/uid/user。mode <mode>: 设置套接字文件的权限process <process-set>[/<thread-set>]: 将具体的套接字绑定在具体的进程或线程上。主要是为了解决haproxy多进程之间信息处理问题。expose-fd listeners:这个选项只适用于stats套接字。这个选项可以让套接字有你能力监听另一个haproxy 进程的文件描述符。在master-wooker模式重新加载过程中,会自动使用-x选项,并会连接其中一个套接字文件。level <level>: 限制stats套接字的等级user: 最低等级。只显示不敏感的信息 , 无法更改任何内容operator: 默认等级。可以读取所有数据, 但是无法更改任何内容。admin: 可以做任何操作。读取任何数据, 更改内容
2.2 Proxies配置
在Haproxy中的代理的配置包括4个模块 : defaults、listen、frontend、backend。
defaults(defaults [<name>] [from <defaults_name>]): 用于为所有其它配置段提供默认参数 ,listen、frontend、backend将使用defaults中的设置 , 如果想通的参数被重复设置 , 那么listen、frontend、backend的优先级高于defaults。listen(listen <name> [from <defaults_name>]):定义一个完整的前端和后端代理 , 但后端可以不定义。所以有时候等价于frontend+backend。它常用于绑定前后端1对1的情况。frontend(frontend <name> [from <defaults_name>]):配置监听客户端连接的套接字。backend(backend <name> [from <defaults_name>]):配置haproxy所代理的后端服务器组。
注: 所有代理的名称只能使用大写字母、小写字母、数字、
-、_、.和:。
2.2.1 常用参数
option redispatch: 当server Id对应的服务器挂掉后 , 强制定向到其他健康的服务器 , 重新派发。sections:defaults,listen,backendoption abortonclose: 当服务器负载很高时 , 自动结束掉当前队列处理比较久的链接 , 针对业务情况选择开启。sections:defaults,listen,backendoption http-keep-alive: 开启与客户端的会话保持。sections:defaults,frontend,listen,backend非
Keep-Alive模式时 , 每个请求/应答客户和服务器都要新建一个连接 , 完成之后立即断开连接(HTTP协议为无连接的协议) ;当使用Keep-Alive模式时 ,Keep-Alive功能使客户端到服务器端的连接持续有效。option forwardfor: 透传客户端真实IP至后端web服务器。sections:defaults,frontend,listen,backendmode http|tcp: 设置默认工作类型,使用TCP服务器性能更好 , 减少压力。sections:defaults,frontend,listen,backendtcp: 该模式将在纯TCP模式下工作。全双工连接将在客户端和服务器之间建立 , 并且没有检查第七层。这是默认模式。http: 在http模式下工作。在连接到任何服务器之前 , 将对客户端请求进行深入分析。任何不符合RFC协议的请求都将被拒绝。将过滤、处理第七层数据
timeout http-keep-alive 120s:session会话保持超时时间 , 此时间段内会转发到相同的后端服务器。sections:defaults,frontend,listen,backendtimeout connect 120s: 客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前) , 默认单位ms。sections:defaults,listen,backendtimeout server 600s: 客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后) , 默认单位ms, 如果超时 ,会出现502错误 , 此值建议设置较大些 , 访止502错误。sections:defaults,listen,backendtimeout client 600s: 设置haproxy与客户端的最长非活动时间 , 默认单位ms, 建议和timeout server相同。sections:defaults,frontend,listentimeout check 5s: 对后端服务器的默认检测超时时间。sections:defaults,listen,backendbind:指定HAProxy的监听地址 ,可以是IPV4或IPV6, 可以同时监听多个IP或端口。sections:frontend,listenbind [<address>]:<prot_range> [, ...] [param*]bind /<path> [, ...] [param*]crt <cert>: 这个设置只有在支持OpenSSL的情况下才可用。它指定了一个包含所需证书和任何相关私钥的PEM文件。expose-fd listeners: 这个选项只适用于stats socket。它使你的统计套接字有能力将监听器FD传递给另一个HAProxy进程。在master-worker模式下 , 这不再是必需的 , 监听器将使用master和worker之间的内部套接字对来传递。gid <gid>/group <group>/uid <uid>/user <user>:设置套接字文件的gid/group/uid/user。mode <mode>: 设置套接字文件的权限process <process-set>[/<thread-set>]: 将具体的套接字绑定在具体的进程或线程上。主要是为了解决haproxy多进程之间信息处理问题。level <level>: 限制stats套接字的等级user: 最低等级。只显示不敏感的信息 , 无法更改任何内容operator: 默认等级。可以读取所有数据, 但是无法更改任何内容。admin: 可以做任何操作。读取任何数据, 更改内容
id <id>: 固定套接字的ID。默认情况下 , 套接字ID是自动分配的 , 但有时为了便于监控 , 固定套接字会更方便。这个值必须是严格的正数 , 并且在listen/frontend中是唯一的。这个选项只能在只定义一个套接字时使用。interface <interface>: 将套接字限制在一个特定的接口上。当指定时 , 只有从该特定接口收到的数据包才会被套接字处理。目前仅在Linux上支持该功能。该接口必须是一个主要的系统接口 , 而不是一个别名的接口。如果多个前台被绑定到不同的接口上 , 也可以将它们绑定到同一个地址上。注意 , 绑定到网络接口需要
root权限。这个参数只与TCPv4/TCPv6套接字兼容。当指定时 , 返回的流量使用与入站流量相同的接口及其相关的路由表 , 即使配置了通过不同接口的明确路由。当相同的客户端IP地址需要能够到达托管在不同接口上的前端时 , 这可以证明对解决非对称路由问题很有用。maxconn <maxconn>: 将套接字限制在这个并发连接数上。额外的连接将保留在系统的积压中 , 直到有连接被释放。如果没有指定 , 该限制将与前端的maxconn相同。注意 , 在端口范围或多个地址的情况下 , 相同的值将被应用于每个套接字。这个设置可以对昂贵的套接字进行不同的限制 , 例如 , SSL条目可能很容易消耗掉所有的内存。
name <name>, 为这些套接字设置一个可选的名称 , 该名称将在统计页面上报告。shards <number> | by-thread, 在多线程模式下 , 在支持同一IP:端口的多个监听器的操作系统上 , 这将自动为同一线路创建这个数量的多个相同的监听器 , 所有的监听器都被绑定在一个公平的线程数上。当使用非常大的线程数时 , 这有时会很有用 , 因为单个套接字上的内核锁开始导致显著的开销。在这种情况下 , 传入的流量被分配到多个套接字上 , 从而减少了争论。请注意 , 这样做很容易通过让更多的线程工作而增加CPU的使用率。如果分片的数量高于可用线程的数量 , 它将自动被修剪到线程的数量(即每个线程一个分片)。特殊的 "by-thread "值也会创建与 "bind "线上的线程数一样多的分片。由于系统将在所有这些分片之间均匀地分配传入的流量 , 所以这个数字是线程数的整数 , 这一点很重要。
ssl: 这个设置只有在支持OpenSSL的情况下才可用。它可以对从该监听器实例化的连接进行SSL破译。一个证书是必要的(见上面的 "crt")。缓冲区中的所有内容将以明文显示 , 因此ACL和HTTP处理将只能访问破译的内容thread [<thread-group>/]<thread-set>,这限制了允许该监听器运行的线程列表。它并不强制执行其中的任何一个 , 而是消除那些不匹配的。它限制了允许为这个监听器处理传入连接的线程。有两种编号方案。默认情况下 , 线程编号在进程中是绝对的 , 由
1和global.nbthread中指定的值组成。当启用线程组时 , 可以在线程范围前的斜线('/')前指定单个所需线程组的编号(从1开始)。在这种情况下 , 范围内的线程编号是相对于线程组而言的 , 每个线程组都从1开始。绝对线程编号和相对线程编号可以互换使用 , 但它们不能在单一的 "bind"行中混合使用 , 因为那些未设置的线程编号将在解析结束时被解决。对于不太可能出现的需要几个范围的情况 , 可以重复这个指令。即使使用多个指令 , 也不允许使用不同的线程组。<线程组>的规范必须使用这样的格式。
all | odd | even | number[-[number]]范围可以部分定义。上限可以省略。在这种情况下 , 它被相应的最大值所取代。主要目的是让多个绑定线在一个监听器中共享同一个 IP:port 但不是同一个线程 , 这样系统可以将进入的连接分配到多个队列中 , 绕过haproxy的内部队列负载平衡。目前已知Linux 3.9及以上版本支持这个功能。
listen http_proxy #监听http的多个IP的多个端口和sock文件 bind :80,:443,:8801-8810 bind 10.0.0.1:10080,10.0.0.1:10443 bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy listen http_https_proxy #https监听 bind :80 bind :443 ssl crt /etc/haproxy/site.pem listen http_https_proxy_explicit #监听IPv6、IPv4和unix sock文件 bind ipv6@:80 bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem bind unix@ssl-frontend.sock user root mode 600 accept-proxy listen external_bind_app1 #监听file descriptor bind "fd@${FD_APP1}" use_backend <backend> [{if | unless} <condition>]: 在符合指定条件之后,切换至指定的backend。sections:frontend,listen。default_backend <backend>: 当未匹配到use_backend的规则时,使用default_backend指定的backend。sections:defaults,frontend,listen。redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]: 重定向到指定的PREFIX上redirect prefix https://mysite.com if login_page !secureserver: 声明后端real server。sections:listen,backend。server <name> <address>[:[port] [param*]param*backup: 将后端服务器标记为备份状态disbaled: 将后端服务器标记为不可用状态no-check: 重置server的配置。将参数重置为default-server选项指定的参数checkinter <delay>: 健康状态检查间隔时间,默认2000msrise <count>: 后端服务器从下线回复检查次数 , 默认为2fall <count>: 后端服务器失效检查次数,默认为3
addr IP: 可指定的健康状态监测IPport num: 指定的健康状态监测端口send-proxy: 参数强制要求在任何建立到该服务器的连接上使用PROXY协议。PROXY协议通知另一端关于传入连接的3/4层地址 , 这样它就可以知道客户的地址或它访问的公共地址 , 不管上层协议是什么。对于由 "accept-proxy"或 "accept-netscaler-cip"监听器接受的连接 , 将使用公布的地址。只有TCPv4和TCPv6地址系列被支持。其他家族 , 如Unix套接字 , 将报告一个UNKNOWN家族。使用这个选项的服务器可以完全连接到另一个HAProxy监听实例 , 并设置为 "accept-proxy"。如果服务器没有意识到该协议 , 则不得使用该设置。当健康检查被发送到服务器时 , 除非有明确的 "port"或 "addr"指令, 在这种情况下 , 还需要明确的 "check-send-proxy"指令来使用PROXY协议 , 当这个选项被设置时 , 会自动使用PROXY协议。cookie <value>: 为指定server设定cookie值 , 指定的值将在请求入站时被检查, 第一次为此值挑选的server将在后续的请求中被选中 , 其目的在于实现基于客户端cookie的持久连接;maxconn <maxconn>: 当前后端server的最大并发连接数backlog <backlog>: 当server的连接数达到上限后的后援队列长度maxqueue <maxqueue>: 设定请求队列的最大长度observe <mode>: 这个选项在观察与服务器通信的基础上启用健康调整。默认情况下 , 这个功能是禁用的 , 启用它还需要启用健康检查。有两种支持的模式 : "layer4"和 "layer7"。在layer4模式下 , 只有成功/不成功的tcp连接是重要的。在第7层 ,只允许http代理 , 从服务器收到的响应被验证 , 如有效/错误的http代码、不可解析的头文件、超时等。有效的状态代码包括100到499,501和505。
redir <prefix>: 启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应,意味着不会将请求转发至后端服务器;在prefix后面不能使用/,且不饿能使用相对地址server srv1 192.168.1.1:80 redir http://image1.mydomain.com checkweight <weight>:指定real server权重。 默认为1,最大值为256,0表示不参与负载均衡,即认为下线了不进行调度on-marked-down shutdown-sessions:使HAproxy在后端宕机时关闭所有现有的连接。通常情况下 ,HAProxy允许现有的连接完成 ,这可能会导致重复的主键(如果连接继续工作)或查询超时(如果它不工作)。
default-server [param*]: 指定后端服务器的默认设置, 参数基本与server上的参数一样。sections:defaults,listen,backenddefault-server inter 1000 weight 3log:为每个实例启用事件和流量日志 , 因此可用于所有区段。每个实例最多可以指定两个log参数。配置方法和意义同前文全局配置参数的log。sections:defaults,frontend,listen,backend。log global log <address> <facility> [<level> [<minlevel>]] no log如果使用
log global, 则表示从全局继承日志设置。另外 , 如果全局已经定义过两个log了 ,此处除引用global外还自定义了一个log , 则此自定义的log失效 , 因为只支持两个日志设置。maxconn:设置frontend的并发连接的最大数量。sections:defaults,frontend,listen。errorfile <code> <file>:HAproxy生成对应code值时返回指定文件的内容。sections:defaults,frontend,listen,backend。
示例
frontend WEB_PORT_80
bind 192.168.7.248:80
mode http
user_backend web_port_http_nodes
backend web_port_http_nodes
mode http
option forwardfor
server 192.168.7.101 192.168.7.101:8080 check inter 3000 fall 3 rise 5
server 192.168.7.102 192.168.7.102:8080 check inter 3000 fall 3 rise 5
使用listen替代frontend+backend;
listen WEB_PORT_80
bind 192.168.7.102:80
mode http
option forwardfor
server web1 192.168.7.101:80 check inter 3000 fall 3 rise 5
server web2 192.168.7.101:80 check inter 3000 fall 3 rise 52.3 用户列表
userlist <listname>group <groupname> [users <user>,<user>,(...)]:
用于对haproxy状态监控页面的用户认证。至少要定义一个用户列表并且添加一个用户 密码可以加密或明文。
userlist L1
group G1 users tiger,scott
group G2 users xdb,scott
user tiger password $6$k6y3o.eP$JlKqe4(...)xHSwRv6J.C0/D7cV91
user scott insecure-password elgato
user xdb insecure-password hello
userlist L2
group G1
group G2
user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
user scott insecure-password elgato groups G1,G2
user xdb insecure-password hello groups G2