<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4098字,需瀏覽 9分鐘

           ·

          2021-08-25 12:31


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

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

          今天,就簡單的為自己解答一下這幾個問題哈。本文主要是做一些簡單的調研和基礎知識的分析哈,引出 ETCD Client 的生命周期管理比較合理的方式。

          普及知識

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

          gRPC 相關的概念

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

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

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

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

          TCP 短連接使用的問題

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

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

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

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

          通過上面的一次 socket 關閉操作,可以得出以下幾點:

          • 主動方最終會進入 TIME_WAIT 狀態(tài);
          • 被動方,有一個中間狀態(tài),即 CLOSE_WAIT,因為協(xié)議層在等待上層的應用程序,主動調用 close 操作后才主動關閉這條連接;
          • TIME_WAIT 會默認等待 2MSL 時間后,才最終進入 CLOSED 狀態(tài);
          • 在一個連接沒有進入 CLOSED 狀態(tài)之前,這個連接是不能被重用的!

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

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

          gRPC Client 生命周期控制問題

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

          // 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)有什么變化,如下所示,不到一分鐘時間 TIME_WAIT 暴漲到了 16325 多個。

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

          結論和建議

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

          所以,對于 ETCD Client 的使用,應該充分利用其多路復用的原則,全局定義一個 Client 變量,生命同期等同于進程,以降低對 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


          你可能還喜歡

          點擊下方圖片即可閱讀

          K8s 的節(jié)點問題檢測器原理解析

          云原生是一種信仰 ??

          關注公眾號

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



          點擊 "閱讀原文" 獲取更好的閱讀體驗!


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

          瀏覽 89
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  av在线资源观看 a黄色在线视频无 | 操鼻素材大全在线观看 | 豆花无码短视频在线观看网址 | 西西人体大胆4444w 6 2w | 人人草免费公开 |