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的关键特性
性能
-
采用单线程、事件驱动、非阻塞模型,减少上下文切换的消耗,能在1ms内处理数百个请求。并且每个会话只占用数KB的内存。
-
大量精细的性能优化,如O(1)复杂度的事件检查器、延迟更新技术、Single-buffereing、Zero-copy forwarding等等,这些技术使得HAProxy在中等负载下只占用极低的CPU资源。
-
HAProxy大量利用操作系统本身的功能特性,使得其在处理请求时能发挥极高的性能,通常情况下,HAProxy自身只占用15%的处理时间,剩余的85%都是在系统内核层完成的。
-
HAProxy作者在8年前(2009)年使用1.4版本进行了一次测试,单个HAProxy进程的处理能力突破了10万请求/秒,并轻松占满了10Gbps的网络带宽。
稳定性
作为建议以单进程模式运行的程序,HAProxy对稳定性的要求是十分严苛的。按照作者的说法,HAProxy在13年间从未出现过一个会导致其崩溃的BUG,HAProxy一旦成功启动,除非操作系统或硬件故障,否则就不会崩溃(我觉得可能多少还是有夸大的成分)。
在上文中提到过,HAProxy的大部分工作都是在操作系统内核完成的,所以HAProxy的稳定性主要依赖于操作系统,作者建议使用2.6或3.x的Linux内核,对sysctls参数进行精细的优化,并且确保主机有足够的内存。这样HAProxy就能够持续满负载稳定运行数年之久。
环境配置
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld &>/dev/null
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config
开启转发
vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_nonlocal_bind=1
net.ipv4.ip_forward = 1net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65023
net.ipv4.tcp_max_syn_backlog = 10240
net.ipv4.tcp_max_tw_buckets = 400000
net.ipv4.tcp_max_orphans = 60000
net.ipv4.tcp_synack_retries = 3
net.core.somaxconn = 10000sysctl -p
yum install haproxy -y
日志配置
在haproxy的配置文件中,默认已经绑定到local2上了,我们需要在rsyslog上关联下。
注:info级的日志会打印HAProxy处理的每一条请求,会占用很大的磁盘空间,在生产环境中,建议将日志级别调整为notice
为rsyslog添加haproxy日志的配置
vi /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerRun 514
$FileCreateMode 0644 #日志文件的权限
$FileOwner ha #日志文件的owner
local0.* /var/log/haproxy.log #local0接口对应的日志输出文件
local1.* /var/log/haproxy_warn.log #local1接口对应的日志输出文件
修改rsyslog的启动参数
vi /etc/sysconfig/rsyslog
# Options for rsyslogd
# Syslogd options are deprecated since rsyslog v3.
# If you want to use them, switch to compatibility mode 2 by "-c 2"
# See rsyslogd(8) for more details
SYSLOGD_OPTIONS="-c 2 -r -m 0"
重启rsyslog和HAProxy
service rsyslog restart
service haproxy restart
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
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
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode tcp
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
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:5000
mode http
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
#use_backend static if url_static
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
#backend static
# balance roundrobin
# server static 172.16.30.80:80 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
mode http
balance roundrobin
server app1 172.16.30.26:80 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
listen test1
bind 0.0.0.0:3307
mode tcp
balance roundrobin
server s1 172.16.30.26:3306 check
listen ssh
bind 0.0.0.0:3304
mode tcp
balance roundrobin
server s1 172.16.30.26:22 check
listen admin_stats
bind 0.0.0.0:8189
stats enable
mode http
log global
stats uri /haproxy_stats
stats realm Haproxy\ Statistics
stats auth admin:admin
#stats hide-version
stats admin if TRUE
stats refresh 30s
haproxy.cfg配置文件详解
global #全局设置
maxconn 10000 #最大连接数
stats socket /var/run/haproxy.stat mode 600 level admin
log 127.0.0.1 local0 #日志输出配置,所有日志都记录在本机,通过local0输出
uid 200 #所属运行的用户uid
gid 200 #所属运行的用户组
chroot /var/empty
daemon #以后台形式运行haproxy
defaults #默认设置
mode http #工作模式,支持TCP、http、health
log global #使用global的日志
option httplog #启用HTTP请求,会话状态和计时器的日志记录
option dontlognull #启用空连接不记录日志
monitor-uri /monitoruri
maxconn 8000 #设置最大套接字连接数
timeout client 30s #设置客户端的最长不活动时间
retries 2 #2次连接失败就认为服务器不可用,主要通过后面的check检查
option redispatch #当serverid对应的服务器挂掉后,强制定向到其他健康服务器
timeout connect 5s #设置等待连接尝试到服务器成功的最长时间。
timeout server 30s #设置服务器端的最长不活动时间。
timeout queue 30s #设置队列中等待连接池空闲的最长时间
stats uri /admin/stats #haproxy 监控页面的访问地址
stats auth admin:westos #设置监控页面的用户和密码
stats refresh 5s
mode { tcp|http|health } 设定实例的运行模式或协议。当实现内容交换时,前端和后端必须工作于同一种模式(一般说来都是HTTP模式),否则将无法启动实例。
tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;此为默认模式,通常用于SSL、SSH、SMTP等应用;
http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;
health:实例工作于health模式,其对入站请求仅响应“OK”信息并关闭连接,且不会记录任何日志信息;此模式将用于响应外部组件的健康状态检查请求;目前业讲,此模式已经废弃,因为tcp或http模式中的monitor关键字可完成类似功能;
frontend public #前台
bind *:80 name clear
default_backend dynamic
use_backend: 调用指定的后端主机(定义在frontend和listen中);
语法: use_backend backend [{if | unless} condition]condition 条件多为acl的名称
default_backend: 默认调用的后端主机;
语法:default_backend backend
# the application servers go here
backend dynamic #后台
balance roundrobin #负载均衡算法(轮循)
server web2 172.25.83.3:80 check inter 1000
server web2 172.25.83.3:80 check inter 1000
#check inter 1500 是检测心跳频率
balance 定义负载均衡算法(可用于“defaults”和“backend”)。
语法:balance algorithm [ arguments ]
algorithm用于在负载均衡场景中挑选一个server,其仅应用于持久信息不可用的条件下或需要将一个连接重新派发至另一个服务器时。
支持的算法有:roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;
static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;
leastconn:新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;
source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使hash-type修改此特性;
server 定义后端服务器
语法: server name address [param ]name:为此服务器指定的内部名称,其将出现在日志及警告信息中;如果设定了"http-send-server-name",它还将被添加至发往此服务器的请求首部中;
address:此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地
址;param:为此服务器设定的一系参数;其可用的参数非常多,具体请参考官方文档中的说明,下面仅说明几个常用的参数:
disabled:此服务器禁用;backup:设定为备用服务器,仅在负载均衡场景中的其它server均不可用才启用此server;
check:启动对此server执行健康状态检查,其可以借助于额外的其它参数完成更精细的设定;
inter delay:设定监控状态检查的时间间隔,单位为毫秒,默认为2000,也可以使用fastinter和downinter来根据服务器端专题优化此事件延迟;
rise count:设定检查状态检查中,某离线的server从离线状态转换至正常状态需要成功检查的次数;
fall count:设定检查状态检查中,某server从正常状态转换至离线状态需要成功检查的次数;
cookie value:为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现持久连接的功能;
maxconn maxconn:指定此服务器接受的最大并发连接数;如果发往此服务器的连接数目高于此处指定的值,其将被放置于请求队列,以等待其它连接被释放;
maxqueue maxqueue:设定请求队列的最大长度;0表示无上限;
weight weight:权重,默认为1,最大值为256,0表示不参与负载均衡;