日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SOFAMosn 无损重启/升级

發(fā)布時(shí)間:2025/3/18 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SOFAMosn 无损重启/升级 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

說明,本文檔基于 SOFAMosn 0.4.0 版本編寫

前言

SOFAMosn 是一款采用 GoLang 開發(fā)的 Service Mesh 數(shù)據(jù)平面代理,由螞蟻金服系統(tǒng)部網(wǎng)絡(luò)團(tuán)隊(duì)、螞蟻金服中間件團(tuán)隊(duì)、UC 大文娛團(tuán)隊(duì)共同開發(fā),功能和定位類似 Envoy,旨在提供分布式,模塊化,可觀察,智能化的代理能力;她通過模塊化,分層解耦的設(shè)計(jì),提供了可編程,事件機(jī)制,擴(kuò)展性,高吞吐量的能力。

——摘自《 SOFAMosn 的誕生和特性》

概述

總體上看,連接遷移的流程如下圖:

  • MOSN 通過 forkexec 生成 New MOSN
  • MOSN 通過 domain socket 把 TCP fd 和請(qǐng)求數(shù)據(jù)發(fā)送給 New MOSN
  • New MOSN 轉(zhuǎn)發(fā)請(qǐng)求到后端(PUB2)
  • 后端 回復(fù)響應(yīng)到 New MOSN
  • New MOSN 通過 MOSN 傳遞來的 TCP fd,回復(fù)響應(yīng)到 client

此后:

  • mosn 退出 readloop,不再接受該 TCP 連接上的數(shù)據(jù)
  • New mosn 開始 readloop,接受該 TCP 連接上的數(shù)據(jù)

——摘自《SOFAMosn Introduction》

具體實(shí)現(xiàn)

觸發(fā)

在 MOSN 啟動(dòng)的時(shí)候,會(huì)加載包

github.com/alipay/sofa-mosn/pkg/server

在這個(gè)包加載的時(shí)候,該里面的 serverkeeper.go 這個(gè)文件中的 init() 函數(shù)被執(zhí)行。這個(gè)函數(shù)會(huì)起一個(gè)協(xié)程在捕獲 HUP 信號(hào)。

當(dāng) Mosn 接收到來自系統(tǒng)的 HUP 信號(hào)時(shí),MOSN 首先會(huì)調(diào)用 stopStoppable 函數(shù)先讓 Admin Server 中的所有 Listener 都關(guān)閉 。然后調(diào)用 reconfigure 函數(shù)來進(jìn)行配置重新加載。

遷移過程

舊進(jìn)程的退出

觸發(fā)了 reconfigure 函數(shù)后,首先 MOSN 會(huì)設(shè)置兩個(gè)環(huán)境變量

