Socket連接超時(轉)


Socket.connect連接超時有二種情況:

1.由於網絡的問題,TCP/IP三次握手時間>timeout的設置時間。這在國外訪問weibo時,並且網絡環境極差的情況下有可能發生。
解決的辦法:調大socket.connect方法中的timeout參數值,比如50s,linux默認最高是70s,如果超過70s沒有意義,linux會采用70s.
但是當調大之后,發現不到10s就報timeout exception。
通過國外的機器ping api.weibo.com發現unreachable。
說明客戶端在傳輸層之下的網絡層就發現連個Syn的報文都發不出去,更不用說三次握手了,客戶端直接失敗並拋timeout exception。

經驗:在connection timeout診斷的第一步應該是ping一下確認網絡層沒有問題。
注:客戶端設置了timeout,但並不會等到超時才返回異常。客戶端只要第一時間發現連接失敗,就會拋timeout exception。


2.如果timeout設置的時間足夠,但是由於服務器端的處理能力較差,比如緩沖連接隊列較小,而應用層的處理能力沒有連接緩沖快,導致緩沖連接占滿,而拒絕新的連接。
在服務端因為連接隊列占滿而拒絕服務的期間,客戶端的通過TCP協議重試三次。每次的時間翻倍。
如果三次時間的累加<timeout參數值且能連接上,屬於正常情況,表示隊列騰出空位放當前連接。
如果三次時間的累加<timeout參數值且未能連接上,則客戶端會立刻拋出timeout exception,而不等timeout到期才拋。

 

附:讀寫超時

1.讀寫超時

read超時設置有意義,在服務器處理能力差,但最終會響應的情況下,可以將客戶端的等待響應時間設長一些。如果太長的話,由於客戶端使用的是BIO的方式,線程會一直阻塞在IO而導致掛起。當客戶端的處理能力明顯快於服務端,這樣掛起的線程會很多。

不管客戶端還是服務器端,當有很多線程阻塞時,對機器的性能都會影響。我在weibo的論壇上看到有人在read timed out后,將soTimeout的時間設為100s。這是很危險的,新浪的服務器一旦崩潰,自己的服務器也會由於大量線程積壓崩潰。

因為線程在掛起之后,它掌握的資源並不會釋放,比如內存,直到阻塞完成。同時大量線程的掛起就意味着系統要做大量上下文的恢復並調度執行。

解決辦法:

如果客戶端使用NIO的方式,如果服務端的響應能標出客戶端的請求,則線程在客戶端請求之后,完全可以把請求放入一個BlockQueue,然后利用Future或Wait/Notify等機制在帶着請求標志的響應返回的時候,喚想隊列中的請求接着處理,從而實現異步處理,可以用少量線程服務大量請求。

同樣,如果服務器端可以使用NIO做到請求每線程處理,而不是連接每線程,可以大大減少線程掛起導致資源的浪費,NIO適用於連接很多,請求很少的場合。另外,Commet又稱為服務器推技術,它的主要特點是長連接。避免客戶端低效的請求輪詢。主要用於聊天室,WEIBO,因為連接多,請求不一定多,同樣也適合在服務器端使用NIO

注:read timeout異常時,並不需要ping遠程機器,因為它是輔助定位connection timeout,如果ping不通,肯定是conneciton timeout而不會到read timeout。read timeout exception不會導致連接中斷。為重試提供了機會。

 

2.write超時一般不象connection timeout和read timeout可以在客戶端顯示調值,TCP有寫重傳的概念,一般8m內會重試,否則,直接斷開連接。

http://www.cnblogs.com/highriver/archive/2012/01/16/2324035.html
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM