2010-03-26 54 views
1

我們正在面向使用IPC插座的高吞吐量事務處理系統中出現隨機尖峯。插座性能中的尖峯

下面是用於運行安裝程序:

  1. 客戶端打開和關閉對每一項交易新的連接,並有服務器和客戶端之間的交流4。
  2. 我們已經通過getsockopt設置套接口逗留(SO_LINGER)選項來禁用TIME_WAIT,因爲我們認爲尖峯是由於套接字等於TIME_WAIT而引起的。
  3. 沒有爲交易完成處理。只有消息被傳遞。
  4. OS中使用的Centos 5.4

平均往返時間是約3毫秒,但有時往返時間從100毫秒秒至幾秒鐘。用於執行測量和輸出

步驟

  1. 啓動服務器

    $蟒蛇sockServerLinger.py>的/ dev/null的&

  2. 啓動客戶端後1百萬筆交易到服務器。並在client.log文件中記錄事務的時間。

    $蟒sockClient.py百萬> client.log

  3. 一旦執行完成以下命令將顯示的執行時間比在格式<line_number>:<execution_time> 100毫秒以上。

    $ grep -n「0. [1-9]」client.log | less

以下是服務器和客戶端的示例代碼。

服務器

# File: sockServerLinger.py 
import socket, traceback,time 
import struct 
host = '' 
port = 9999 

l_onoff = 1 
l_linger = 0 
lingeropt = struct.pack('ii', l_onoff, l_linger) 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, lingeropt) 
s.bind((host, port)) 
s.listen(1) 

while 1: 
    try: 
     clientsock, clientaddr = s.accept() 
     print "Got connection from", clientsock.getpeername() 
     data = clientsock.recv(1024*1024*10) 
     #print "asdasd",data 
     numsent=clientsock.send(data) 
     data1 = clientsock.recv(1024*1024*10) 
     numsent=clientsock.send(data) 
     ret = 1 
     while(ret>0): 
      data1 = clientsock.recv(1024*1024*10) 
      ret = len(data) 
     clientsock.close() 
    except KeyboardInterrupt: 
     raise 
    except: 
     print traceback.print_exc() 
     continue 

客戶

# File: sockClient.py 

import socket, traceback,sys 
import time 
i = 0 
while 1: 
    try: 
     st = time.time() 
     s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
     while (s.connect_ex(('127.0.0.1',9999)) != 0): 
      continue 
     numsent=s.send("asd"*1000) 
     response = s.recv(6000) 
     numsent=s.send("asd"*1000) 
     response = s.recv(6000) 
     i+=1 
     if i == int(sys.argv[1]): 
      break 
    except KeyboardInterrupt: 
     raise 
    except: 
     print "in exec:::::::::::::",traceback.print_exc() 
     continue 
    print time.time() -st 

回答

1

這裏是想到一種可能性:由於您使用SOCK_STREAM

1),您使用的是TCP協議 2)作爲一個可靠的協議,TCP將重新發送pa已經超時的箱子,以確保一切最終到達。 3)TCP使用的動態超時值是根據當前往返時間(RTT)估計爲 計算得出的。4)當TCP連接首次啓動時,它不知道RTT是什麼,所以它使用非常大的初始超時值,有時大約爲秒。

所以...如果其中一個早期的TCP握手數據包被丟棄,您的套接字可能會在很長一段時間內等待,然後才決定數據包沒有到達並重新發送數據包。這種情況會隨機發生,相對較少,但在無數連接中肯定會發生多次。

嘗試使用socket.settimeout()的值較短,並在連接超時後立即重試。這樣你就可以假設初始RTT估計值較短。

+0

感謝您的可能性。嘗試將超時設置爲0.5秒的值,並且在引發異常時,操作(connect或send或recv)在while循環中重試。這也表現了相同的方式(5秒是最大時間)。我們注意到,如果通信延遲大約5秒鐘,那麼它會引發異常10次和第11次操作成功。 如果您有任何其他建議,請讓我知道。 – 2010-03-27 02:29:15