和朋友一起搞定了这个应用~ 以前是用shell写的,方法比较二,而且性能不好,因为公司有更好的解决方案,所以这个方法也就可以分享出来了>
一个用python来监控 lvs的调度情况,根据后端服务器负载的情况,来实现lvs权衡负载
因为每个人的环境不一样,最好是看下代码,多方面测试再用~
这个程序需设置一个阈值,在lvs端运行server.py 在realserver运行client.py 。
后端的服务器会把当前的负载情况,利用socket的方式发送给 LVS端, 随之LVS端会检查 ipvsadm -L -n 的情况。
如果检查达到警告阈值,会相应的平衡,如果不是,什么都没发生。当负载回到正常,权重设置回到原来的值。
我会在三更半夜的时候,把代码讲解注释的~
通信用xmlrpc,不适合大型的应用,对付这个简单报告的话,还是可以的。
给个小例子大家可以看看~
xml rpc是使用http协议做为传输协议的rpc机制,使用xml文本的方式传输命令和数据。一个rpc系统,必然包括2个部分:1.rpc client,用来向rpc server调用方法,并接收方法的返回数据;2.rpc server,用于响应rpc client的请求,执行方法,并回送方法执行结果。
rpcserver
import SimpleXMLRPCServer class HelloWorld: def say(self): return "hello, world!" obj = HelloWorld() server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 80)) server.register_instance(obj) print "Listening on port 80..." server.serve_forever()
rpcclient
import xmlrpclib server = xmlrpclib.ServerProxy("http://localhost:80") print "result: " + server.say()
server.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # 绑定自己的ip 和 一个可用的端口 serverIP = '172.17.0.100' serverPort = 12219 # 设置服务器的负载阀值 LoadAvg_crit_threshold = '1.00' LoadAvg_warn_threshold = '0.60' # 什么时候,会设置权衡 比如设置5的话 就是20% changeWeightWarn = 4 # 100%/4 = -25% of original changeWeightCrit = 2 # 100%/2 = -50% of original from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler import string,socket # convert hex2dec def hex2dec(s): return int(s, 16) # simple routine to read from a file, line by line def readLines(filename): f = open(filename, "r") lines = f.readlines() return lines # 或者 realserver ip 在 /proc/net/ip_vs 的连接情况 # This ACL should be built with the following format: # { RIP = [VIP, WEIGHT, WEIGHTCURRENT, VPORT, RPORT] } print "Building ACL from LVS table ..." accessList={} for line in readLines('/proc/net/ip_vs'): if line.split()[0] == 'TCP' or line.split()[0] == 'UDP': vIP = line.split()[1].split(':')[0] vIPvIPfst = vIP[0:2] vIPvIPscd = vIP[2:4] vIPvIPtrd = vIP[4:6] vIPvIPfth = vIP[6:8] vIPport = hex2dec(line.split()[1].split(':')[1]) virtualIP = str(hex2dec(vIPfst)) + "." + str(hex2dec(vIPscd)) + "." + str(hex2dec(vIPtrd)) + "." + str(hex2dec(vIPfth)) if line.split()[0] == '->': if len(str(line.split()[1])) == 13: rsIP = line.split()[1].split(':')[0] rsIPrsIPfst = rsIP[0:2] # first octet rsIPrsIPscd = rsIP[2:4] # second octet rsIPrsIPtrd = rsIP[4:6] # third octet rsIPrsIPfth = rsIP[6:8] # fourth octet rsIPport = hex2dec(line.split()[1].split(':')[1]) # get routing type (nat/direct/tun) rsRouteType = line.split()[2] if rsRouteType == "Route": rsRoute = "g" elif rsRouteType == "Masq": rsRoute = "m" elif rsRouteType == "Tunnel": rsRoute = "i" # compile RIP realserverIP = str(hex2dec(rsIPfst)) + "." + str(hex2dec(rsIPscd)) + "." + str(hex2dec(rsIPtrd)) + "." + str(hex2dec(rsIPfth)) # build realserver list realserverList = [virtualIP] # add original weight to list realserverList.append(line.split()[3]) # add current weight to list (same as original weight) realserverList.append(line.split()[3]) # add virtual port to list realserverList.append(vIPport) # add real port to list realserverList.append(rsIPport) # add routing type to list realserverList.append(rsRoute) # add keypair (ip:weight) to ACL accessList[realserverIP] = realserverList print "Adding %s:%s:%s:%s:%s:%s to ACL as RIP:VIP:weightOrig:weightCurrent:vPort:rPort:rType" % (str(realserverIP),str(virtualIP),str(accessList[realserverIP][1]),str(vIPport),str(rsIPport),str(rsRouteType)) # 或者负载情况 并且 pushLoad def pushLoad_function(LoadAvg, clientIP): import os LoadAvgLoadAvg1 = LoadAvg.split()[0] #print "DEBUG: Client reports IP: %s " % clientIP # Determine original weight rsWeightOriginal = accessList[clientIP][1] #print "DEBUG: Original weight of rs: %s " % rsWeightOriginal # Determine changed weight rsWeightCurrent = accessList[clientIP][2] #print "DEBUG: Current weight of rs: %s " % rsWeightCurrent # Determine if CRITICAL threshold is reached if float(LoadAvg1) >= float(LoadAvg_crit_threshold): print "CRITICAL: Load Average (1min) threshold (%s) reached: %s" % (str(LoadAvg_crit_threshold),LoadAvg1) rsWeightHalf = int(rsWeightOriginal) - int(rsWeightOriginal)/2 # Only change weight if not already changed if not int(rsWeightCurrent) == int(rsWeightHalf): print "Changing realserver's weight to 50% of original" print "Running /sbin/ipvsadm -e -t " + str(accessList[clientIP][0]) + ":" + str(accessList[clientIP][3]) + " -r " + str(clientIP) + ":" + str(accessList[clientIP][4]) + " -w " + str(rsWeightHalf) + " -" + str(accessList[clientIP][5]) cmd = "/sbin/ipvsadm -e -t " + str(accessList[clientIP][0]) + ":" + str(accessList[clientIP][3]) + " -r " + str(clientIP) + ":" + str(accessList[clientIP][4]) + " -w " + str(rsWeightHalf) + " -" + str(accessList[clientIP][5]) os.system(cmd) # Setting new weight in list accessList[clientIP][2] = rsWeightHalf else: print "Weight already changed. Doing nothing." # Determine if WARNING threshold is reached elif float(LoadAvg1) >= float(LoadAvg_warn_threshold): print "WARNING: Load Average (1min) threshold (%s) reached: %s" % (str(LoadAvg_warn_threshold),LoadAvg1) rsWeightQuart = int(rsWeightOriginal) - int(rsWeightOriginal)/4 # Only change weight if not already changed if not int(rsWeightCurrent) == int(rsWeightQuart): print "Changing realserver's weight to 75% of original" print "Running /sbin/ipvsadm -e -t " + str(accessList[clientIP][0]) + ":" + str(accessList[clientIP][3]) + " -r " + str(clientIP) + ":" + str(accessList[clientIP][4]) + " -w " + str(rsWeightQuart) + " -" + str(accessList[clientIP][5]) cmd = "/sbin/ipvsadm -e -t " + str(accessList[clientIP][0]) + ":" + str(accessList[clientIP][3]) + " -r " + str(clientIP) + ":" + str(accessList[clientIP][4]) + " -w " + str(rsWeightQuart) + " -" + str(accessList[clientIP][5]) os.system(cmd) # Setting new weight in list accessList[clientIP][2] = rsWeightQuart else: print "Weight already changed. Doing nothing." else: print "OK: Load Average (1min) threshold normal: %s" % LoadAvg1 # Setting weight back to original value if not already set if not int(rsWeightCurrent) == int(rsWeightOriginal): print "Setting weight back to original value of %s" % str(rsWeightOriginal) print "Running /sbin/ipvsadm -e -t " + str(accessList[clientIP][0]) + ":" + str(accessList[clientIP][3]) + " -r " + str(clientIP) + ":" + str(accessList[clientIP][4]) + " -w " + str(rsWeightOriginal) cmd = "/sbin/ipvsadm -e -t " + str(accessList[clientIP][0]) + ":" + str(accessList[clientIP][3]) + " -r " + str(clientIP) + ":" + str(accessList[clientIP][4]) + " -w " + str(rsWeightOriginal) os.system(cmd) accessList[clientIP][2] = rsWeightOriginal return LoadAvg1 # subclass SimpleXMLRPCServer to grab client_address class Server(SimpleXMLRPCServer): def __init__(self,*args): SimpleXMLRPCServer.__init__(self,(args[0],args[1])) def server_bind(self): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) SimpleXMLRPCServer.server_bind(self) def verify_request(self,request, client_address): print "\n" clientIP = client_address[0] if accessList.has_key(clientIP): print "Client (%s) in LVS table." % clientIP return 1 else: print "Client (%s) NOT in LVS table." % clientIP return 0 if __name__ == "__main__": print "Starting up ..." server = Server(serverIP,serverPort) server.register_function(pushLoad_function, 'pushLoad') server.logRequests = 0 server.serve_forever()
client.py
#!/usr/bin/env python import xmlrpclib import socket # IP:port settings of director directorIP = '172.17.0.100' directorPort = '12219' # Connect to server s = xmlrpclib.ServerProxy("http://" + directorIP + ":" + directorPort) # FIXME: Implement timeout (else RPC request will hang indefinately) #socket.setdefaulttimeout(60) def readLine(filename): f = open(filename, "r") lines = f.readline() return lines LoadAvg = readLine('/proc/loadavg') # Fugly way to grab our ip. A better way would be to take our initial # connect and get it from there. I don't know how (yet). from socket import socket, SOCK_DGRAM, AF_INET ugly = socket(AF_INET, SOCK_DGRAM) ugly.connect((directorIP, int(directorPort))) myIP = ugly.getsockname()[0] myLoad = s.pushLoad(LoadAvg,myIP) print "DEBUG: pushed current 1m load avg of " + str(myLoad)
本文出自 “峰云,就她了。” 博客,请务必保留此出处http://rfyiamcool.blog.51cto.com/1030776/1141785
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索server
, split
, str
, print
, weight
floating ip
lvs socket 负载均衡、lvs socket、lvs socket配置、lvs websocket、java socket lvs,以便于您获取更多的相关知识。