Http 爬蟲 socketRead0

1、昨天線上出了個問題:我們線上的一個爬蟲任務(wù)一直沒有執(zhí)行完畢,導(dǎo)致后面其他的任務(wù)跑的數(shù)據(jù)出錯。發(fā)現(xiàn)問題之后,立刻找運維幫忙dump線上機器的日志來看:

我們可以看到線程的狀態(tài)還是runnable,然后看下線程的是阻塞在了socketRead0,因為之前有遇到過類似的問題就是MySQL的查詢語句,從線程池中拿連接的時候沒有校驗連接的有效性導(dǎo)致拿不到連接,然MySQL的連接超時時間是默認的8小時。導(dǎo)致任務(wù)一個無效的線程,拿阻塞了8個小時才斷開連接,問題當(dāng)然是毀滅性的了。當(dāng)然缺少有效性的校驗和超時時間的設(shè)置是必要的,但是任務(wù)的監(jiān)控添加也是有必要的。這個后面在說。

今天發(fā)生的這個問題是由于DefaultHttpClient這個不推薦使用的客戶端引起的,具體我們項目中的代碼是這樣使用的:


問題就出在這句上面:get.setConfig(RequestConfig.custom().setConnectTimeout(Constant.TIMEOUT)

? ? ? ? ? ? ? ? .setSocketTimeout(Constant.TIMEOUT).build());//10秒鐘超時時間

這個超時時間的設(shè)置是不對的。我們跟著源碼進去,我這里貼出非重要的路徑:


當(dāng)我們跟著源碼到DefaultRequestDirector的exectue的方法的時候就差不多要切入正題了。下面咱們具體看看一個特別重要的方法tryConnect,他里面給我們會設(shè)置連接的超時時間等信息。

tryConnect是一個內(nèi)部方法,先檢查是否當(dāng)前連接是否是開啟的,沒有就會開啟,進入到這個open方法中。


可以看到連接是有的上一個方法返回的open屬性的值是false。那么就去開啟這個連接。結(jié)合上一步我們可以知道這個方法是需要設(shè)置超時時間等信息的。同事我們也可以看到poolEntry連接池中的信息,創(chuàng)建時間就是我Test啟動的時間,超時時間是個特別大的值。

開啟的時候最終會走到PlainSocketFactory:


你會發(fā)現(xiàn)他是從HttpParams params里面取值的。而不是我們代碼中設(shè)置的樣子。

到此問題找到了,具體的解決辦法有沒有呢,當(dāng)然有啊,而且還不只一個:

解決辦法:

1.用下面的這種方式設(shè)置參數(shù)就是OK的啦。因為她就是按照下面的方式取值的么。

2.第二種不用這個廢棄的方式了。這種方式呢大家猜也難能猜到了,她設(shè)置值的時候是直接加載的config,就是咱們構(gòu)造的這個socketConfig啦。大家有興趣就跟進源碼中去看看了。

第二章fa

debug源碼真的很爽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,667評論 1 32
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時,會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,980評論 0 9
  • feisky云計算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 4,355評論 0 5
  • 最近被藍瘦香菇圍堵了,周圍的人都在藍瘦香菇,自己也有點中了魔咒。也許,誰的生活不是一地雞毛呢,難過的時候就沉浸在自...
    QuellaJ閱讀 946評論 10 14
  • 我來自一個,S爸爸,D媽媽,S妹妹,I弟弟的家庭 所以,看來這個家庭很缺C,但是很歡樂 遇到事情就是,大家一起笑一...
    可小姐的繽紛世界閱讀 568評論 0 4

友情鏈接更多精彩內(nèi)容