1

我有一個多線程的python程序,它會連續打開本地URL的連接(),我已經安裝了WAMP並具有sendMessages_mock.php文件在本地進行測試。有時,我得到「[Errno 10061]由於目標機器主動拒絕,所以無法連接」Python:無法建立連接,因爲目標機器主動拒絕它

每個線程都會調用此函數。每一秒鐘,就會有數百個線程調用這個函數。只爲少數線程調用獲取此異常。對此有何想法?

def sendMessage(body): 
    try: 
     request = Request(url="http://testing.com/sendMessages_mock.php", data=json.dumps(body)) 
     request.add_header('Authorization', 'key=' + CONST.API_KEY) 
     request.add_header('Content-Type', 'application/json') 
     response = urlopen(request) 
     responseData = response.read().decode('utf-8') 

    except Exception as exceptionErr: 
     print("Oops! " + str(traceback.format_exc())) 
+3

服務器端監聽連接,但「listen」調用有backlog - 最大數量的尚未被接受的傳入連接請求。當請求隊列太大時,服務器TCP堆棧可能會開始拒絕連接。這可能是你所看到的。您可能可以將服務器配置爲更大的待辦事項,但也可以考慮這是正常的背壓,可以讓您的客戶冷靜一點。 – tdelaney

回答

1

如果每秒太多調用導致WAMP拒絕請求的問題,你想解決這個Python的一面,你可以寫限制類,它會處理的sendMessage執行和調用的數量限制。

請注意,這是我第一次回答別人的問題,所以可能是絕對錯誤的。請有合理的懷疑態度。

#python 2.7 
import threading 

class Throttle(object): 
    def __init__(self, call_limit, interval): 
     self.call_limit = call_limit 
     self.interval = interval 
     self.cleaner = None 
     self.buffer = threading.Semaphore(call_limit) 
     self.calls_in_buffer = 0 

    def call(self, function, *args): 
     self.buffer.acquire() 

     self.calls_in_buffer += 1 
     try: 
      return function(*args) 
     except: 
      raise 
     finally: 
      if self.cleaner == None: 
       self._init_cleaner() 

    def _drain(self): 
     for i in range(self.call_limit): 
      self.calls_in_buffer -= 1 
      self.buffer.release() 
     self.cleaner = None 

    def _init_cleaner(self): 
     self.cleaner = threading.Timer(self.interval, self._drain) 
     self.cleaner.daemon = True 
     self.cleaner.start() 

通過這樣的類進行調用將有效地抑制請求,所以服務器將能夠處理它們。

+0

假設這可行,它可能會更好[裝飾](http://python-3-patterns-idioms-test.readthedocs.io/en/latest/PythonDecorators.html#function-decorators)。在這種情況下,它會接受包裝在其構造函數中的函數,並且'call'將被'__call__'替換。 – Tagc

相關問題