Docker Swarm - Overlay 網(wǎng)絡(luò)長連接問題

問題描述

如圖所示,在 Swarm 集群中部署了 ServiceAServiceB 這兩個(gè)服務(wù)礼华,服務(wù)間通過 grpc 建立長連接實(shí)現(xiàn)服務(wù)間調(diào)用。然而 ServiceA 在調(diào)用 ServiceB 時(shí)拗秘,偶爾會(huì)出現(xiàn)如下錯(cuò)誤:

java.io.IOException: Connection reset by peer
    at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
    at sun.nio.ch.IOUtil.read(IOUtil.java:192)
    at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
    at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1100)
    at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:367)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:118)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    at java.lang.Thread.run(Thread.java:745)

在我們查看容器日志時(shí)圣絮,這個(gè)錯(cuò)誤出現(xiàn)次數(shù)不是很頻繁,但是一定會(huì)出現(xiàn)雕旨,由于這個(gè)錯(cuò)誤會(huì)導(dǎo)致業(yè)務(wù)系統(tǒng)異常扮匠,所以我們花了點(diǎn)時(shí)間去處理它。

問題排查

1凡涩、 grpc 中間件的問題棒搜?
并發(fā)測試:50 個(gè)線程,10萬次請求活箕,重復(fù)了 3 次力麸,均能正常響應(yīng)。因此,排除這種可能性克蚂。

2闺鲸、測試環(huán)境網(wǎng)絡(luò)波動(dòng)導(dǎo)致的?
持續(xù)請求測試:多線程持續(xù)請求 4 小時(shí)埃叭,均能正常響應(yīng)摸恍。然而另外一套測試環(huán)境,測試妹子人工測試的時(shí)候還是出現(xiàn)這個(gè)問題赤屋。因此立镶,排除這種可能性。

3益缎、搜索 Connection reset by peer 相關(guān)信息
網(wǎng)上很多文章都說明了這個(gè)異趁栈牛可能出現(xiàn)的原因,經(jīng)過各種 DEBUG莺奔,發(fā)現(xiàn)這個(gè)異常發(fā)生時(shí)欣范,ServiceA 沒有將數(shù)據(jù)發(fā)送到 ServiceB。結(jié)合上述 1 和 2 兩步的測試令哟,長連接一直維持時(shí)無異常恼琼;人工測試時(shí),中途會(huì)停止請求屏富,時(shí)間過長晴竞,長連接會(huì)斷開,ServiceA 無法將數(shù)據(jù)發(fā)送給 ServiceB狠半,就能解釋通了噩死。

4、分析 Docker Swarm 中的網(wǎng)絡(luò)模型

Docker Swarm 中使用 IPVS 將 ServiceA 的請求路由到 ServiceB 的一個(gè)實(shí)例神年,ServiceAServiceB 長連接的建立會(huì)經(jīng)過 IPVS已维。此處 IPVS 的規(guī)則是:當(dāng) TCP 會(huì)話空閑超過15分鐘(900秒)時(shí),IPVS 連接超時(shí)并從連接表中清除已日,即圖中 IPVS 與 ServiceB 之間的連接垛耳。

下面是兩種不同的 timeout ,一種是 IPVS 的飘千,另一種是 TCP 的:

默認(rèn) IPVS timeout 值:

  • ipvsadm -l --timeout
  • Timeout (tcp tcpfin udp): **900** 120 300

默認(rèn) TCP timeout 值:

  • tcp_keepalive_time = **7200** (秒堂鲜,連接時(shí)長)
  • tcp_keepalive_intvl = 75 (秒,探測時(shí)間間隔)
  • tcp_keepalive_probes = 9 (次护奈,探測頻率)

當(dāng) IPVS 超時(shí), 它將從連接表中清除缔莲。而 IPVS 超時(shí)后,時(shí)間在 7200s 之內(nèi)霉旗,ServiceA 還是會(huì)認(rèn)為長連接處于連接狀態(tài)痴奏,實(shí)則不然磺箕,繼續(xù)調(diào)用 ServiceB 則會(huì)出現(xiàn)問題。

5抛虫、精準(zhǔn)復(fù)現(xiàn)問題
ServiceA 調(diào)用 ServiceB松靡,正常響應(yīng),等待 15 分鐘以上建椰,ServiceA 繼續(xù)調(diào)用 ServiceB雕欺,一定出現(xiàn) Connection reset by peer 的異常。

問題解決

方式一:ServiceA 在代碼層面實(shí)現(xiàn)連接重試邏輯

方式二:系統(tǒng)層面設(shè)置 TCP 的 timeout

設(shè)置 tcp_keepalive_time 小于 900s 棉姐,建議 600 ~ 800

sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=10

或者編輯文件 /etc/sysctl.conf屠列,添加如下內(nèi)容:

net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 10

為了使配置生效,必須重啟 Swarm 中的服務(wù)伞矩。建議同時(shí)應(yīng)用上述的兩種方法笛洛。

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市乃坤,隨后出現(xiàn)的幾起案子苛让,更是在濱河造成了極大的恐慌,老刑警劉巖湿诊,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狱杰,死亡現(xiàn)場離奇詭異,居然都是意外死亡厅须,警方通過查閱死者的電腦和手機(jī)仿畸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朗和,“玉大人错沽,你說我怎么就攤上這事】衾” “怎么了千埃?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長镀层。 經(jīng)常有香客問我镰禾,道長皿曲,這世上最難降的妖魔是什么唱逢? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮屋休,結(jié)果婚禮上坞古,老公的妹妹穿的比我還像新娘。我一直安慰自己劫樟,他們只是感情好痪枫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布织堂。 她就那樣靜靜地躺著,像睡著了一般奶陈。 火紅的嫁衣襯著肌膚如雪易阳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天吃粒,我揣著相機(jī)與錄音潦俺,去河邊找鬼。 笑死徐勃,一個(gè)胖子當(dāng)著我的面吹牛事示,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播僻肖,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肖爵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了臀脏?” 一聲冷哼從身側(cè)響起劝堪,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揉稚,沒想到半個(gè)月后幅聘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窃植,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年帝蒿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巷怜。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葛超,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出延塑,到底是詐尸還是另有隱情绣张,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布关带,位于F島的核電站侥涵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宋雏。R本人自食惡果不足惜芜飘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磨总。 院中可真熱鬧嗦明,春花似錦、人聲如沸蚪燕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诗良,卻和暖如春汹桦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鉴裹。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工营勤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人壹罚。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓葛作,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猖凛。 傳聞我的和親對象是個(gè)殘疾皇子赂蠢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容