_MOSN_GRACEFUL_RESTART=true _MOSN_INHERITFD_FD=<number>
  • _MOSN_GRACEFUL_RESTART 對(duì)應(yīng)的包 github.com/alipay/sofa-mosn/pkg/types 中的 GracefulRestart 常量,用于告訴新啟動(dòng)的 MOSN(下簡(jiǎn)稱 New MOSN) 這個(gè)是一個(gè)優(yōu)雅重啟。
  • _MOSN_INHERITFD_FD 對(duì)應(yīng)包 github.com/alipay/sofa-mosn/pkg/types 中的 InheritFd 常量,里面存儲(chǔ)的是 ListenerFD 的數(shù)量(ListenerFD 就是每個(gè) Listener 調(diào)用 listen() 返回的 fd)。
  • 準(zhǔn)備好環(huán)境變量后,就調(diào)用 syscall 包的 ForkExec 按照當(dāng)前 MOSN 的啟動(dòng)參數(shù)進(jìn)行啟動(dòng),并將環(huán)境變量和標(biāo)準(zhǔn)輸入輸出錯(cuò)誤和 ListenerFD 都和 New MOSN 共享。然后,MOSN 會(huì)等 3 秒,讓 New MOSN 啟動(dòng)起來。認(rèn)為 New MOSN 啟動(dòng)完成后,它就會(huì)調(diào)用 StopAccept() 讓所有的 Listener 停止 Accept 新的請(qǐng)求(已經(jīng) Accept 的請(qǐng)求不會(huì)結(jié)束,socket 的監(jiān)聽也不會(huì)斷),然后調(diào)用 WaitConnectionsDone 函數(shù)根據(jù) GracefulTimeout(默認(rèn)是 30秒) 設(shè)置的優(yōu)雅重啟的超時(shí)時(shí)間讓所有的連接都完畢。接著 MOSN 就進(jìn)行 Metrics 的遷移,完成后就會(huì)退出進(jìn)程。

    在 WaitConnectionsDone 中,MOSN 設(shè)置了一個(gè)時(shí)間長(zhǎng)度為 2 個(gè) GracefulTimeout + 10秒 的時(shí)間的定時(shí)器。然后首先會(huì) sleep 一個(gè) GracefulTimeout 的時(shí)間,等待所有的連接主動(dòng)關(guān)閉。然后關(guān)閉所有 server 中 connHandler 的 listeners 成員的 stopChan. 然后再 sleep 一個(gè) GracefulTimeout + 10秒的時(shí)間,等待所有連接的遷移。時(shí)間過了之后,函數(shù)就會(huì)返回。此后,上層會(huì)調(diào)用 TransferMetrics 進(jìn)行 Metrics 的調(diào)用 Exit 進(jìn)行進(jìn)程退出。

    新進(jìn)程的啟動(dòng)

    繼承 Listener 的獲取

    在 New MOSN 啟動(dòng)的過程中,首先會(huì)調(diào)用 getInheritListeners。這個(gè)函數(shù)會(huì)從讀取 Old MOSN 設(shè)置的環(huán)境變量 _MOSN_GRACEFUL_RESTART,如果為 true, 說明這是一個(gè)優(yōu)雅重啟,就會(huì)讀取環(huán)境變量 _MOSN_INHERITFD_FD。由于 Listener 是最先使用 fd 的,所以 fd 總是從3 開始,那么所有 Listener fd 就是: 3, 4, ... , 3 + _MOSN_INHERITFD_FD。然后利用這些 fd 將 Old MOSN 的 Listener 恢復(fù)出來。從而獲取到繼承過來的 Listener。獲取完之后,會(huì)對(duì)獲取的 Listener 和配置文件進(jìn)行比對(duì),判斷其合法性。如果不合法的,或者不能新的配置里面沒有以致繼承過來的 Listener 不需要復(fù)用,就會(huì)將其關(guān)閉。

    完成了所有的初始化之后,就會(huì)啟動(dòng)兩個(gè) Unix Sock 的Server, 分別用與進(jìn)行連接的遷移和 metrics 的遷移。用于連接遷移的 Unix Sock Server 會(huì)在 2 個(gè) GracefulTimeout + 10 秒后自動(dòng)關(guān)閉。

    遷移過程中,New MOSN 對(duì)每一個(gè) Unix Sock 請(qǐng)求都會(huì)分配一個(gè)協(xié)程去處理。

    連接的遷移

    當(dāng)一個(gè)請(qǐng)求進(jìn)來的時(shí)候,如果請(qǐng)求使用的協(xié)議不是 HTTP1 且不使用系統(tǒng)提供的事件循環(huán)的時(shí)候,MOSN 會(huì)啟動(dòng)自己的 ConnIo, 調(diào)用 startReadLoop 和 startWriteLoop 來開啟針對(duì)這個(gè)請(qǐng)求的的讀寫循環(huán)。

    讀寫數(shù)據(jù)遷移的協(xié)議

    在發(fā)送請(qǐng)求的過程中,首先會(huì)發(fā)送一個(gè)字節(jié)的數(shù)據(jù), 這個(gè)字節(jié)代表了傳輸?shù)氖亲x數(shù)據(jù)遷移還是寫數(shù)據(jù)遷移。0 代表是使用讀數(shù)據(jù)遷移協(xié)議。1 代表是使用寫數(shù)據(jù)協(xié)議。如果是 0, 還會(huì)將該連接的 fd 以 out-of-band 的方式也發(fā)送出去。

    讀數(shù)據(jù)遷移協(xié)議

    首先是頭部分:包括 8 個(gè)字節(jié),前 4 個(gè)字節(jié)是 data 部分的長(zhǎng)度,后 4 個(gè)字節(jié)是 TLS 部分的長(zhǎng)度。body 部分:接下來 data length 個(gè)字節(jié)存儲(chǔ)的是 readBuffer 數(shù)據(jù)。最后 TLS length 個(gè)字節(jié)存儲(chǔ)的是 TLS 的數(shù)據(jù)。

    寫數(shù)據(jù)遷移協(xié)議

    頭部分也是 8 個(gè)字節(jié), 前 4 個(gè)字節(jié)存儲(chǔ)了 data 部分長(zhǎng)度,后 4 個(gè)字節(jié)存儲(chǔ)的是 connection ID。body 部分:接下來的 data length 自己存儲(chǔ)的是 writeBuffer 數(shù)據(jù)。

    讀數(shù)據(jù)的遷移

    Old MOSN 發(fā)送

    在 startReadLoop 中,MOSN 會(huì)捕獲之前提到的 stopChan 被關(guān)閉的事件。捕獲到這個(gè)事件之后,MOSN 會(huì)讓這個(gè)鏈接等待一個(gè)隨機(jī)的時(shí)間,然后開啟連接遷移的過程。

    首先 MOSN 會(huì)往連接中的 transferChan 發(fā)一個(gè) transferNotify(值為1) 消息,告訴這個(gè)連接對(duì)應(yīng)的寫循環(huán):要開始遷移連接了。然后調(diào)用 transferRead 開始遷移讀連接,并返回一個(gè)connection ID,最后將這個(gè) ID 再次發(fā)送給 transferChan。

    在函數(shù) transferRead 中:

  • 和 New MOSN 先前提到的負(fù)責(zé)連接遷移的 transferServer 建立 unix socket 連接。
  • 獲取該連接對(duì)應(yīng)的 fd
  • 調(diào)用 transferSendType 將傳輸數(shù)據(jù)使用的協(xié)議類型(讀數(shù)據(jù)遷移協(xié)議還是寫數(shù)據(jù)遷移協(xié)議)和連接的 fd 發(fā)送給 New MOSN。
  • 調(diào)用 transferReadSendData 將 header 部分和 body 部分傳輸給 New MOSN。如果 TLS 握手還沒結(jié)束,則 TLS length 為 0。
  • 接收 New MOSN 處理完這些數(shù)據(jù)之后返回的 connection ID, 并返回
  • New MOSN 的接收

    當(dāng) New MOSN 接受到來自 Old MOSN 的數(shù)據(jù)時(shí):

  • New MOSN 會(huì)調(diào)用 transferRecvType, 首先接受協(xié)議的類型(一個(gè)字節(jié)), 如果是讀數(shù)據(jù)遷移的協(xié)議,還會(huì)去接受 oob(out-of-band)中的 fd,并利用個(gè)這個(gè) fd 重建出一個(gè)連接,恢復(fù)監(jiān)聽。
  • 調(diào)用 transferReadRecvData 獲得本次請(qǐng)求中的 data 部分和 tls 部分的數(shù)據(jù)。
  • 調(diào)用 transferNewConn, 首先根據(jù)重建出的連接,找到 NewMOSN 中對(duì)應(yīng)的 Listener。如果這是一個(gè) TLS 連接,還會(huì)利用 Old MOSN 傳過來的 TLS 信息將連接重建成一個(gè) TLS 連接。
  • 然后該 Listener 從觸發(fā) Listener 的 OnAccept 事件開始,處理這個(gè)連接的請(qǐng)求。當(dāng) MOSN 用于封裝連接的 connection 結(jié)構(gòu)體建立完畢后,就標(biāo)志著這個(gè)連接遷移完成,并將這個(gè) connection 結(jié)構(gòu)體存儲(chǔ)在一個(gè)叫 transferMap 的數(shù)據(jù)結(jié)構(gòu)中。
  • 利用重建的 connection 的 id 生成一個(gè)本次遷移連接的 ID,回傳給 Old MOSN。
  • 寫數(shù)據(jù)的遷移

    Old MOSN 的發(fā)送

    當(dāng)寫循環(huán)收到讀循環(huán)從 transferChan 發(fā)過來的 transferNotify 消息時(shí),會(huì)再讀一次 transferChan, 獲取到這一次連接傳輸?shù)?ID,如果 ID 合法,則會(huì)開始監(jiān)聽兩個(gè) channel:

  • internalStopChan: 從這個(gè) channel 收到信號(hào)(這個(gè) channel 被 close 了),認(rèn)為這寫數(shù)據(jù)遷移完成了,會(huì)直接退出。
  • writeBufferChan: 這個(gè) channel 傳送過來的是需要寫的數(shù)據(jù),也就是需要傳送的數(shù)據(jù)。收到后就會(huì)調(diào)用 transferWrite 開始遷移。當(dāng) writeLoop 要結(jié)束的時(shí)候,會(huì) close 掉 internalStopChan 和 writeBufferChan。觸發(fā)條件1。
  • 在 transferWrite 中:

  • 和 New MOSN 先前提到的負(fù)責(zé)連接遷移的 transferServer 建立 unix socket 連接。
  • 調(diào)用 transferSendType 將傳輸數(shù)據(jù)使用的協(xié)議類型(讀數(shù)據(jù)遷移協(xié)議還是寫數(shù)據(jù)遷移協(xié)議,此處是寫數(shù)據(jù)遷移協(xié)議)
  • 調(diào)用 tranferWriteSendData 將 writeBuffer 里面的內(nèi)容連同從 New MOSN 返回的連接傳輸 ID 一起發(fā)送給 New MOSN
  • New MOSN 的接收

    當(dāng) New MOSN 接受到來自 Old MOSN 的數(shù)據(jù)時(shí):

  • New MOSN 會(huì)調(diào)用 transferRecvType, 接受協(xié)議的類型(一個(gè)字節(jié)),判斷是寫數(shù)據(jù)遷移協(xié)議,進(jìn)入接受寫數(shù)據(jù)遷移的數(shù)據(jù)流程。
  • 從 unix sock 中讀出要寫的 buffer, 和連接傳輸?shù)?ID
  • 根據(jù) ID 從 transferMap 中 取出對(duì)應(yīng)的 connection 結(jié)構(gòu)體。并讓將傳輸過來的數(shù)據(jù)扔到 connection 結(jié)構(gòu)體中的 writeBufferChan 中,進(jìn)入新的 writeLoop。
  • 至此,連接遷移的過成就完成了。

    Metrics 的遷移

    Old MOSN 退出前的最后一件事,就是把 Metrics 數(shù)據(jù)托付給 New MOSN。

    協(xié)議

    Metrics 的傳輸協(xié)議很簡(jiǎn)單,包括兩部分 header 和 body

  • Header 長(zhǎng)度為 4 個(gè)字節(jié) 存放的是 body length
  • Body 的長(zhǎng)度為 body length 個(gè)字節(jié)。存放著要傳輸?shù)臄?shù)據(jù),即 Metrics 數(shù)據(jù)。
  • Old MOSN 的發(fā)送
  • 首先他會(huì)調(diào) makesTransferData, 將所有的 Metrics 數(shù)據(jù)都統(tǒng)一收集起來。
  • 和 New MOSN 先前提到的負(fù)責(zé) Metrics 遷移的 transferServer 建立 unix socket 連接。
  • 先后把 header 和 body 發(fā)送給 New MOSN
  • 如果設(shè)置了等待 New MOSN 的響應(yīng),會(huì)在一個(gè)超市時(shí)間內(nèi)等待 New MOSN 1 個(gè)字節(jié)的返回。
  • New MOSN 的接收

    當(dāng) New MOSN 接受到來自 Old MOSN 的數(shù)據(jù)時(shí),會(huì)調(diào) serveConn 函數(shù)去處理每一個(gè)遷移請(qǐng)求:

  • 讀取數(shù)據(jù)中的協(xié)議頭,并根據(jù)協(xié)議頭讀取出報(bào)文體。
  • 將報(bào)文體的數(shù)據(jù)恢復(fù)成成 go-metrics 的數(shù)據(jù),供 New MOSN 使用
  • 至此,所有關(guān)于平滑重啟的操作就完成了。

    原文地址:https://blog.coordinate35.cn/...

    總結(jié)

    以上是生活随笔為你收集整理的SOFAMosn 无损重启/升级的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。