Linux企业运维——HAProxy负载均衡
1、HAProxy简介
HAProxy是一种高效、可靠、免费的高可用及负载均衡解决方案,非常适合于高负载站点的七层数据请求。 因为HAProxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。客户端通过HAProxy代理服务器获得站点页面,而代理服务器收到客户请求后根据负载均衡的规则将请求数据转发给后端真实服务器。HAProxy还支持Session的保持和Cookie的引导。
1.1、HAProxy优缺点
优点: 1.支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机; 2.支持Session的保持,Cookie的引导;同时支持通过获取指定的url来检测后端服务器的状态。能够补充Nginx的一些缺点。 3.HAProxy跟LVS类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。 4.HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。 5.HAProxy负载均衡策略非常多,比如:动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和加权参数哈希(Weighted Parameter Hash) 6.免费开源,稳定性也是非常好,可以与LVS相媲美; 7.自带强大的监控服务器状态的页面,实际环境中我们结合Nagios进行邮件或短信报警;
缺点: 1.不支持POP/SMTP协议 SPDY协议; 2.不能做Web服务器,即不支持HTTP cache功能; 3.重载配置的功能需要重启进程,虽然也是soft restart,但没有Nginx的reaload更为平滑和友好; 4.多进程模式支持不够好;
1.2、4层负载均衡
将网络流量负载平衡到多个服务器的最简单方法是使用第4层(传输层)负载平衡。以这种方式进行负载均衡将根据IP范围和端口转发用户流量。用户访问负载均衡器,负载均衡器将用户的请求转发给后端服务器的Web后端组。无论选择哪个后端服务器,都将直接响应用户的请求。通常,Web后端中的所有服务器应该提供相同的内容 - 否则用户可能会收到不一致的内容。 
1.3、7层负载均衡
7层负载均衡是更复杂的负载均衡。网络流量使用第7层(应用层)负载均衡,允许负载均衡器根据用户请求的内容将请求转发到不同的后端服务器。这种负载平衡模式允许在同一域和端口下运行多个Web应用程序服务器。 
2、HAProxy工作原理
HAProxy有前端(frontend)和后端(backend),前端和后端都可以有多个。也可以只有一个listen块来同时实现前端和后端。 前端(frontend)区域可以根据HTTP请求的header信息来定义一些规则,然后将符合某规则的请求转发到相应后端(backend)进行处理。因此HAProxy可以实现动静分离(动静分离简单来说就是指将静态请求转发到对应的静态资源服务器,将动态请求转发到动态资源服务器),我们上篇说过的LVS就没有此功能。
3、HAProxy实验演练
3.1、HAProxy负载均衡
环境准备,在真实主机上为所有虚拟机配置域名解析  在server1上安装haproxy  编辑haproxy的配置文件 
stats uri /status
frontend main *:80
default_backend app
backend app
server app1 172.25.33.2:80 check
server app2 172.25.33.3:80 check
 server1启动haproxy服务,看到端口处于监听状态  server2和server3启动httpd服务   访问172.25.33.1进行测试,看到轮询请求  修改系统文件,添加如下配置   访问统计页面172.25.33.1/status  关闭server2的httpd服务  再次访问,请求都转发给了server3  在web统计页面也可以看到app1标红了,就是出现了问题无法工作 
3.2、身份验证
编译haproxy配置文件,输入用户名密码 (haproxy配置文件修改后,必须使用reload,不能restart,否则会使连接断开)   配置生效后访问web页面,需要登陆 
3.3、自定义路由监控器
可以将设置的符合监控条件的url转发到指定服务器
编译haproxy配置文件,并重新加载服务
- 当访问路径以/static /images等开头,以.jpg .gif等结尾时,跳入backend static模块,由该模块内server提供服务
  在server2网站目录内创建images文件夹并放入一张jpg格式的图片  现在访问172.25.33.1/images/rabbit.jpg,因为设置了自定义路由,可以访问到server2里的文件图片  另一个例子,我们监控php页面 首先,在server2中安装php  在server2网站目录下编写一个简单的php页面  在server1的haproxy配置文件中添加如下配置,然后重新加载服务   测试访问,可以看到我们在访问以.php结尾的url时,会访问到server2的php页面 
