2017-09-03 113 views
8

我需要建立一個UDP服務器,它可以處理〜10_000個請求/秒。從下面的代碼開始,測試一個java套接字是否可以處理這些數量的請求。java UDP套接字可以處理多少個請求?

我轟擊服務器在〜9000個請求一分鐘,

Total number of requests sent from the client : 596951 

和TCP轉儲我看到

90640 packets captured 
175182 packets received by filter 
84542 packets dropped by kernel 

UDP服務器代碼:

try (DatagramSocket socket = new DatagramSocket(port)) { 
      System.out.println("Udp Server started at port :" + port); 


      while (true) { 
       byte[] buffer = new byte[1024]; 
       DatagramPacket incomingDatagramPacket = new DatagramPacket(buffer, buffer.length); 
       try { 
        socket.receive(incomingDatagramPacket); 
        LinkedTransferQueue.add(incomingDatagramPacket); 
       } catch (IOException e) { 
        e.printStackTrace(); 
        continue; 

       } 


      } 

     } catch (SocketException e) { 
      e.printStackTrace(); 
     } 

內核在程序中丟棄數據包的可能原因是什麼? m 這個簡單嗎?

如何減少?任何其他實現?

從這個link,從評論閱讀,失去UDP協議到Java socket.recieve方法甚至網絡之間可以隨時發生的數據包。

注意:必須弄清楚捕獲到的tcpdump數據包中的異常情況,但丟棄的數據包數量相當多。

了tcpdump的異常是lack of buffer space,爲了知道數據包的數量收到,我現在用的是iptraf-ng這給每個端口:)

+4

可能的原因是套接字接收緩衝區填滿了,因爲沒有足夠快地讀取它。嘗試減少'println()'調用,例如每百個數據報一個。 – EJP

+0

@EJP我已經做到了,但仍然有丟包 –

+0

使用多線程來同時處理多個數據包。您也可以在您的以太網接口和交換機上相應的端口上激活流量控制(但丟失數據包是一種被告知擁塞的方式,因此激活流量控制可能會產生不良的副作用)。 –

回答

2

輯陣線程接收的數據包的數量

收到數據包後,您的代碼示例不執行任何操作。如果是這樣,多線程不能幫助你。但是,如果這僅僅用於測試,並且實際應用程序需要對接收到的數據包執行某些操作,則需要將數據包推送到另一個Thread(或其中的一個池),然後立即返回以偵聽下一個數據包。

基本上你需要最小化兩次調用socket.receive()之間的時間。

注意:這是而不是這種情況下唯一可用的多線程模型。

緩衝區大小

增加與socket.setReceiveBufferSize緩衝區大小將映射到SO_RCVBUF:

增加SO_RCVBUF可以允許網絡實現,以緩衝多個數據包時,包到達比正在接收更快使用receive(DatagramPacket)。

然而,這僅僅是一個暗示

的SO_RCVBUF選項用於通過網絡實現爲暗示尺寸底層網絡I/O緩衝區。

如果您的設置允許,也可以直接進入操作系統並更改緩衝區的大小。

無關

注:閱讀本只有當你不能確定包的大小小於1024個字節。

對於通用數據包,您的數據包緩衝區大小似乎很低,這可能會導致錯誤,因爲:如果數據包大於緩衝區,則不會有錯誤,它將忽略溢出字節。

編輯:

等多線程模型

注:這是一個想法,我不知道它的實際工作。

3個線程:

  • 線程A:在處理分組
  • 螺紋B1:接收分組
  • 螺紋B2:接收分組

初始化:

  • 原子計數器設置爲0
  • B1正在接收,B2正在等待。

雖然B1的環:

  • 而計數器> 0等待
  • 計數器+ = 1
  • 接收的分組
  • 計數器 - = 1
  • 醒B2
  • 將數據包推送到A隊列

相同的B2。

這線程圖(線在數據包已經收到):

B1 [--------|---] [--------|---] 
B2   [--------|---] [--------|---] 
+0

我已經更新了代碼,我已經按照註釋中的建議更改了os緩衝區大小,仍然有10%的數據包丟失:( –

+0

你有沒有嘗試其他機器?也有可能是網卡是瓶頸,你不能改善它... – MaanooAk

+0

如果你有興趣,我添加了其他多線程模型,它只是一個想法,我你絕望,你可以測試它...沒有承諾 – MaanooAk

0

而不是使用線程,您可以點擊這裏使用的API NIO2使用AsynchronousDatagramChannel的可能性。

幫助鏈接: https://www.ibm.com/developerworks/library/j-nio2-1/index.html

+1

AsynchronousDatagramChannel類已從java中刪除8 http://bugs.java.com/view_bug.do?bug_id=6993126 –

+0

@ forum.test17這是不正確的,這不是bug報告所說的。它在Java 7發佈之前已經從Java 7中撤銷了,現在它已經存在於Java 8中了。請參閱Javadoc。 – EJP

0

一個缺點是它不與TCP UDP協議的mcast_recv_buf_sizeucast_recv_buf_size提供了可靠的傳輸保證配置屬性用於指定接收緩衝區的數量。

它取決於您用來運行程序的操作系統。緩衝區大小不同的操作系統有:

<table sytle="width:100% border:1px solid black"> 
 
<tr> 
 
<th><b>Operating System</b></th> \t 
 
<th><b>Default Max UDP Buffer (in bytes)</b></th> 
 
</tr> 
 
<tr><td>Linux</td> \t      <td>131071</td></tr> 
 
<tr><td>Windows</td> \t   <td>No known limit</td></tr> 
 
<tr><td>Solaris</td> \t      <td>262144</td></tr> 
 
<tr><td>FreeBSD</td> \t    <td>262144</td></tr> 
 
<tr><td>AIX</td>      <td>1048576</td></tr> 
 
</table>

所以UDP負載處理以及取決於機器的操作系統配置。