2012-11-08 78 views
3

我目前使用這個LIB進行壓力測試,我已經建立了一個卡夫卡服務器:https://github.com/dsully/pykafka如何強制用python打開的套接字關閉?

import kafka 
import time 

def test_kafka_server(n=1): 
    for i in range(0,n): 
     producer = kafka.producer.Producer('test',host='10.137.8.192') 
     message = kafka.message.Message(str(time.time())) 
     producer.send(message) 
     producer.disconnect() 

def main(): 
    test_kafka_server(100000) 

if __name__ == '__main__': 
    main() 

什麼只是最終發生的是,我最終超載我自己的本地機器。

我得到錯誤10055,根據谷歌意味着「Windows已經用盡了TCP/IP套接字緩衝區,因爲太多的連接一次打開。」根據netstat,producer.disconnect()沒有關閉套接字,而是將其置於TIME_WAIT狀態。

IPython的調試器指向該行:

C:\Python27\lib\socket.pyc in meth(name, self, *args) 
    222  proto = property(lambda self: self._sock.proto, doc="the socket protocol") 
    223 
--> 224 def meth(name,self,*args): 
    225  return getattr(self._sock,name)(*args) 
    226 

的罪魁禍首,但這似乎然後進入比我舒適與更低層級的事情搞亂。

我已經搜查,發現了這個Python socket doesn't close connection properly其中建議這樣做:

setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

所以,我重建了pykafka LIB使用該選項在io.py文件:

def connect(self): 
    """ Connect to the Kafka server. """ 
    global socket 
    self.socket = socket.socket() 
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    self.socket.connect((self.host, self.port)) 

,我仍然得到同樣的錯誤。

我是不是把setsockopt線放在正確的位置?還有什麼我可以嘗試嗎?

+1

我沒有看到它的解決辦法:http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers html的 – Will

回答

5

您所描述的是套接字級別的正常TCP行爲。當用戶級程序關閉套接字時,內核不會立即釋放套接字。它進入TIME_WAIT狀態:

TIME-WAIT(無論是服務器或客戶端)表示等待足夠 時間通過,以確保遠程TCP接收的 其連接終止請求的確認。 [根據RFC 793,連接 可以停留在TIME-WAIT中最多四分鐘,稱爲MSL (最大段壽命)。

因此,套接字已關閉。 socket.SO_REUSEADDR用於偵聽器(服務器),不影響客戶端連接。那麼,綁定套接字時真的很習慣。