第一次用TCL,也是第一次测试A10的LB设备。
根据公司原来架构要求,改写了原来的images LB系统的url hash,提高了容错能力。
主要构想是要实现url hash的一致性,连续性的负载均衡要求;
算法很简单,url md5 hash后根据nodes数量为取模值然后转到后端的node id;
如果该后端出现故障,将nodes数量减去当前的故障设备,重新取模后转到后端。
A10脚本不是完整的TCL语法,除了增加了自己的设备command外也相应了删减了很多TCL的command。
比如proc就不能用了,导致我的语法显的啰嗦了。
设备上的脚本为AfleX,转帖如下:
#后端设备列表 when RULE_INIT { set ::ips [list "xx.xx.xx.1" "xx.xx.xx.2" "xx.xx.xx.3" "xx.xx.xx.4" "xx.xx.xx.5" ] } when HTTP_REQUEST { #取url做md5并转成整数型 set url_hash [HTTP::host][HTTP::uri] set md5_hash [md5 $url_hash] set int_md5 [scan $md5_hash %c] set nodes [llength $::ips] #debug 信息排错用 log local0.NOTICE "Each variable:All node: $nodes; URI hash: $int_md5" #在循环判断service-groups和nood状态并指向后端 while 1 { if { [LB::status pool imgcache_pool] == "down" } { break log local0.ERR "Imgcache group is down or disables." } #取模 set hashs [expr $int_md5 % $nodes] #模数指向后端 switch $hashs { 0 { set IP [lindex $::ips 0] if { [LB::status node $IP port 80 tcp] == "up" } { node $IP 80 break } else { set nodes [expr $nodes - 1 ] log local0.ERR "IP addr:$IP is down. no hash its service." } } 1 { set IP [lindex $::ips 1] if { [LB::status node $IP port 80 tcp] == "up" } { node $IP 80 break } else { set nodes [expr $nodes - 1 ] log local0.ERR "IP addr:$IP is down. no hash its service." } } 2 { set IP [lindex $::ips 2] if { [LB::status node $IP port 80 tcp] == "up" } { node $IP 80 break } else { set nodes [expr $nodes - 1 ] log local0.ERR "IP addr:$IP is down. no hash its service." } } 3 { set IP [lindex $::ips 3] if { [LB::status node $IP port 80 tcp] == "up" } { node $IP 80 break } else { set nodes [expr $nodes - 1 ] log local0.ERR "IP addr:$IP is down. no hash its service." } } 4 { set IP [lindex $::ips 4] if { [LB::status node $IP port 80 tcp] == "up" } { node $IP 80 break } else { set nodes [expr $nodes - 1 ] log local0.ERR "IP addr:$IP is down. no hash its service." } } } } #http_header中插入真实client ip if { not [HTTP::header exists "CLIENT_IP"] } { HTTP::header "CLIENT_IP" [IP::client_addr] } }