HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。另外其支持从4层至7层的网络交换,即覆盖所有的TCP协议,换而言之,Haproxy 甚至还支持Mysql的均衡负载。
HAProxy特别适用于那些负载特大的web站点, 这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
在功能上haproxy通过反向代理方式实现Web负载均衡,和nginx、ApacheProxy、lighttpd、Cheroke等一样。不同点在于,haproxy并不是Web服务器,前面提到的所有带反向代理负载均衡产品,都是Web服务器。简单来说就是,haproxy仅仅是一款负载均衡的应用代理程序,本身不提供Web服务。
haproxy配置简单,拥有非常不错的服务器健康检查功能,还有专门的系统状态监控页面。当其代理的后端服务器出现故障,haproxy会自动将该服务器剔除,故障恢复后再自动加入。
下载地址:https://github.com/haproxy/haproxy/releases/
(1).haproxy的负载均衡算法
haproxy的负载均衡算法配置在etc/haproxy.cfg中balance参数,与server参数配合使用。haproxy提供来8种负载均很算法:roundrobin根据权重轮询(动态)、static-rr根据权重轮询(静态)、source根据请求源IP、leastconn最少连接者先处理、uri根据请求的uri、url_param根据请求的url参数、rdp-cookie据据cookie(name)来锁定并哈希每一次请求、hdr(name)根据HTTP请求头来锁定每一次HTTP请求。
我是没发现动态权重分配和静态权重分配有什么区别。
详细查看:https://blog.csdn.net/eddie_cm/article/details/79796883
haproxy配置文件参数详细介绍:https://blog.csdn.net/wngua/article/details/54618299
(2).实验环境
youxi1 192.168.1.6 负载均衡器(haproxy)
youxi2 192.168.1.7 主机1
youxi3 192.168.1.8 主机2
(3).实验
1)负载均衡器youxi1上安装配置haproxy
安装依赖包
[root@youxi1 ~]# yum -y install make gcc gcc-c++ openssl-devel
将下载好的安装包上传到服务器上,解压安装
[root@youxi1 ~]# tar -xf haproxy-1.7.9.tar -C /usr/local/src/ //解压 [root@youxi1 ~]# cd /usr/local/src/haproxy-1.7.9/ [root@youxi1 haproxy-1.7.9]# cat README //找到如下部分 To build haproxy, you have to choose your target OS amongst the following ones and assign it to the TARGET variable : - linux22 for Linux 2.2 - linux24 for Linux 2.4 and above (default) - linux24e for Linux 2.4 with support for a working epoll (> 0.21) - linux26 for Linux 2.6 and above - linux2628 for Linux 2.6.28, 3.x, and above (enables splice and tproxy) - solaris for Solaris 8 or 10 (others untested) - freebsd for FreeBSD 5 to 10 (others untested) - netbsd for NetBSD - osx for Mac OS/X - openbsd for OpenBSD 5.7 and above - aix51 for AIX 5.1 - aix52 for AIX 5.2 - cygwin for Cygwin - haiku for Haiku - generic for any other OS or version. - custom to manually adjust every setting [root@youxi1 haproxy-1.7.9]# uname -r //与上面的信息对照,找到TARGET对应的值 3.10.0-957.el7.x86_64 //与其他的不同,这里使用的make生成的Makefile,不过虽然添加来参数但Makefile里根本没有写上,还得进去改 [root@youxi1 haproxy-1.7.9]# make TARGET=linux2628 PREFIX=/usr/local/haproxy [root@youxi1 haproxy-1.7.9]# vim Makefile //修改如下参数,也可以注意下CPU参数 PREFIX = /usr/local/haproxy //第94行 TARGET = linux2628 //第104行 [root@youxi1 haproxy-1.7.9]# make install install -d "/usr/local/haproxy/sbin" install haproxy haproxy-systemd-wrapper "/usr/local/haproxy/sbin" install -d "/usr/local/haproxy/share/man"/man1 install -m 644 doc/haproxy.1 "/usr/local/haproxy/share/man"/man1 install -d "/usr/local/haproxy/doc/haproxy" for x in configuration management architecture cookie-options lua WURFL-device-detection proxy-protocol linux-syn-cookies network-namespaces DeviceAtlas-device-detection 51Degrees-device-detection netscaler-client-ip-insertion-protocol close-options SPOE intro; do \ install -m 644 doc/$x.txt "/usr/local/haproxy/doc/haproxy" ; \ done [root@youxi1 haproxy-1.7.9]# echo $? 0 [root@youxi1 haproxy-1.7.9]# ls /usr/local/haproxy/ doc sbin share //总共就这三个目录,安装完成后看一下
手动创建haproxy配置文件
[root@youxi1 haproxy-1.7.9]# mkdir /usr/local/haproxy/etc [root@youxi1 haproxy-1.7.9]# vim /usr/local/haproxy/etc/haproxy.cfg global #全局配置 #定义全局的syslog服务器,最多可以定义两个。 #格式log [IP地址] [日志设备] [日志级别] #日志设备必须是以下24种标准syslog设备之一: #kern、user、mail、daemon、auth、syslog、lpr、news、uucp、cron、auth2、ftp、ntp、 #audit、alert、cron2、local0、local1、local2、local3、local4、local5、local6、local7 #这里的日志设备要与/etc/syslog.conf中定义的日志收集保持一致。 #日志级别有四种:err、warning、info、debug,默认为info log 127.0.0.1 local0 maxconn 4096 #最大连接数 chroot /usr/local/haproxy #当前工作目录 uid 99 #所属运行的用户uid,也可以使用user [用户名] gid 99 #所属运行的用户组id,也可以使用group [组名] daemon #以后台形式运行haproxy #启动haproxy进程个数。实际工作中,进程个数一般与CPU核心数一样。这样可以发挥出最大的性能 nbproc 1 pidfile /usr/local/haproxy/run/haproxy.pid #pid文件存放位置 #debug #调试模式,输出启动信息到标准输出。调错时使用 #quiet #静默模式,启动时无输出 defaults #默认设置 log global #应用全局的日志配置 #日志文件的输出定向。产生的日志级别为local3. 系统中local1-7,用户自己定义 log 127.0.0.1 local3 #工作模式,所处理的协议类型 #参数值可以为http|tcp|health,默认采用http模式 #tcp是4层,http是7层,health只会返回OK mode http option httplog #日志类别,记载http日志 #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式的实现 option httpclose option dontlognull #不记录空连接产生的日志 #如果后端服务器需要获得客户端真实ip,需要配置此参数,可以从Http Header中获得客户端ip option forwardfor option redispatch #当serverid对应的服务器挂掉后,强制定向到其他健康服务器 retries 2 #2次连接失败就认为服务器不可用,主要通过后面的check检查 maxconn 2000 #最大连接数 balance roundrobin #负载均衡算法 #haproxy监控页面的访问地址,可通过http://localhost:80/haproxy-stats访问 stats uri /haproxy-stats timeout connect 5000 #连接超时时间,单位:ms毫秒。等同contimeout timeout client 50000 #客户端连接超时时间。等同clitimeout timeout server 50000 #服务器端连接超时时间。等同srvtimeout mode http #健康检测,完整格式为option httpchk <method> <uri> <version> #注意实际工作中测试时,应该下载某一个页面来进行测试, #因此这个页面应该是个小页面,而不要用首页面。这里是每隔一秒检查一次页面。 option httpchk GET /index.html frontend http #前端配置,接收请求的端口组,http名称可自定义 bind 0.0.0.0:80 #监听端口,发起http请求到80端口,会被转发到设置的后端ip及端口 default_backend http_back #转发到后端,后端名http_back可以自定义 backend http_back #后端配置,后端名需要与前端配置的保持一致 server s1 192.168.1.7:80 weight 3 check #后端的主机IP、端口和权衡 server s2 192.168.1.8:80 weight 3 check #后端的主机IP、端口和权衡
上面的uid99,和gid99都是nobody,系统自带的。
[root@youxi1 haproxy-1.7.9]# id nobody uid=99(nobody) gid=99(nobody) 组=99(nobody)
另外,后端服务器配置格式为server [服务器名称] [IP地址:端口号] [参数],参数如下:
backup:设定为备用服务器,仅在负载均衡场景中的其他server均不可以启用此server check:启动对此server执行监控状态检查,其可以借助于额外的其他参数完成更精细的设定,如: inter: 设定监控状态检查的时间间隔,单位为毫秒,默认为2000,也可以使用fastinter和downinter来根据服务器端专题优化此事件延迟 rise:设定检查状态检查中,某离线的server从离线状态转换至正常状态需要成功检查的次数 fall:设定检查状态检查中,某离线的server从正常状态转换至离线状态需要成功检查的次数 cookie:为指定server设定cookie值,此处指定的值将会在请求入站时被检查,第一次为此值挑选的server将会倍后续的请求所选中,其目的在于实现持久连接的功能 maxconn:指定此服务器接受的最大并发连接数,如果发往此服务器的连接数目高于此处指定的值,其将被放置于请求队列,以等待其他连接被释放 maxqueue:通过观察服务器的通信状况来判断其健康状态,默认为禁用,其支持的类型有“layer 4”和“layer 7”,“layer 7”仅能用于http代理场景 redir:启用重定向功能,将发往此服务的GET和HEAD请求均以302状态码响应,需要注意的是,在prefix后面不能使用/,且不能使用相对地址,以避免造成循环,例如 server srv1 192..168.1.202:80 redir http://imageserver.wangfeng7399.com check weight: 权重,默认为1,最大值为256,0表示不参与负载均衡
配置文件参数详细查看:https://blog.csdn.net/wngua/article/details/54618299
生成haproxy的启动脚本,改太麻烦了直接复制好了。注意:这是解压目录下的examples/haproxy.init修改来的,不过reload是有问题的。想要reload需要手动输入命令。
[root@youxi1 haproxy-1.7.9]# vim /etc/init.d/haproxy #!/bin/sh # chkconfig: - 85 15 # description: HA-Proxy server # processname: haproxy # config: /usr/local/haproxy/etc/haproxy.cfg # Source function library. if [ -f /etc/init.d/functions ]; then . /etc/init.d/functions elif [ -f /etc/rc.d/init.d/functions ] ; then . /etc/rc.d/init.d/functions else exit 0 fi # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 # This is our service name BASENAME=`haproxy` BIN=/usr/sbin/haproxy CFG=/usr/local/haproxy/etc/haproxy.cfg [ -f $CFG ] || exit 1 PIDFILE=/usr/local/haproxy/run/haproxy.pid LOCKFILE=/usr/local/haproxy/run/haproxy RETVAL=0 start() { quiet_check if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with '$BASENAME check'." return 1 fi echo -n "Starting $BASENAME: " daemon $BIN -D -f $CFG -p $PIDFILE RETVAL=$? echo [ $RETVAL -eq 0 ] && touch $LOCKFILE return $RETVAL } stop() { echo -n "Shutting down $BASENAME: " killproc $BASENAME -USR1 RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $LOCKFILE [ $RETVAL -eq 0 ] && rm -f $PIDFILE return $RETVAL } restart() { quiet_check if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with '$BASENAME check'." return 1 fi stop start } reload() { if ! [ -s $PIDFILE ]; then return 0 fi quiet_check if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with '$BASENAME check'." return 1 fi $BIN -D -f $CFG -p $PIDFILE -sf $(cat $PIDFILE) } check() { $BIN -c -q -V -f $CFG } quiet_check() { $BIN -c -q -f $CFG } rhstatus() { status $BASENAME } condrestart() { [ -e $LOCKFILE ] && restart || : } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart) restart ;; reload) reload ;; condrestart) condrestart ;; status) rhstatus ;; check) check ;; *) echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}" exit 1 esac exit $? [root@youxi1 haproxy-1.7.9]# chmod +x !$ //添加执行权限 chmod +x /etc/init.d/haproxy
做一个软连接给启动脚本使用(添加环境变量没有试过),也可以直接复制过去
[root@youxi1 haproxy-1.7.9]# ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin/ [root@youxi1 haproxy-1.7.9]# ll /usr/sbin/haproxy lrwxrwxrwx 1 root root 31 7月 21 01:28 /usr/sbin/haproxy -> /usr/local/haproxy/sbin/haproxy
创建pid存放目录,并修改haproxy的所属主
[root@youxi1 haproxy-1.7.9]# mkdir /usr/local/haproxy/run [root@youxi1 haproxy-1.7.9]# chown -R nobody /usr/local/haproxy [root@youxi1 haproxy-1.7.9]# ll -d /usr/local/haproxy drwxr-xr-x 7 nobody root 64 7月 21 01:31 /usr/local/haproxy
配置日志收集文件
[root@youxi1 haproxy-1.7.9]# vim /etc/rsyslog.conf $ModLoad imudp//第15~16行去除注释 $UDPServerRun 514 local7.* /var/log/boot.log //这一行是第73行,在这一行下面添加两行 local3.* /var/log/haproxy.log //需要与上面的haproxy配置文件对应 local0.* /var/log/haproxy.log [root@youxi1 haproxy-1.7.9]# systemctl restart rsyslog
启动
#方法一 [root@youxi1 haproxy-1.7.9]# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.cfg [root@youxi1 haproxy-1.7.9]# ps aux | grep haproxy nobody 10654 0.0 0.0 12272 808 ? Ss 01:39 0:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.cfg root 10656 0.0 0.0 112724 996 pts/0 S+ 01:40 0:00 grep --color=auto haproxy #方法二 [root@youxi1 ~]# /etc/init.d/haproxy start Reloading systemd: [ 确定 ] Starting haproxy (via systemctl): [ 确定 ] [root@youxi1 ~]# ps aux | grep haproxy //两行Message信息提示服务器不可用,因为还没有配置,显示的比较慢,直接<Enter>就可以了 Message from syslogd@localhost at Jul 21 01:43:02 ... haproxy[10763]: backend http_back has no server available! Message from syslogd@localhost at Jul 21 01:43:02 ... haproxy[10763]: backend http_back has no server available! nobody 10763 0.0 0.0 12272 804 ? Ss 01:42 0:00 /usr/sbin/haproxy -D -f /usr/local/haproxy/etc/haproxy.cfg -p /usr/local/haproxy/run/haproxy.pid root 10766 0.0 0.0 112724 992 pts/0 S+ 01:43 0:00 grep --color=auto haproxy
特别说明reload手动输入命令该怎么做,主要是不停服务重新加载配置文件,平滑过渡
//首先使用ps aux | grep haproxy查看有几个进程 [root@youxi1 ~]# ps aux | grep haproxy nobody 7224 0.0 0.0 12272 828 ? Ss 16:57 0:00 /usr/sbin/haproxy -D -f /usr/local/haproxy/etc/haproxy.cfg -p /usr/local/haproxy/run/haproxy.pid root 7511 0.0 0.0 112724 996 pts/0 S+ 16:58 0:00 grep --color=auto haproxy //如果只有一个进程,那么把上面的命令复制一下,追加-sf [pid] [root@youxi1 ~]# /usr/sbin/haproxy -D -f /usr/local/haproxy/etc/haproxy.cfg -p /usr/local/haproxy/run/haproxy.pid -sf 7224 [root@youxi1 ~]# ps aux | grep haproxy nobody 7513 0.0 0.0 12272 824 ? Ss 17:00 0:00 /usr/sbin/haproxy -D -f /usr/local/haproxy/etc/haproxy.cfg -p /usr/local/haproxy/run/haproxy.pid -sf 7224 root 7516 0.0 0.0 112724 996 pts/0 S+ 17:00 0:00 grep --color=auto haproxy //如果是多个命令,或者不想看PID,也可以复制上面的命令,最佳-sf $(cat /usr/local/haproxy/run/haproxy.pid) [root@youxi1 ~]# /usr/sbin/haproxy -D -f /usr/local/haproxy/etc/haproxy.cfg -p /usr/local/haproxy/run/haproxy.pid -sf $(cat /usr/local/haproxy/run/haproxy.pid) [root@youxi1 ~]# ps aux | grep haproxy nobody 7532 0.0 0.0 12272 824 ? Ss 17:03 0:00 /usr/sbin/haproxy -D -f /usr/local/haproxy/etc/haproxy.cfg -p /usr/local/haproxy/run/haproxy.pid -sf 7513 root 7534 0.0 0.0 112724 992 pts/0 S+ 17:03 0:00 grep --color=auto haproxy
添加开机自启
[root@youxi1 ~]# chkconfig --add haproxy [root@youxi1 ~]# chkconfig --list haproxy haproxy 0:关 1:关 2:关 3:关 4:关 5:关 6:关 [root@youxi1 ~]# chkconfig haproxy on [root@youxi1 ~]# chkconfig --list haproxy haproxy 0:关 1:关 2:开 3:开 4:开 5:开 6:关
结束所有haproxy,使用killall(不要用killall5,好像会导致断开,可能是我用的有问题吧),如果没有killall使用命令yum -y install psmisc安装
[root@youxi1 ~]# killall haproxy [root@youxi1 ~]# ps aux | grep haproxy root 10786 0.0 0.0 112724 996 pts/0 S+ 01:44 0:00 grep --color=auto haproxy
如果防火墙开启来记得添加端口号
[root@youxi1 ~]# firewall-cmd --permanent --zone=public --add-port=80/tcp && firewall-cmd --reload success success
2)配置后端服务器youxi2和youxi3
我这边做实验,一切从简。
[root@youxi2 ~]# yum -y install httpd php [root@youxi2 ~]# echo youxi2 > /var/www/html/index.html [root@youxi2 ~]# systemctl start httpd [root@youxi2 ~]# systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. [root@youxi1 ~]# yum -y install httpd php [root@youxi1 ~]# echo youxi3 > /var/www/html/index.html [root@youxi1 ~]# systemctl start httpd [root@youxi1 ~]# systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
防火墙启动时记得添加端口号
[root@youxi2 ~]# firewall-cmd --permanent --zone=public --add-port=80/tcp && firewall-cmd --reload success success [root@youxi3 ~]# firewall-cmd --permanent --zone=public --add-port=80/tcp && firewall-cmd --reload success success
3)测试
首先查看下监控页面
然后直接访问负载均衡器
此时回头看监控页面,可以看出是平均分配的