Python實現簡單的負載平衡
提到分發請求,相信大多數人首先會想到Nginx,Nginx作為一種多功能伺服器,不僅提供了反向 Proxy隱藏主機ip的能力,還擁有簡單的緩衝加速功能。當然Nginx最強大的功能還是分發請求,不僅提供了雜湊,一致性雜湊,負載平衡等多種請求分發模式,還保證了自己服務的輕量和穩定。一台Nginx伺服器常年工作在高並發請求的環境下,也極少宕機。
在Nginx負載平衡模式下,請求會發送到壓力最小的未宕機伺服器上。今天我們不考慮目標伺服器的壓力,用Python實現最簡單的負載平衡方法,即將請求發送到未宕機的伺服器上。
我們想調用module_b模組中的介面,module_b服務在10.10.10.115伺服器上的10081,10082,10083,10084這4個連接埠上。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import random
import os
import sys
import time
import ConnectionError
import Module_bException
module_b = "10.10.10.115:10081,10.10.10.115:10082,10.10.10.115:10083,10.10.10.115:10084"
class Module_b():
def __init__(self):
self.url_prefix = [val.strip() for val in module_b.split(',')]
def _request(self, short_uri, payload):
res = None
try_count = 1
url_prefixs = self.url_prefix[:]
url_prefixs.sort(key=lambda f: random.randint(0, 100))
for curr_url_prefix in url_prefixs:
url = os.path.join(curr_url_prefix, short_uri)
try:
res = requests.post(url, data=payload)
break
except ConnectionError as e:
try_count += 1
sys.stderr.write('can not connect to Module_b, retry ...\n')
time.sleep(1)
if try_count == len(url_prefixs):
raise e
if res.status_code != 200:
raise Module_bException('HTTP ERROR: %s' % res.text)
result = res.json()
if result['status'] != '0':
raise Module_bException(result['errstr'])
return result['result']
ConnecttionError和Module_bException為封裝好的報錯類無需在意。
整個負載平衡的實現也很簡單,傳入api和參數,然後從所有的module_b地址中隨機選出一個,拼接成完整的requests請求,如果無法訪問到module_b服務,那麼將換到另一個未訪問過的module_b服務地址,直到訪問過全部的module_b服務。