健康监测是负载均衡不可缺少的一个重要环节,所有负载均衡流量分配的不同方式实现都是基于稳定可靠的健康监测基础之上的;针对一个无法提供应用的端口,负载均衡设备应该较快发现并将其从可用应用端口中剔除,在该端口恢复后再重新加入。
A10网络的AX系列产品,本身已经提供了丰富的健康检测方式,如下图,包含了多个不同协议,甚至可以使用多个不同健康监测的联动(例如或,与的关系)。基本上可以满足绝大多数应用的健康监测需求。
但是有一次在银行客户碰到有些特殊的健康监测需求,总结如下:
客户是在Linux上基于java自行开发的应用,该应用根据用户请求数目增加会建立新进程,由于开发需求,该程序需要进行复杂的数据调用和处理,导致可以正常工作的并发进程数目有限。在该应用并发进程达到一定数值时,即使Linux服务器本身CPU, 内存正常,也无法再继续对外提供服务。
客户要求: 能根据每台服务器上具体的应用进程数设定端口可用状态; 最好可以提前预警通知,可以通知超过警戒线,以及回复后告知。
解决思路
1)在客户端Linux服务器中,解决进程统计的问题,并增加定制化SNMP功能
2)A10负载均衡功设备负责通过SNMP获取该进程统计数,判定端口可用性;同时负责发送预警,告警和恢复邮件通知(告警功能其实服务器上可以做,但是由于负载均衡是决定该端口是否可用的最终决策者,交给负载均衡处理最合理。)
具体配置
在Linux服务器上
1)新增脚本,统计进程并发并发数,例如命名为HttpdThreadCheck的脚本
- #!/bin/sh
- #例如监测进程名称为b的所有统计
- conn=`ps -aef | grep -i b |wc -l`
- #warn, down, send分别代表告警状态,端口状态,以及通知状态
- #告警,预警,恢复的邮件通知均只发送一次,避免批量持续发送
- warn=0
- down=0
- send=0
- if [ $conn -gt 55 ]; then
- warn=1
- down=1
- if [ ! -f /tmp/a10down ]; then
- echo >/tmp/a10down
- send=1
- fi
- if [ ! -f /tmp/a10warn ]; then
- echo >/tmp/a10warn
- fi
- elif [ $conn -gt 49 ]; then
- warn=1
- down=0
- if [ -f /tmp/a10down ]; then
- send=1
- rm -rf /tmp/a10down
- fi
- if [ ! -f /tmp/a10warn ]; then
- send=1
- echo >/tmp/a10warn
- fi
- echo >/tmp/a10warn
- else
- warn=0
- down=0
- if [ -f /tmp/a10down ]; then
- send=1
- rm -rf /tmp/a10down
- fi
- if [ -f /tmp/a10warn ]; then
- send=1
- rm -rf /tmp/a10warn
- fi
- fi
- echo "$down:$warn:$conn:$send"
2)修改SNMP参数,新增自定义OID
通常位于/etc/snmp/snmp.conf
A: 修改SNMP community “public”的属性
注销缺省配置
- com2sec notConfigUser default public
B: 增加public属性并配置SNMP返回参数以及脚本位置
- rocommunity public
- exec .1.3.6.1.4.1.2021.18 HttpdThreadCheck /etc/httpthreadcheck.sh
其中 .1.3.6.1.4.1.2021.18为SNMP对应OID值,HttpdThreadCheck为名称(可使用任何有效名);/etc/httpthreadcheck.sh为执行脚本; 该配置的优势在于,只有在外部查询该OID时,才会执行触发对应的脚本并返回结果
C:重启SNMP服务, 例如 service snmpd restart
D:如果必要,需要取消selinux功能
通常在/etc/selinux/config文件中,使用 SELINUX=disabled
如果马上有效,执行命令 setenforce 0
E: 此时可以通过远程设备执行snmpwalk获取相关信息
- [root@CentOS ~]# snmpwalk -c public -v 2c 192.168.159.129 .1.3.6.1.4.1.2021.18
- UCD-SNMP-MIB::ucdavis.18.1.1 = INTEGER: 1
- UCD-SNMP-MIB::ucdavis.18.2.1 = STRING: "tcpCurrEstab"
- UCD-SNMP-MIB::ucdavis.18.3.1 = STRING: "/etc/httpthreadcheck.sh"
- UCD-SNMP-MIB::ucdavis.18.100.1 = INTEGER: 0
- UCD-SNMP-MIB::ucdavis.18.101.1 = STRING: "0:0:60:0"
- [root@CentOS ~]#
如果只关心相关结果特定返回值,可以使用snmpgetnext命令;例如
在A10负载均衡上; 创建新的外部程序,例如命名为httpcheck, 将如下脚本贴入
- [root@CentOS ~]# snmpgetnext -c public -v 1 192.168.159.129 .1.3.6.1.4.1.2021.18.100.1
- UCD-SNMP-MIB::ucdavis.18.101.1 = STRING: "0:0:60:0"
- A10健康检测脚本
- #!/bin/sh
- function send_mail()
- {
- # $1 subject; $2 msg $3 send mail or not
- smtp="10.1.1.219"
- to="[email protected]"
- from="[email protected]"
- port=25
- if [ $3 -gt 0 ]; then
- mailsend -smtp $smtp -p $port -t $to -f $to -sub "\"$1\"" -d ax +c +b -M "\"$2\"" -u $to -w test
- fi
- }
- numb=`snmpgetnext -c public $HM_SRV_IPADDR -v1 .1.3.6.1.4.1.2021.18.100.1 | cut -d \" -f2`
- down=`echo $numb | cut -d : -f1`
- warn=`echo $numb | cut -d : -f2`
- number=`echo $numb | cut -d : -f3`
- sendmail=`echo $numb | cut -d : -f4`
- if [ $number -gt 25 ]; then
- send_mail "$HM_SRV_IPADDR down: from A10 con is $number " "Server is marked down" $sendmail
- echo "Mark it down"
- exit 1
- elif [ $number -gt 22 ]; then
- send_mail "$HM_SRV_IPADDR warning: from A10 con is $number " "Sever warning" $sendmail
- echo "problem. Need watch"
- exit 0
- else
- echo "up"
- send_mail "$HM_SRV_IPADDR back to normal: from A10 con is $number " "Server recovered and marked up" $sendmail
- exit 0
- fi
- exit 0
然后再配置服务器端口的对应健康监测即可
- health monitor httpthreadcheck
- method external program httpcheck
- !
- slb server 10.7.32.199 10.7.32.199
- port 8080 tcp
- health-check httpthreadcheck
健康监测脚本也是一个可以根据需求灵活定义的开放工具,这里只是一个示例供参考。另外健康监测的脚本请勿与A10的aFleX功能(基于七层的流量分发等)混淆。
(J.L.)