too many open files錯誤
雖然一直在Linux下開發服務,但是說實話,Linux的東西我基本不懂。這次這個問題的解決,讓我稍微知道一些東西了。
大家都知道,最近我模仿binux大嬸的pyspider
的害羞組在線上跑了一段時間了。後來加入了一些新的東西,比如代理池等。看瞅著代碼越來越靠譜了,結果突然有一天,發現抓取停止了,緊接著去看日誌:
2015/08/12 23:18:22 Post http://api.duoshuo.com/posts/import.json: dial tcp: lookup api.duoshuo.com: too many open files
作為一個菜鳥,我哪知道這是啥啊。後來用Google去搜,發現這是Linux套接字占滿了。在目錄/proc//fd/
ll | wc -l
查看當前進程的socket連接數。
這一看就是有東西申請了沒釋放,果斷重啟了服務好了。但是到底是哪裏沒釋放,我還是不得而知。只能是用Google繼續查,我懂得少,查了很多東西,把結論說一下。
在/proc/net/tcp
文件裏,保存的是當前計算機的TCP協議連接,我這邊服務器的結果如下:
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 276: BE848368:80E5 2F80CFB7:0050 08 00000000:000019E4 00:00000000 00000000 1000 0 3748204 1 ffff8800182c1c00 116 4 30 10 -1
然後就是換算IP,這裏面本地和遠程IP都是16進制的,並且是倒著排的,換算完的本地IP是104.131.132.190:32997(BE848368:80E5),遠程IP是183.207.128.47:80(2F80CFB7:0050),說明我的計算機連接這個IP沒有正常斷開。查了一下這個IP,他是我用的西祠代理裏面提供的一個,說明代理那部分新寫的代碼有問題。
後來又得知,用netstat
命令也成,而且比這個更牛逼。我一般還會用-p
參數,這個能看到連接相關的進程,別的參數我也不懂了,大家想知道就Google把。netstat -p | grep haixiuzu
這個就能看到我的害羞組程序的連接。當時顯示出的一個結果如下表。此外,還發現一次抓取結束後會有30個CLOSE_WAIT狀態的連接,其中118.144.80.201
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 1 0 104.131.132.190:60059 118.144.80.201:http CLOSE_WAIT 14397/haixiuzu
網上查了查,大神們都說如果Recv-Q
和Send-Q
有不為0的就說明不對,這是發送和接受隊列,說明一直在等待,一般需要兩個小時操作系統才會自動釋放這個資源,但是據我觀察,兩個小時也不會正常,要不也不會增加到1024個。
問題大體了定位好了,然後就是定位和修復。又去看了TCP連接的3次握手和斷開的4次握手,大概猜測是握手握了一半沒繼續握。又去看了看Golang的net/http
包,斷開連接就是resp.Body.Close()
,我沒寫這個,抱著試一試的態度改了一下,發現TCP連接恢復正常了。。。
我自己造的這個輪子還是可以的,讓我學到了TCP的一些皮毛,還是很有成就感的。
本文所涉及到的完整源碼請參考。
too many open files錯誤