1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        ETCD Client 的生命周期影響系統(tǒng) TCP 連接資源

        共 4098字,需瀏覽 9分鐘

         ·

        2021-08-25 12:31


        最近發(fā)現(xiàn)一個(gè) ETCD Client 端的實(shí)現(xiàn)問題——ETCD 所在機(jī)器宕機(jī)或者斷網(wǎng)的情況下,ETCD Client 無法快速重連到可用的 etcd 節(jié)點(diǎn),導(dǎo)致 client 端不可用(該問題的描述后續(xù)發(fā)表文章介紹)。

        后來找到一個(gè)比較簡(jiǎn)單的優(yōu)化方式,即臨時(shí)新創(chuàng)建一個(gè)新的 ETCD 的 Client 來重試操作,可以立即操作成功。但是每次遇到斷網(wǎng)錯(cuò)誤或者斷網(wǎng)時(shí)間比較長(zhǎng),那么這段時(shí)間內(nèi)所有的請(qǐng)求都要重新創(chuàng)建一個(gè)新的 ETCD Client 來重試嗎?頻繁創(chuàng)建 ETCD Client 對(duì)系統(tǒng)有什么影響?此外,還聯(lián)想到在使用 ETCD 初期的時(shí)候,請(qǐng)教過一個(gè)專家同學(xué),關(guān)于 ETCD Client 的使用上,全局使用一個(gè) ETCD Client,還是在需要使用的模塊內(nèi)部使用獨(dú)立的 Client,這兩種方式哪個(gè)更為合理?

        今天,就簡(jiǎn)單的為自己解答一下這幾個(gè)問題哈。本文主要是做一些簡(jiǎn)單的調(diào)研和基礎(chǔ)知識(shí)的分析哈,引出 ETCD Client 的生命周期管理比較合理的方式。

        普及知識(shí)

        先來普及一些基本的概念,便于我們更好的研究和分析哈。ETCD_API=3,即 v3 Client。

        gRPC 相關(guān)的概念

        etcd clientv3 端是基于 gPRC 實(shí)現(xiàn)的。所以,這里先簡(jiǎn)單的描述一下 gRPC 的相關(guān)的基本內(nèi)容哈。

        首先,計(jì)算機(jī)網(wǎng)絡(luò)的 7 層協(xié)議: 物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會(huì)話層、表示層和應(yīng)用層,大家肯定都非常熟悉了。從協(xié)議上來說:

        • TCP[1] 是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸,它解決了第四層傳輸層所指定的功能。
        • HTTP[2] 是應(yīng)用層協(xié)議,主要解決如何包裝數(shù)據(jù),是建立在 TCP 協(xié)議之上的應(yīng)用協(xié)議。因?yàn)?TCP 協(xié)議對(duì)上層應(yīng)用的不友好,所以面向應(yīng)用層的開發(fā)產(chǎn)生了 HTTP 協(xié)議。

        RPC 是遠(yuǎn)程過程調(diào)用,它是一種設(shè)計(jì)、實(shí)現(xiàn)框架,通信協(xié)議只是其中一部分,所以他和 HTTP 并不是對(duì)立的,也沒有包含關(guān)系,本質(zhì)上是提供了一種輕量無感知的跨進(jìn)程通信的方式,通信協(xié)議可以使用 HTTP,也可以使用其他協(xié)議。關(guān)于為何有 HTTP 協(xié)議,為何還要在系統(tǒng)之后通信上使用 RPC 調(diào)用的原因,相信網(wǎng)上有很多論述,這里就不詳細(xì)描述了哈。gRPC 是谷歌開源的一個(gè) RPC 框架,面向移動(dòng)和 HTTP2 設(shè)計(jì)的。和很多 RPC 系統(tǒng)一樣,服務(wù)端負(fù)責(zé)實(shí)現(xiàn)定義好的接口并處理客戶端的請(qǐng)求,客戶端根據(jù)接口描述直接調(diào)用需要的服務(wù)??蛻舳撕头?wù)端可以分別使用 gPRC 支持的不同語(yǔ)言實(shí)現(xiàn)。HTTP2[3] 相對(duì)于 HTTP1.x 具有很多新特性,比如多路復(fù)用,即多個(gè) request 共用一個(gè) TCP 連接,其他特性這里不詳細(xì)敘述了。

        TCP 短連接使用的問題

        TCP 連接是網(wǎng)絡(luò)編程中最基礎(chǔ)的概念,這里就不詳細(xì)介紹 TCP 連接過程了。短連接最大的問題在占用大量的系統(tǒng)資源,例如,socket,而導(dǎo)致這個(gè)問題的原因其實(shí)很簡(jiǎn)單:tcp 連接的使用,都需要經(jīng)過相同的流程:連接建立 -> 數(shù)據(jù)傳輸 -> 連接關(guān)閉。

        對(duì)于系統(tǒng)請(qǐng)求負(fù)載較高的情況下,系統(tǒng)出現(xiàn)的最多和最直觀的錯(cuò)誤應(yīng)該就是 "too many time wait"。這里簡(jiǎn)單說一下 socket 句柄被耗盡的原因,主要因?yàn)?TIME_WAIT 這種狀態(tài)的 TCP 連接的存在。

        由于 socket 是全雙工的工作模式,一個(gè) socket 的關(guān)閉,是需要四次握手來完成的,如下圖所示:

        TCP 連接關(guān)閉過程
        • 主動(dòng)關(guān)閉連接的一方(成為主動(dòng)方),調(diào)用 close,然后發(fā)送 FIN 包給被動(dòng)方,表明自己已經(jīng)準(zhǔn)備關(guān)閉連接;
        • 被動(dòng)方收到 FIN 包后,回復(fù) ACK ,然后進(jìn)入到 CLOSE_WAIT ;
        • 主動(dòng)方等待對(duì)方關(guān)閉,則進(jìn)入 FIN_WAIT_2 狀態(tài);此時(shí),主動(dòng)方等待被動(dòng)方的調(diào)用 close() 操作;
        • 被動(dòng)方在完成所有數(shù)據(jù)發(fā)送后,調(diào)用 close()操作;此時(shí),被動(dòng)方發(fā)送 FIN 包給主動(dòng)方,等待對(duì)方的 ACK,被動(dòng)方進(jìn)入 LAST_ACK 狀態(tài);
        • 主動(dòng)方收到 FIN 包,協(xié)議層回復(fù) ACK ;此時(shí),主動(dòng)方進(jìn)入 TIME_WAIT 狀態(tài);而被動(dòng)方,進(jìn)入 CLOSED 狀態(tài)
        • 等待 2MSL 時(shí)間,主動(dòng)方結(jié)束 TIME_WAIT ,進(jìn)入 CLOSED 狀態(tài)

        通過上面的一次 socket 關(guān)閉操作,可以得出以下幾點(diǎn):

        • 主動(dòng)方最終會(huì)進(jìn)入 TIME_WAIT 狀態(tài);
        • 被動(dòng)方,有一個(gè)中間狀態(tài),即 CLOSE_WAIT,因?yàn)閰f(xié)議層在等待上層的應(yīng)用程序,主動(dòng)調(diào)用 close 操作后才主動(dòng)關(guān)閉這條連接;
        • TIME_WAIT 會(huì)默認(rèn)等待 2MSL 時(shí)間后,才最終進(jìn)入 CLOSED 狀態(tài);
        • 在一個(gè)連接沒有進(jìn)入 CLOSED 狀態(tài)之前,這個(gè)連接是不能被重用的!

        所以,由上面的原理可以看出,TCP 連接的頻繁創(chuàng)建和關(guān)閉,會(huì)導(dǎo)致系統(tǒng)處于 TIME_WAIT 或者 CLOSE_WAIT 狀態(tài)的 TCP 連接變多,占用系統(tǒng)資源,影響正常的功能。

        那么,下面我們看看,gRPC 的 Client 如果不合理的使用,會(huì)造成什么樣的問題呢?

        gRPC Client 生命周期控制問題

        寫個(gè)簡(jiǎn)單的 ETCD Client V3 的小程序,來看看頻繁的創(chuàng)建和關(guān)閉 ETCD Client 會(huì)有什么樣的影響,程序代碼如下:

        // golang

        func TestNewETCDClient() {
            for {
                etcdClient, err := clientv3.New(clientv3.Config{
                    Endpoints:   []string{"10.0.0.2:2379"},
                    DialTimeout: 3 * time.Second,
                })

                if err != nil {
                    logger.Errorf("new client failed due to %v", err)
                    return
                }
                etcdClient.Close()
            }
        }

        然后,我們用如下命令看看系統(tǒng)有什么變化,如下所示,不到一分鐘時(shí)間 TIME_WAIT 暴漲到了 16325 多個(gè)。

        $ netstat -n| awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

        結(jié)論和建議

        前面原理上已經(jīng)解釋過, ETCD Client v3 基于 gRPC 實(shí)現(xiàn),而 gRPC 采用的 HTTP2 協(xié)議,在傳輸層的協(xié)議依然是 tcp。如果對(duì) gRPC 的 Client 的生命周期設(shè)置的非常短,那么相當(dāng)于對(duì)這個(gè) TCP 連接資源轉(zhuǎn)化成了短連接,沒有發(fā)揮其核心功能。

        所以,對(duì)于 ETCD Client 的使用,應(yīng)該充分利用其多路復(fù)用的原則,全局定義一個(gè) Client 變量,生命同期等同于進(jìn)程,以降低對(duì) TCP 資源的管理成本。

        參考文章

        • 你所不知道的 TIME_WAIT 和 CLODE_WAIT[4]

        引用鏈接

        [1]

        TCP: https://tools.ietf.org/html/rfc793

        [2]

        HTTP: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

        [3]

        HTTP2: https://zh.wikipedia.org/wiki/HTTP/2

        [4]

        你所不知道的 TIME_WAIT 和 CLODE_WAIT: https://blog.oldboyedu.com/tcp-wait/


        原文鏈接:https://developer.aliyun.com/article/704034


        你可能還喜歡

        點(diǎn)擊下方圖片即可閱讀

        K8s 的節(jié)點(diǎn)問題檢測(cè)器原理解析

        云原生是一種信仰 ??

        關(guān)注公眾號(hào)

        后臺(tái)回復(fù)?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



        點(diǎn)擊 "閱讀原文" 獲取更好的閱讀體驗(yàn)!


        發(fā)現(xiàn)朋友圈變“安靜”了嗎?

        瀏覽 89
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久热草视频 | 五月丁香色婷婷七月在线视频 | www.婷色情网一区 | 少妇放荡的呻吟干柴烈火动态图 | 18桃色在线观看网站 | 《乳色吐息》免费看 | 欧美国产日韩在线观看 | 爆操人妻在线 | 久久夜色精品国产欧美乱 | 91超碰在线播放 |