3.4、负载均衡权重
编译haproxy配置文件,将app1(也就是server2)的权重设置为2  重新加载haproxy服务  访问172.25.33.1,发现在轮询种server2占的次数是server3的两倍,因为haproxy中服务器默认权重是1,我们把server2设置为2,权重增加了 
3.5、设置备份服务器
在haproxy配置文件中添加如下备份服务器  重新加载服务  将server2和server3的httpd服务关闭   server1查看网络状态,httpd和haproxy的监听端口重复了  配置server1的httpd服务,将监听端口设置为8080  重启server1的httpd服务,现在可以看到8080端口处于监听状态  访问172.25.33.1,可以看到备份服务器生效 
3.6、haproxy日志管理
编辑文件,加入haproxy的日志信息   开启server2和server3的httpd服务   访问172.25.33.1,可以看到正常轮询  查看日志记录,可以看到访问记录 
3.7、访问黑名单与错误重定向
编辑haproxy的配置文件,添加黑名单  重新加载haproxy服务  用黑名单上的ip对应的主机对172.25.33.1进行访问,被拒绝  如果不想出现访问失败的页面,而是需要跳转到别的页面,我们可以在配置文件中添加如下配置   再次访问,可以看到没有报错页面,而是跳转到了配置文件中指定的页面 
3.8、访问重定向
我们也可以直接做如下配置,让所有对目标的访问都重定向到指定的url  编写一个简单的跳转页面  测试访问,发现页面被重定向到了我们刚才设置的跳转页面 
3.9、读写分离
目标:访问流量导向server3服务器,写入数据时导向server2服务器
在server2和server3上都安装php  在server2网站目录下创建index.php和upload_file.php,创建upload文件夹并赋予权限,用来接收访问者上传的文件  将上一步server2上创建的文件和文件夹发送给server3   编辑server1的haproxy配置文件 server3来接收访问流量,当写入数据时切换至server2  重新加载haproxy服务  现在测试,进行文件上传   查看日志  现在查看server2和server3的upload文件夹,发现我们上传的文件发送到了server2  
4、HAProxy高可用
4.1、pacemaker实现双机热备
真实主机上准备高可用插件的文件夹  server1修改软件仓库,配置高可用插件地址  安装高可用插件pacemaker  为了操作方便,server1生成免密操作密钥,发送给server4  将server1的仓库配置文件发送给server4  server1连接server4并为其安装相关高可用插件  开启server1和server4的pcsd服务,可以使用pcs命令  修改server1和server4的hacluster认证密码,然后认证  设定集群的名称为mycluster,集群内有server1和server4两个设备  启动集群内所有服务节点  查看状态,会出现如下报错,这个是没有Fencing设备时,没有禁用stonith功能,将其禁用就可以了  pcs property set stonith-enabled=false 禁用stonith功能,现在没有报警  在server4上安装haproxy,并将server1的haproxy配置文件发送给server4   server1和server4启动haproxy负载均衡,查看网络状态可以看到80端口处于监听状态   测试访问  查看pcs支持的脚本和提供者  配置集群管理VIP  可以看到集群状态里已经获取到了VIP信息,测试访问看到服务已经成功启动   在server1中将节点置为后备standby状态,pcs查看集群状态,看到vip现在运行在了server4节点  在server4中删除vip网络接口,因为server1节点已经为后备状态了,所以vip网络接口信息又会自动生成   停止haproxy,会出现下面报错  server1节点取消后备状态  server1和server4关闭haproxy服务 将haproxy添加到集群管理  查看集群状态,可以看到vip运行在server4节点,haproxy运行在server1节点  为了解决不同步的问题,我们将vip和haproxy放入同一个组  现在将server4设为后备状态,可以看到vip和haproxy都运行在了server1节点  取消server4的后备状态,看到vip和haproxy还是运行在server1节点  现在关闭server1的haproxy服务,查看集群运行状态,可以看到haproxy在server1节点的运行出行错误和警告  再次开启haproxy服务,集群运行恢复  再server1中输入命令echo c > /proc/sysrq-trigger ,让系统崩溃  现在再server4上查看集群状态,可以看到vip和haproxy服务都转移到了server4节点,并正常运行  
4.2、fence防止文件系统脑裂
Fence主要的作用是为防止二个服务器同时向资源写数据,破坏了资源的安全性和一致性从而导致脑裂的发生。
在server1和server4上安装客户端fence   查看fence设备和fence设备的元数据  真实主机安装fence组件  配置fence  此处根据自己的网卡名进行设置,这里接口选择br0桥接  查看到后续要生成的fence_xvm.key文件的存放位置 建立fence_xvm.key的存放目录,并生成fence_xvm.key文件,然后重启fence服务  在server1和server4上创建将要存放密钥文件的cluster目录,并将server1和server4节点添加到fence  真实主机将密钥文件发送到server1和server4的cluster目录下  查看集群状态,可以看到资源在server4节点,fence服务运行在server1  现在测试,关闭server4的网卡  可以看到server4重启后fence还在server4,防止资源争抢 
|