author: "trainyao"
date: 2019-11-24
title: mosn 的 reconfig 機制
linktitle: mosn 的 reconfig 機制
本文記錄了對 mosn 的源碼研究破停,研究 mosn 是如何做到平滑重啟的逆日。
本文的內(nèi)容基于 mosn v0.8.1蒲凶。
我們先將被重啟的 mosn 進程稱為 舊 mosn
卿操,將重啟并接管流量的進程成為 新 mosn
。
1. 機制
mosn 沒有使用重新讀取 config 文件的方法來實現(xiàn) reconfig痒钝,而是通過 unix socket
作為進程間通信急波,并將舊進程的監(jiān)聽 fd 通過 socket 傳過去昧辽,新 mosn 接管 fd 并且重新讀取 config,舊 mosn 進行 gracefully shutdown嫉你,以達到 reconfig 和平滑重啟的功能月帝。
2. 舊mosn
我們先從一個啟動著的 mosn 進程看起,看看它是如何被重啟的幽污。
mosn 的 reconfig 邏輯在 server
包的 reconfigure.go
內(nèi)嚷辅。
mosn 進程啟動后,會創(chuàng)建一個叫 reconfig.sock
的 unix socket距误,創(chuàng)建一個協(xié)程簸搞,開始監(jiān)聽并往里面寫入一個字節(jié)的內(nèi)容扁位,這時會出現(xiàn)寫阻塞。一旦有另一個進程從 reconfig.sock 讀取到這一個字節(jié)趁俊,舊 mosn 便開始 reconfig 邏輯
域仇。
reconfig 邏輯:
當(dāng)寫阻塞結(jié)束,協(xié)程會嘗試鏈接另一個 unix socket :
listen.sock
-
一旦鏈接上则酝,負(fù)責(zé) reconfig 的協(xié)程會將已經(jīng)存在的 fd 從
listen.sock
發(fā)送殉簸,發(fā)送是通過out-of-band
數(shù)據(jù)進行的。 很顯然沽讹,這個listen.sock
是新的 mosn 進程創(chuàng)建的般卑,用來接收正在服務(wù)的 fd,接管并用以繼續(xù)服務(wù)爽雄。這里的
已經(jīng)存在的 fd
包括兩種:-
server listener fd
蝠检, 負(fù)責(zé)監(jiān)聽業(yè)務(wù)的 tcp 連接,對應(yīng)config.json
里的servers
數(shù)組里的listeners
數(shù)組里的 ip +端口 -
service listener fd
挚瘟,控制相關(guān)的端口叹谁,比如 pprof、prometheus metrics export乘盖、admin 端口
-
發(fā)送完 fd 之后焰檩,舊 mosn 會接收 listen.sock 的數(shù)據(jù)(由新 mosn 寫入的數(shù)據(jù),代表 fd 已接管完畢)订框,并進入 gracefully shutdown 狀態(tài)析苫,不再接收新的鏈接,等已有請求處理完再關(guān)閉
舊 mosn 有30秒時間處理完現(xiàn)存請求
30秒后穿扳,舊 mosn 關(guān)閉衩侥,鏈接由新 mosn 接管
3. 新mosn
接下來是新 mosn 的啟動。有兩個問題:
-
新 mosn 是如何將舊mosn的fd據(jù)為己有矛物,并且接受數(shù)據(jù)的呢茫死?
- 新 mosn 通過
net.FileListener
方法對接受到的 fd 進行處理,該函數(shù)會返回 fd 的一個 network listener 副本履羞,改副本可以用來接收數(shù)據(jù)峦萎,新 mosn 就是通過這個操作來從舊 mosn 做 fd 的接管 - 新 mosn 會重新解析一遍 config.json 進行解析,而在上一部處理過的 network listener 副本也能查找到對應(yīng)的地址和端口吧雹。通過比對兩者相同之處骨杂,就能在創(chuàng)建新的 server listener 和 service listener 時,接管舊 mosn 的 fd雄卷,用來初始化新的 listener搓蚪。
- 新 mosn 通過
-
新 mosn接收到 fd 信息后,會做些什么呢丁鹉?
- 接管 server listener fd
- 接管 service listener fd
- 給 listen.sock 發(fā)送一個字節(jié)數(shù)據(jù)妒潭,通知舊 mosn:可以關(guān)閉了
- 至此悴能,mosn reconfig 結(jié)束
5. 后續(xù)疑問
- 新 mosn 通過
net.FileListener
方法處理完 fd 并初始化了 listener,由于處理后的 fd 是一個副本雳灾,如果這個時候來了一個連接漠酿,那這個連接是會被舊 mosn 處理到,還是新 mosn谎亩,還是兩者都會通知到呢? 關(guān)于這方面炒嘲,可以做一個實驗驗證一下。
參考資料: