簡體   English   中英

Java TCP / IP套接字性能問題

[英]Java TCP/IP Socket Performance Problem

我們的應用程序是通過Java中的TCP / IP套接字非常快速地讀取數據。 我們正在使用帶有非阻塞套接字和選擇器的NIO庫來指示讀取的准備情況。 平均而言,讀取和處理讀取數據的總處理時間是亞毫秒。 然而,我們經常看到10-20毫秒的尖峰。 (在Linux上運行)。

使用tcpdump,我們可以看到tcpdump讀取2條謹慎消息之間的時差,並將其與我們的應用程序時間進行比較。 我們看到tcpdump似乎沒有延遲,而應用程序可以顯示20毫秒。

我們非常確定這不是GC,因為GC日志幾乎沒有顯示Full GC,而且在JDK 6中(根據我的理解),默認GC是並行的,所以它不應該暫停應用程序線程(除非執行Full GC) 。

它看起來幾乎像Java的Selector.select(0)方法有一些延遲返回准備讀取,因為在TCP層,數據已經可以讀取(並且tcpdump正在讀取它)。

附加信息:在峰值負載時,我們每條消息處理大約6,000 x 150字節平均值,或每秒大約900 MB。

eden集合仍然會產生STW暫停,因此20ms可能完全正常,具體取決於實時集的分配行為和堆大小/大小。

您的Java代碼是在RTLinux下運行,還是其他一些具有硬實時調度功能的發行版? 如果沒有,處理時間內10-20毫秒的抖動似乎是完全合理的,並且是預期的。

我在我工作的java服務中遇到了同樣的問題。 當從客戶端重復發送相同的請求時,服務器將在流中的相同位置阻塞25-35ms。 在套接字中關閉Nagle的算法為我修復了這個問題。 這可以通過在Socket上調用setTcpNoDelay(true)來完成。 這可能導致網絡擁塞增加,因為ACK現在將作為單獨的數據包發送。 有關Nagle算法的更多信息,請參見http://en.wikipedia.org/wiki/Nagle%27s_algorithm

tcpdump faq

什么時候是一個時間戳? 時間准確度如何准確?

在大多數運行tcpdump和libpcap的操作系統中,數據包都帶有時間戳,作為網絡接口設備驅動程序或網絡堆棧處理過程的一部分。 這意味着數據包在到達網絡接口時沒有加蓋時間戳; 在數據包到達網絡接口之后,將會有一個延遲,直到中斷被傳遞或網絡接口被輪詢(即,網絡接口可能不立即中斷主機 - 如果網絡可以設置驅動程序輪詢接口流量很大,以減少中斷次數並在每次中斷時處理更多數據包),並且在中斷開始處理的時間點和生成時間戳之間會有進一步的延遲。

很可能,時間戳是在特權內核層中進行的,丟失的20ms是將上下文切換回用戶空間以及Java和JVM網絡選擇器邏輯。 如果不對整個系統進行更多分析,我認為不可能做出肯定的原因選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM