💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
HAProxy是一个开源的,高性能的,高可用的,可以支持TCP和HTTP的负载均衡代理服务软件。 * 支持双机热备 * 良好的服务器节点健康检查 * 故障节点服务器自动剔除 * 节点服务器恢复后自动加入负载集群的功能 * 能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作 * HAProxy是支持虚拟主机的,通过frontend指令来实现 * HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。 * 能对请求的url和header中的信息做匹配 * HAProxy的负载均衡算法现在也越来越多了,具体有如下8种: ①roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的; ②static-rr,表示根据权重,建议关注; ③leastconn,表示最少连接者先处理,建议关注; ④source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法 ⑤ri,表示根据请求的URI; ⑥rl_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name; ⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求; ⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。 ## HAProxy简介 HAProxy特别适用于高负载,访问量大,但又需要回话保持的七层应用的代理业务.HAProxy几乎不需要任何优化,就可以支持数以万计的并发链接.Haproxy的代理模式,使得所有的应用服务器不会被暴露到公网上。 从1.3版本开始,Haproxy引入了frontend和backend的概念,frontend(acl规则匹配)可以让运维管理人员根局任意的HTTP请求头做规则匹配,然后把请求定向到相关的backend。 HAproxy支持两种主要的代理模式: * 基于4层的tcp应用代理(例如:邮件服务,内部协议通信服务器,mysql,https服务等) * 基于7层的http代理。在4层tcp代理模式下,HAproxy尽在客户端和服务器之间进行流量转发。但是在7层http代理模式下,HAProxy会分析应用层协议,并且能通过允许,拒绝,交换,增加,修改或者删除请求(request)或者响应(response)里指定内容控制协议. ## 拓扑结构图 ### 四层代理 ![](https://box.kancloud.cn/2016-07-31_579dd7375b0c5.png) ### 七层代理 ![](https://box.kancloud.cn/2016-07-31_579dd73792910.png) ## 安装 > 本安装脚本基于操作系统Ubuntu14.04 Server 安装的shell脚本保存于https://github.com/hanxt/haproxy_setup/setup.sh, 如下: ``` #!/bin/bash ROOTPATH=`pwd` export LANG=en #wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.7.tar.gz; tar zxvf ./haproxy-1.6.7.tar.gz cd $ROOTPATH/haproxy-1.6.7 make TARGET=linux2628 ARCH=x86_64 sudo make PREFIX=/usr/local/haproxy-1.6.7 install sudo ln -s /usr/local/haproxy-1.6.7 /usr/local/haproxy; cd /usr/local/haproxy; sudo mkdir -p bin conf logs var/run var/chroot sudo useradd haproxy -s /sbin/nologin; sudo chown -R haproxy:haproxy /usr/local/haproxy/var/run/; sudo cp ./haproxy.cfg /usr/local/haproxy/conf; ``` > 查看README,可以获得关于更多的编译安装的帮助信息. 配置haproxy的日志环境,不同的操作系统配置方法不一致。 ``` # vim /etc/syslog.conf 添加: local0.* /usr/local/logs/haproxy.log local3.* /usr/local/logs/haproxy_err.log #vim /etc/sysconfig/syslog 修改: SYSLOGD_OPTIONS="-r -m 0" service syslog restart 注: -r enables logging from remote machines ``` #### 内核参数修改 > 注意:/etc/sysctl.conf为ubuntu系统内核参数修改文件,Centos待确认! net.ipv4.ip_forward = 1 #基于NAT模式的负载均衡器都需要打开系统转发的功能 ``` #使内核参数修改生效 sysctl -p ``` 其他的常用参数优化: ![](https://box.kancloud.cn/2016-07-31_579dd737cfb44.png) ## haproxy.conf配置文件说明 HAProxy配置文件总体分为五个部分: * global:全局配置参数段,主要用来控制HAProxy启动前的进程及系统相关设置. * defaults:配置一些默认参数,如果frontend,backend,listen等端未设置就使用defaults的配置. * listen:frontend和backend的组合体 * frontend:用来匹配接收客户所请求的域名,url等,并针对不同的匹配,做不同的请求处理. * backend:定义后端服务集群,以及后端服务器的权重,队列,连接数等选项。 ### 一个http负载均衡代理的配置模板 ``` global # 全局参数的设置 log 127.0.0.1 local0 info # log语法:log [max_level_1] # 全局的日志配置,使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备, 记录日志等级为info的日志 user haproxy group haproxy # 设置运行haproxy的用户和组,也可使用uid,gid关键字替代之 daemon # 以守护进程的方式运行 nbproc 16 # 设置haproxy启动时的进程数,根据官方文档的解释,我将其理解为:该值的设置应该和服务 #器的CPU核心数一致,即常见的2颗8核心CPU的服务器,即共有16核心,则可以将其值设置为: #<=16 ,创建多个进程数,可以减少每个进程的任务队列,但是过多的进程数也可能会导致进程 #的崩溃。这里我设置为16 maxconn 4096 # 定义每个haproxy进程的最大连接数 ,由于每个连接包括一个客户端和一个服务器端,所以单 #个进程的TCP会话最大数目将是该值的两倍。 #ulimit -n 65536 # 设置最大打开的文件描述符数,在1.4的官方文档中提示,该值会自动计算,所以不建议进行 #设置 pidfile /var/run/haproxy.pid # 定义haproxy的pid defaults # 默认部分的定义 mode http # mode语法:mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测 #,返回OK log 127.0.0.1 local3 err # 使用127.0.0.1上的syslog服务的local3设备记录错误信息 retries 3 # 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为 #不可用 option httplog # 启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[Jan 5 13 #:23:46] 日志服务器[127.0.0.1] 实例名已经pid[haproxy[25218]] 信息[Proxy http_80_in s #topped.]”,日志格式很简单。 option redispatch # 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证 #会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的 #,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常 option abortonclose # 当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接 option dontlognull # 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了 #探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描 #端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负 #载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来 option httpclose # 这个参数我是这样理解的:使用该参数,每处理完一个request时,haproxy都会去检查http头 #中的Connection的值,如果该值不是close,haproxy将会将其***,如果该值为空将会添加为: #Connection: close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该 #参数类似的另外一个参数是“option forceclose”,该参数的作用是强制关闭对外的服务通道 #,因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,如果客户端也不关 #闭,连接就会一直处于打开,直到超时。 contimeout 5000 # 设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout #connect替代,该参数向后兼容 clitimeout 3000 # 设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用 #timeout client替代。该参数向后兼容 srvtimeout 3000 # 设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用 #timeout server替代。该参数向后兼容 listen status # 定义一个名为status的部分,可以在listen指令指定的区域中定义匹配规则和后端服务器ip, #相当于需要在其中配置frontend,backend的功能。一般做tcp转发比较合适,不用太多的规则 #匹配。 bind 0.0.0.0:1080 # 定义监听的套接字 mode http # 定义为HTTP模式 log global # 继承global中log的定义 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版本信息 frontend http_80_in # 定义一个名为http_80_in的前端部分,haproxy会监听bind的端口 bind 0.0.0.0:80 # http_80_in定义前端部分监听的套接字 mode http # 定义为HTTP模式 log global # 继承global中log的定义 option forwardfor # 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获 #取到客户端的真实IP acl static_down nbsrv(static_server) lt 1 # 定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到 acl php_web url_reg /*.php$ #acl php_web path_end .php # 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,上面两种写 #法任选其一 acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$ #acl static_web path_end .gif .png .jpg .css .js .jpeg # 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif #结尾的,将会被匹配到,上面两种写法任选其一 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 backend php_server #定义一个名为php_server的后端部分,frontend定义的请求会到到这里处理 mode http # 设置为http模式 balance source # 设置haproxy的调度算法为源地址hash cookie SERVERID # 允许向cookie插入SERVERID,每台服务器的SERVERID可在下面使用cookie关键字定义 option httpchk GET /test/index.php # 开启对后端服务器的健康检测,通过GET /test/index.php来判断后端服务器的健康情况 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 2000 rise 3 fall 3 weight 1 server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup # server语法:server [:port] [param*] # 使用server关键字来设置后端服务器;为后端服务器所设置的内部名称[php_server_1],该名 #称将会呈现在日志或警报中、后端服务器的IP地址,支持端口映射[10.12.25.68:80]、指定该 #服务器的SERVERID为1[cookie 1]、接受健康监测[check]、监测的间隔时长,单位毫秒[inter #2000]、监测正常多少次后被认为后端服务器是可用的[rise 3]、监测失败多少次后被认为后端 #服务器是不可用的[fall 3]、分发的权重[weight 2]、最为备份用的后端服务器,当正常的服 #务器全部都宕机后,才会启用备份服务器[backup] backend static_server mode http option httpchk GET /test/index.html server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3 ``` ### tcp负载均衡的代理配置例子 ![](https://box.kancloud.cn/2016-07-31_579dd7382893b.png) ![](https://box.kancloud.cn/2016-07-31_579dd738449ed.png) 轮询测试: ![](https://box.kancloud.cn/2016-07-31_579dd738a4c9e.png) ## 实现haproxy启动/关闭/重启SHELL脚本 ``` #!/bin/bash #set -x # chkconfig 2345 on # description: HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high availability environments. if [ `whoami` = "root" ];then echo "root用户!" else echo "请使用root用户执行该命令,或者使用sudo!" exit 1; fi config="/usr/local/haproxy/conf/haproxy.cfg" exec="/usr/local/haproxy/sbin/haproxy" PID="/usr/local/haproxy/var/run/haproxy.pid" if [ -f $config ];then echo "" else echo "/usr/local/haproxy/conf/haproxy.cfg配置文件不存在,请检查" exit 1; fi RETVAL=0 start() { $exec -c -q -f $config if [ $? -ne 0 ]; then echo "Errors found in configuration file." return 1 fi echo -n "Starting HAproxy: " $exec -D -f $config -p $PID RETVAL=$? echo [ $RETVAL -eq 0 ] return $RETVAL } stop() { echo -n "Shutting down HAproxy: " kill `cat $PID` RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $PID return $RETVAL } restart() { $exec -c -q -f $config if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with 'haproxy check'." return 1 fi stop start } rhstatus() { status haproxy } check(){ $exec -c -f $config } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) rhstatus ;; check) check ;; *) echo $"Usage: haproxy {start|stop|restart|status|check}" RETVAL=1 esac exit $RETVAL ``` chmod +x /etc/init.d/haproxy 可通过以下命令实现haproxy的启动\关闭\重启等操作 service haproxy start/stop/restart service haproxy status 查看运行状态 出自:http://lxsym.blog.51cto.com/1364623/852363 ## 虚拟主机核心配置 如下配置中忽略了global,defaults等配置,案例如下: ``` frontend lvs2-lvs3 bind *:8080 acl is_lvs2 hdr_end(host) -i lvs2.test.net:8080 #使用hdr_end指令取request header中的host,如果host后缀部分匹配lvs2.test.net:8080,则匹配请求, #然后把请求打到对应use_backend指定的后端server上 acl is_lvs3 hdr_beg(host) -i lvs3.test.net:8080 #用于测试request header中的host前缀部分是否匹配到lvs3.test.net:8080 use_backend lvs2 if is_lvs2 #如果规则if指定的acl匹配,则打到use_backend指定的后端server上 use_backend lvs3 if is_lvs3 backend lvs2 #定义后端server balance roundrobin #采用轮询的负载均衡方法,网后端server转发请求 server free172 10.253.3.14:80 weight 10 server free173 10.253.3.15:80 weight 10 backend lvs3 balance roundrobin server free174 10.253.3.16:80 weight 10 server free173 10.253.3.15:80 weight 10 ``` ## 健康监测 1、通过监听端口进行健康检测 这种检测方式,haproxy只会去检查后端server的端口,并不能保证服务的真正可用。 ``` listen http_proxy 0.0.0.0:80 mode http cookie SERVERID balance roundrobin option httpchk server web1 192.168.1.1:80 cookie server01 check server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2 ``` 2、通过URI获取进行健康检测 这种检测方式,是用过去GET后端server的的web页面,基本上可以代表后端服务的可用性。 ``` listen http_proxy 0.0.0.0:80 mode http cookie SERVERID balance roundrobin option httpchk GET /index.html server web1 192.168.1.1:80 cookie server01 check server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2 ``` 3、通过request获取的头部信息进行匹配进行健康检测 这种检测方式,则是基于高级,精细的一些监测需求。通过对后端服务访问的头部信息进行匹配检测。 ``` listen http_proxy 0.0.0.0:80 mode http cookie SERVERID balance roundrobin option httpchk HEAD /index.jsp HTTP/1.1\r\nHost:\ www.xxx.com server web1 192.168.1.1:80 cookie server01 check server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2 ``` ## haproxy实现持久连接 1 调度算法source haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令) 配置指令 balance source 2 cookie 识别 haproxy 将WEB服务端发送给客户端的cookie中插入(或添加加前缀)haproxy定义的后端的服务器COOKIE ID。 配置指令例举 cookie SESSION_COOKIE insert indirect nocache 3 session 识别 haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。然后根据session分配后端server。 配置指令:appsession <cookie> len <length> timeout <holdtime> 详细参考:http://bbs.linuxtone.org/thread-9526-1-1.html ## 参考 http://leejia.blog.51cto.com/4356849/1421882 * 高可用 http://wgkgood.blog.51cto.com/1192594/961544 * 开启haproxy监控页面 和页面详细参数介绍 http://blog.csdn.net/dylan_csdn/article/details/51261421