知识库

标准化实施手册及常见错误


nginx高可用集群方案

<h1>一、目的</h1> <p>目前越来越多的线上环境都采用nginx做反向代理、负载均衡,为了避免因为负载均衡服务器的宕机从而影响整个系统运行的问题,需要建立一个备份机。主服务器和备份服务器上都运行监控程序,通过传送心跳信息来监控对方的运行状况。当备份服务器在一定的时间内没有收到主服务器的心跳信息时,它就自动接管主服务器的服务IP,继续提供负载均衡服务;当备份服务器又从主服务器收到心跳信息时,它就释放服务IP地址,这样的主服务器就开始再次提供负载均衡服务,由此引出该方案,负载均衡服务器主备冗余,实现高可用。</p> <h1>二、高可用技术方案</h1> <p>采用keepalived+NGINX实现主备、负载均衡</p> <h1>三、keepalived工作原理</h1> <p>Keepalived高可用服务对之间的故障切换转移,是通过VRRP来实现的。在keepalived服务工作时,主Master节点会不断地向备节点发送(多播的方式)心跳消息,用来告诉备Backup节点自己还活着。当主节点发生故障时,就无法发送心跳的消息了,备节点也因此无法继续检测到来自主节点的心跳了。于是就会调用自身的接管程序,接管主节点的IP资源和服务。当主节点恢复时,备节点又会释放主节点故障时自身接管的IP资源和服务,恢复到原来的备用角色。 <img src="http://60.191.64.5:16100/server/index.php?s=/api/attachment/visitFile/sign/b53dd404c69ad456a1a2310095e08ff8" alt="" /></p> <h1>四、keepalived实现主备机冗余功能</h1> <p>1.当nignx负载均衡服务器发生宕机时,keepalived通过主备机共用VIP,VIP对外提供访问,主机宕机了,备机会立即启动将VIP占用,接替主机的工作。 2、对后端的web服务器负载均衡(冗余)+健康监测 Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。</p> <ul> <li>服务器分配(可根据服务器数量自行分配)</li> </ul> <table> <thead> <tr> <th style="text-align: left;">服务器</th> <th style="text-align: left;">IP</th> <th style="text-align: left;">端口</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">VIP</td> <td style="text-align: left;">192.168.5.198</td> <td style="text-align: left;"></td> </tr> <tr> <td style="text-align: left;">nginx主机:node1</td> <td style="text-align: left;">192.168.5.160</td> <td style="text-align: left;">7001</td> </tr> <tr> <td style="text-align: left;">nginx备机:node2</td> <td style="text-align: left;">192.168.5.162</td> <td style="text-align: left;">7001</td> </tr> <tr> <td style="text-align: left;">web01</td> <td style="text-align: left;">192.168.5.160</td> <td style="text-align: left;">8081</td> </tr> <tr> <td style="text-align: left;">web02</td> <td style="text-align: left;">192。168.5.162</td> <td style="text-align: left;">8081</td> </tr> <tr> <td style="text-align: left;">...</td> <td style="text-align: left;">...</td> <td style="text-align: left;">...</td> </tr> </tbody> </table> <h1>五、实现过程</h1> <h2>安装keepalived</h2> <p><strong>keepalived源码包下载地址</strong>:<a href="http://101.69.243.254:5010/share/MQhhdxSV">http://101.69.243.254:5010/share/MQhhdxSV</a></p> <h4>1.新建keepalived安装目录:</h4> <pre><code class="language-java">mkdir -p /risen/soft/keepalived</code></pre> <h4>2.下载安装包至/risen/soft/package</h4> <h4>3.检查依赖</h4> <pre><code class="language-java">centos:yum install -y gcc libnl libnl-devel libnfnetlink-devel openssl-devel ubantu、麒麟:apt-get install -y gcc libnl libnl-devel libnfnetlink-devel</code></pre> <h4>4.源码解压编译安装</h4> <pre><code class="language-java">tar -xvf /risen/soft/package/keepalived-2.2.4.tar.gz -C /risen/soft/package</code></pre> <p><strong>切换目录:</strong></p> <pre><code class="language-java">cd /risen/soft/package/keepalived-2.2.4 chmod +x ./configure &amp;amp;&amp;amp; ./configure --prefix=/risen/soft/keepalived &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install</code></pre> <h4>5.开机自启</h4> <pre><code class="language-java">cp /risen/soft/package/keepalived-2.2.4/keepalived/etc/init.d/keepalived /etc/init.d/</code></pre> <p>需要提前在/etc下创建keepalived目录</p> <pre><code class="language-java">cp /risen/soft/package/keepalived-2.2.4/keepalived/etc/init.d/keepalived /etc/init.d/ mkdir -p /etc/keepalived cp /risen/soft/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ cp /risen/soft/keepalived/etc/sysconfig/keepalived /etc/sysconfig/</code></pre> <pre><code class="language-java">启动 systemctl start keepalived.service 关闭 systemctl stop keepalived.service 重启 systemctl restart keepalived.service 开机自启 systemctl enbale keepalived.service</code></pre> <h4>6.修改keepalivd配置文件(NODE1和NODE2)</h4> <p>配置文件路径:/etc/keepalived/keepalived.conf。建议下载修改,修改完重新上传 node1配置文件参考:</p> <pre><code class="language-java">! Configuration File for keepalived global_defs { router_id node1 vrrp_garp_interval 0 vrrp_gna_interval 0 } #检测脚本 vrrp_script chk_http_port { script &amp;quot;/risen/sh/check_nginx_pid.sh&amp;quot; #心跳执行的脚本,检测nginx是否启动 interval 2 #(检测脚本执行的间隔,单位是秒) weight 2 #权重 } vrrp_instance VI_1 { state MASTER #指定keepalived的角色,MASTER为主,BACKUP为备 interface ens192 # 网卡名,用ifconfig查看你具体的网卡 virtual_router_id 66 # 虚拟路由编号,主从要一致 priority 100 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信 auth_pass 2222 } track_script { chk_http_port #(调用检测脚本) } virtual_ipaddress { 192.168.5.198 # 定义虚拟ip(VIP),可多设,每行一个 } } virtual_server 192.168.5.198 7001 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.5.160 7001 { weight 2 HTTP_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.5.162 7001 { weight 2 HTTP_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } connect_timeout 3 retry 3 delay_before_retry 3 } } }</code></pre> <p>node2配置文件参考:</p> <pre><code class="language-java">! Configuration File for keepalived global_defs { #notification_email { # acassen@firewall.loc # failover@firewall.loc # sysadmin@firewall.loc #} # notification_email_from Alexandre.Cassen@firewall.loc #smtp_server 192.168.200.1 # smtp_connect_timeout 30 router_id node2 #vrrp_skip_check_adv_addr #vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } #检测nginx心跳脚本 vrrp_script chk_http_port { script &amp;quot;/risen/sh/check_nginx_pid.sh&amp;quot; #心跳执行的脚本,检测nginx是否启动 interval 2 #(检测脚本执行的间隔,单位是秒) weight 2 #权重 } vrrp_instance VI_1 { state BACKUP #指定keepalived的角色,MASTER为主,BACKUP为备 interface ens192 # 网卡名,用ifconfig查看你具体的网卡 virtual_router_id 66 # 虚拟路由编号,主从要一致 priority 99 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) authentication { auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信 auth_pass 2222 } track_script { chk_http_port #(调用检测脚本) } virtual_ipaddress { 192.168.5.198 # 定义虚拟ip(VIP),可多设,每行一个 } } virtual_server 192.168.5.198 7001 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.5.160 7001 { weight 2 HTTP_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.5.162 7001 { weight 2 HTTP_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } connect_timeout 3 retry 3 delay_before_retry 3 } } }</code></pre> <h4>7.检测脚本(NODE1和NODE2)</h4> <p>创建nginx检测心跳脚本:</p> <pre><code class="language-java">vim /risen/sh/check_nginx_pid.sh</code></pre> <p>编辑以下内容:</p> <pre><code class="language-java">#!/bin/bash #检测nginx是否启动了 A=`ps -C nginx --no-header |wc -l` if [ $A -eq 0 ];then #如果nginx没有启动就启动nginx /risen/soft/nginx/sbin/nginx #重启nginx if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then #nginx重启失败,则停掉keepalived服务,进行VIP转移 killall keepalived fi fi</code></pre> <p>脚本授权:</p> <pre><code class="language-java">chmod +x /risen/sh/check_nginx_pid.sh</code></pre> <p>说明:脚本必须通过授权,不然没权限执行,VIP(virtual_ipaddress:192.168.5.198),我们在生产环境是直接通过vip来访问服务。</p> <h4>8.安装nginx【NODE1和NODE2】(参考nginx安装手册)</h4> <p>两台nginx主备机各负载两个web后端节点,搭建负载均衡集群(具体参考负载均衡策略) 六、模拟故障场景 1.修改两个服务器默认访问的Nginx的html页面作为区别。 2.首先访问192.168.5.198,通过vip进行访问,页面显示192.168.5.170;说明当前是主服务器提供的服务。 这个时候192.168.5.160主服务器执行命令 /risen/soft/nginx/sbin/nginx -s stop <img src="http://60.191.64.5:16100/server/index.php?s=/api/attachment/visitFile/sign/67d7659d31185ed3bda8ba1ebd59352a" alt="" /> 再次访问vip(192.168.5.198)发现这个时候页面显示的还是:192.168.5.160,这是脚本里面当检测到nginx停止,会自动重启nginx,只有当nginx重启失败,则停掉keepalived服务,进行VIP转移。 现在直接将192.168.5.160服务器关闭或者停掉keepalived服务,在此访问vip(192.168.5.198)现在发现页面显示192.168.5.162这个时候keepalived就自动故障转移了,一套企业级生产环境的高可用方案就搭建好了。</p>

页面列表

ITEM_HTML