調用別人提供的服務的時候沒有設置超時程序被卡住了怎麼辦?,如何模擬超時的情況?

我們有個定時任務會每天去請求一下別人提供的webservice來拿到今天簽署的合同的數據,某天早上巡檢服務器的時候,發現定時任務沒有執行,通過dump線程的狀態,發現執行這個定時任務的線程被阻塞住了

阻塞的原因是讀操作的超時時間沒有設置,默認值是-1 導致了客戶端一直等待,然後程序一直阻塞

解決的方法也很簡單,參照jdk的文檔我們可以在啓動參數上加上超時的相關的屬性

-Dsun.net.client.defaultConnectTimeout=10000
-Dsun.net.client.defaultReadTimeout=10000 

但是這裏又會遇到一個問題:怎樣確定這些參數生效了,也就是說怎樣模擬服務器端超時的情況,畢竟服務器端不會每次都超時

針對這種情況,我們可以使用iptables來丟棄掉服務器端的相關端口返回的SYN包或者數據包,來模擬連接超時和讀數據超時的情況

我們以百度爲例,模擬weget訪問百度的時候的超時情況

用到的兩個wget的參數:

-T 設置以秒爲單位的超時時間
-t 則是設置重試的次數

DROP掉百度返回的連接的建立連接的握手數據包:

iptables -A INPUT -p tcp -m tcp -s baidu.com --tcp-flags SYN SYN --sport 80 -j DROP

清除掉上一個規則,DROP掉百度返回的傳輸數據的數據包:

因爲iptables的INPUT鏈裏裏只設置了這一條規則,所以直接根據行號爲1來DROP即可

iptables -D INPUT 1

iptables -A INPUT -p tcp -m tcp -s baidu.com --tcp-flags PSH PSH --sport 80 -j DROP

通過這種方式,將我們的定時任務的程序請求的webservice的服務器返回的數據包也做這樣的處理,這樣就可以測試超時之後的情況了

模擬連接超時之後程序的報錯信息:

讀超時:

程序記錄超時之後拋出的異常再做相應的處理即可(比如將這次失敗的定時任務寫入數據庫,下次再繼續嘗試等)不會再阻塞線程影響其他任務的執行了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章