一次MongoDB的Socket Exception

來源:互聯網
上載者:User

今天重新部署了一個項目,該項目啟動的時候會訪問MongoDB擷取一些資料,一個蠻簡單的項目,從前發布都沒問題,這次啟動的時候直接就是Socekt Exception:

nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: socket exception [SEND_ERROR] for x.x.x.x:xx; nested exception is com.mongodb.MongoException: socket exception [SEND_ERROR] for x.x.x.x:xx

第一反應是內網網路不太好,網路波動嘛,經查有的事兒。

解決辦法:多試幾次……

很明顯,這個辦法沒解決問題(這要是解決了就不會在這兒寫這個了)。同時ping mong執行個體所在的主機,0.3ms之內就返回了,也沒有丟包。

然後去mongo那邊看了看,也沒啥問題,啟動並執行很正常,log裡也沒什麼錯誤。 而且Mongo這邊配置的最大串連數是2W,這串連現在才用了不到9000啊。

這事情就比較奇怪了,以前從來沒遇到,既然是Socekt Exception只能繼續忘網路方向想了。

首先查看一下tcp串連中各個狀態的串連數:

admin@linux:~> netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'TIME_WAIT 3615CLOSE_WAIT 130FIN_WAIT1 11FIN_WAIT2 69ESTABLISHED 1983SYN_RECV 7CLOSING 23LAST_ACK 39LISTEN 30

這個命令呢,我也是搜來的,上面顯示的是一台服務運行正常的機器上面的結果,而出問題那台呢,ESTABLISHED有6000多,這明顯不科學呀,就業務層面來看,它的壓力應該更小點才對。

這得看一下這多出來的串連是和哪台機器建立的,繼續:

netstat -an |grep ESTA |awk '{print$5 "\n"}' |awk 'BEGIN {FS=":"} {COUNT[$1]++}END{for(a in COUNT) print a, COUNT[a]}' |sort -k 2 -nr

列印出來所有和該機器建立串連的IP以及串連數,一看果不其然是跟mongo所在的機器建立的串連超多,佔到了ESTABLISHED串連的絕大部分。

這得看一下是哪個進程出的問題,繼續:

netstat -anp |grep ESTA |awk '{print$7 }' |awk ' {COUNT[$1]++}END{for(a in COUNT) print a, COUNT[a]}' |sort -k 2 -nr

這樣看一下到底哪些進程佔用的ESTABLISHED串連多,拿到進程號之後,很容易找到對應的服務,結果呢另外一個服務佔用了很多ESTABLISHED串連。

netstat -anp | grep {pid}| grep ESTA |awk '{print$5 "\n"}' |awk 'BEGIN {FS=":"} {COUNT[$1]++}END{for(a in COUNT) print a, COUNT[a] }'

跟據pid反過來可以查看此進程和哪些機器建立了串連,以及建立了多少串連。

這個服務居然佔用了5000個mongo串連,太誇張了。。大概就是它把串連占完了,這就是罪魁禍首了。

等等,我們的mongo不是最大有2w個串連嗎。就算這個出奇的佔了這麼多也不至於讓別的起不來呀。先把5000這個錯誤修正讓服務跑起來再說,檢查了一下,這是配置上的問題,connections-per-host這個參數配置成了500,改成一個合理的值比如100,所有都恢複正常了,原先的服務也能起來了。

接下來分析兩個問題: connections-per-host這個參數是什麼意思 mongo的最大串連數怎麼沒生效

先說第二個,這個比較簡單。

主要原因在於,即使mongo的配置裡面最大串連數是2w,系統裡面每個進程的最大開啟檔案數(open files)只有65535,所以mongo的最大串連數其實也只有65535。串連數有問題的那個服務佔掉了5000個,剩下的被其他服務佔用了,所以重新部署的那個服務無法再獲得新的串連了。

這個地方唯一比較讓人鬱悶的是mongo這邊log裡也沒報錯……

再說第一個問題。官方API中對這個參數的解釋是這樣的:The maximum number of connections allowed per host for this Mongo instance.。允許每個host對這個Mongo執行個體建立的最大串連數。 根據使用的情況,個人反倒覺得解釋為允許每個process對這個Mongo執行個體建立的最大串連數更合適一些。如果是允許每個機器建立的最大串連數,那麼同一台機器上不管部署多少個服務串連到這個Mongo上面,這個機器和Mongo之間的最大串連數都應該是設定的這個值,可實際情況並不是這樣。

另外,也沒發現Mongo串連池有回收的機制,依據個人使用經驗,串連數目基本上只增不減(即使在不需要這麼串連的時候),最多增至設定的connections-per-host。

上面這些分析是個人的一個見解,可能不準確,歡迎指正。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.