shell解决DNS负载均衡RS的健康检测

DNS负载均衡,是最早的实现负载均衡技术的。在DNS的配置文件中为多个地址配置同一个名字,即配置多条指向不同ip的A记录,而客户端在查询这条A记录的时候将随机获得其中一个地址。通过以上描述不难发现,DNS负载均衡有着配置简单,性能优异,没有修改架构的开销等特点。因此,经常被用在内网。

说了优点,也要说说缺点。DNS负载均衡采用的是简单的轮循负载算法,不能分辨服务器的差异,不能根据后端服务器的运行状态进行动态调整,即健康检查。由于实现算法的随机性,不能为性能较好的服务器更多的分配请求,经常会出现将请求集中在某一台服务器上的现象。

如果你负载均衡的要求很高,不如使用其他负载均衡技术来的容易,比如LVS,Nginx或者HAproxy。修改算法,不仅要看明白洋洋散散几万行源码,还要将自己的代码完美融合进去,这个成本因人而异,但肯定不是一朝一夕之功。但如果只是后端服务器的健康检测问题,使用shell脚本就可以办到。

思路:DNS服务器通过某种机制对后端RS主机的运行状态进行判断,如果后端主机出现故障,那么DNS所要做的是修改配置文件,将问题主机从配置文件中提出并重启服务。更进一步,当RS主机恢复时,DNS主机还要将其恢复到配置文件中。

首先是健康检测机制。如果RS主机是web服务,那么可选的至少有三个,icmp,telnet,curl分别工作在第三层,第四层,和第七层。我们在这里使用icmp。修改配置文件,可以通过将提前准备好的配置文件覆盖原文件做到,当然还有sed -i,我们在这里使用sed -i。最后使用while及if elif将这些元素合理的嵌套。

web1 192.168.1.1     web2  192.168.1.2
DNS配置文件:

www IN A 192.168.1.1
www IN A 192.168.1.2

#! /bin/bash
while true;do #定义无限循环,让脚本不间断工作。
ping -c1 192.168.1.1 &> /dev/null #由于linux下的ping命令会无限进行下去,
所以我们要使用-c参数指定数据包个数,并将标准错误和标准输出全部重定向到/dev/null这个脏目录中。
if ! [ $? -eq 0 ];then #如果$?的返回值不为零,即ping不通。
     sed -i '/192.168.1.1/s/^/;/' dns #修改配置文件,将包含192.168.1.1的行开头替换成;号。
(dns配置文件的注释是;号)
     /etc/init.d/bind restart
else
     sed -i '/192.168.1.1/s/;//' dns #如果可以ping通,那么去掉;
     /etc/init.d/bind restart
fi
ping -c1 192.168.1.2 &> /dev/null 
if ! [ $? -eq 0 ];then 
     sed -i '/192.168.1.2/s/^/;/' dns 
     /etc/init.d/bind restart
else
     sed -i '/192.168.1.2/s/;//' dns 
     /etc/init.d/bind restart
fi
     sleep 5 #休息5秒,继续工作。
done

如果使用以上的shell脚本,确实可以完成RS主机的高可用,但我们也会发现,如果后端主机出了问题,配置文件会在问题主机ip所在行前不断的增加;号的同时,不断的重启dns服务。这是我们不能允许的,修改后的脚本如下:

#! /bin/bash
caipan1=0 
caipan2=0 #定义两个裁判变量记录状态
while true;do 
ping -c1 192.168.1.1 &> /dev/null
state=$? 
if ! [ state -eq 0 ] && [ $caipan1 -eq 0 ];then 
     sed -i '/192.168.1.1/s/^/;/' dns 
     /etc/init.d/bind restart
     caipan1=1
elif [ state -eq 0 ] && [ $caipan1 -eq 1 ];then
     sed -i '/192.168.1.1/s/;//' dns 
     /etc/init.d/bind restart
     caipan1=0
fi
ping -c1 192.168.1.2 &> /dev/null 
state=$?
if ! [ state -eq 0 ] && [ $caipan2 -eq 0 ];then 
     sed -i '/192.168.1.2/s/^/;/' dns 
     /etc/init.d/bind restart
     caipan2=1
elif [ state -eq 0 ] && [ $caipan2 -eq 1 ];then
     sed -i '/192.168.1.2/s/;//' dns 
     /etc/init.d/bind restart
     caipan2=0
fi
     sleep 5 #休息5秒,继续工作。
done

caipan变量的目的只有一个,就是增加判断条件,修改配置及重启服务必须要满足双重条件才能进行,通过重置变量让条件不再满足。当然,解决办法还有很多。篇幅所限,在这里我们只给出了变量的办法,希望大家能提出更好的建议,发动集体智慧,开拓思路,写出更好脚本。

文章来自:http://president.blog.51cto.com/4990508/859637

 

 

 

Comment

  • Trackback are closed
  • Comments (1)
  1. 感觉这个做法不是特别好,意义不大。

    bind应该有类似的健康检查的插件机制。通过健康检查定义每一个IP的权值,并动态刷新,确保DNS不中断。

Comment are closed.