天天看點

機器當機引發的複制集心跳異常問題

primary

secondary

hidden

node1:port1

node2:port2

node3:port3

node3重新加入後,服務正常,但複制集内部的通信卻還有問題。

從node3的 rs.status()看整個複制集,一切正常,說明 node3到 node1、node2發送心跳請求都正常(每個節點周期性向其他節點發送心跳,通過心跳應答來更新其他節點的狀态資訊)。

當從 node1、node2的 rs.status()看,node3卻處于當機狀态,錯誤如下

也就是說 node1向 node3發送心跳資訊是一直失敗的,失敗的原因是couldn't get a connection within the time limit

node1上執行 netstat,發現 node1已經建立了到 node3的連接配接 (注意這條連接配接 tcp keepalive timer 是關閉的)

然而從 node3上執行 netstat,這個連接配接并不存在

也就是說,這個連接配接是 node3當機之前建立的連接配接,因為 tcp keepalive 沒有打開,加上 node3異常退出,是以這條連接配接隻是一邊斷開了,node1一端還一直保留着這條連接配接。

此時隻要 node1往 node3通過這個連接配接發送心跳資料,就會發現對端已經關閉,但實際上沒有發送任何資料,在從連接配接池擷取連接配接的時候就已經出錯了(couldn't get a connection within the time limit

解決這個問題,最直接的方法就是把 node1、node2的 mongod 程序重新開機,一切就會恢複正常,但作為雲服務應該盡量避免這麼做,以減少對使用者的影響。猜測隻要上述連接配接隻要能在 node1上關閉,node1重建立立連接配接就能恢複正常,于是嘗試來幹掉這條 tcp連接配接。

利用這個小工具,向上述連接配接随便發送了一些資料,連接配接立即被關閉了,node1向 node3建立立了一條連接配接來發送心跳,一切恢複正常。

機器當機引發的複制集心跳異常問題

繼續閱讀