91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

GRPC連接池如何實現

發布時間:2021-12-18 15:36:35 來源:億速云 閱讀:224 作者:iii 欄目:云計算

這篇文章主要講解了“GRPC連接池如何實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“GRPC連接池如何實現”吧!

前言

在分布式高并發服務器中,client到server以及server中的多個節點之間的連接往往使用連接池來管理。簡單來說就是將提前創建好的連接保存在池中,當有請求到來時,直接使用連接池中的連接對server端訪問,省去了創建連接和銷毀連接的開銷(TCP建立連接時的三次握手和釋放連接時的四次揮手),從而提高了性能。

<a name="chapter1"></a>設計原則

  • 連接池的擴縮容

  • 空閑連接的超時與保活

  • 池滿的處理機制

連接池的擴縮容

通常連接池屬性包含最大空閑連接數和最大活躍連接數。

最大空閑連接數:連接池一直保持的連接數,無論這些連接被使用與否都會被保持。如果客戶端對連接池的使用量不大,便會造成服務端連接資源的浪費。

最大活躍連接數:連接池最多保持的連接數,如果客戶端請求超過次數,便要根據池滿的處理機制來處理沒有得到連接的請求。

擴容:當請求到來時,如果連接池中沒有空閑的連接,同時連接數也沒有達到最大活躍連接數,便會按照特定的增長策略創建新的連接服務該請求,同時用完之后歸還到池中,而不是關閉連接。

縮容:當連接池一段時間沒有被使用,同時池中的連接數超過了最大空閑連接數,那么便會關閉一部分連接,使池中的連接數始終維持在最大空閑連接數。

空閑連接的超時與保活

超時 如果連接沒有被客戶端使用的話,便會成為空閑連接,在一段時間后,服務端可能會根據自己的超時策略關閉空閑連接,此時空閑連接已經失效,如果客戶端再使用失效的連接,便會通信失敗。為了避免這種情況發生,通常連接池中的連接設有最大空閑超時時間(最好略小于服務器的空閑連接超時時間),在從池中獲取連接時,判斷是否空閑超時,如果超時則關閉,沒有超時則可以繼續使用。

保活 如果服務器發生重啟,那么連接池中的連接便會全部失效,如果此時再從池中獲取連接,不論獲取到哪一個,都將通信失敗。因此,連接池必須考慮連接的保活問題,有兩種解決方法:

1、連接池設置一個Ping函數,專門用來做連接的保活。在從池中獲取連接的時候,Ping一下服務器,如果得到響應,則連接依然有效,便可繼續使用,如果超時無響應,則關閉該連接,生成新的連接,由于每次都要Ping一下,必然會增加延遲。也可以后臺用一個線程或者協程定期的執行Ping函數,進行連接的保活,缺點是感知連接的失效會有一定的延遲,從池中仍然有可能獲取到失效的連接。

2、客戶端加入相應的重試機制。比如重試3次,前兩次從池中獲取連接執行,如果報的錯是失效的連接等有關連接問題的錯誤,那么第3次從池中獲取的時候帶上參數,指定獲取新建的連接,同時連接池移除前兩次獲取的失效的連接。

池滿的處理機制

連接池不可能無限的容納連接,當池滿時,有兩種處理機制:

1、池新建連接,并返回給客戶端,當客戶端用完時,如果池滿則關閉連接,否則放入池中。

2、設置一定的超時時間來等待空閑連接。需要客戶端加入重試機制,避免因超時之后獲取不到空閑連接產生的錯誤。

<a name="chapter2"></a>基本原理

  1. 服務啟動時建立連接池。

  2. 初始化連接池,建立最大空閑連接數個連接。

  3. 請求到來時,從池中獲取一個連接。如果沒有空閑連接且連接數沒有達到最大活躍連接數,則新建連接;如果達到最大活躍連接數,設置一定的超時時間,等待獲取空閑連接。

  4. 獲取到連接后進行通信服務。

  5. 釋放連接,此時是將連接放回連接池,如果池滿則關閉連接。

  6. 釋放連接池,關閉所有連接。

<a name="chapter3"></a>GRPC特性

關于GRPC的介紹,不在這里闡述,可閱讀深入了解GRPC協議,也可自行Google。這里主要簡要說明GRPC的兩個特性:多路復用、超時重連。

多路復用GRPC使用HTTP/2作為應用層的傳輸協議,HTTP/2會復用底層的TCP連接。每一次RPC調用會產生一個新的Stream,每個Stream包含多個Frame,Frame是HTTP/2里面最小的數據傳輸單位。同時每個Stream有唯一的ID標識,如果是客戶端創建的則ID是奇數,服務端創建的ID則是偶數。如果一條連接上的ID使用完了,Client會新建一條連接,Server也會給Client發送一個GOAWAY Frame強制讓Client新建一條連接。一條GRPC連接允許并發的發送和接收多個Stream,而控制的參數便是MaxConcurrentStreams,Golang的服務端默認是100。

超時重連我們在通過調用Dial或者DialContext函數創建連接時,默認只是返回ClientConn結構體指針,同時會啟動一個Goroutine異步的去建立連接。如果想要等連接建立完再返回,可以指定grpc.WithBlock()傳入Options來實現。超時機制很簡單,在調用的時候傳入一個timeout的context就可以了。重連機制通過啟動一個Goroutine異步的去建立連接實現的,可以避免服務器因為連接空閑時間過長關閉連接、服務器重啟等造成的客戶端連接失效問題。也就是說通過GRPC的重連機制可以完美的解決連接池設計原則中的空閑連接的超時與保活問題。

以Golang的GRPC客戶端為例: GRPC連接池如何實現

<a name="chapter4"></a>GRPC調優

GRPC默認的參數對于傳輸大數據塊來說不夠友好,我們需要進行特定參數的調優。

MaxSendMsgSizeGRPC最大允許發送的字節數,默認4MiB,如果超過了GRPC會報錯。Client和Server我們都調到4GiB。

MaxRecvMsgSizeGRPC最大允許接收的字節數,默認4MiB,如果超過了GRPC會報錯。Client和Server我們都調到4GiB。

InitialWindowSize基于Stream的滑動窗口,類似于TCP的滑動窗口,用來做流控,默認64KiB,吞吐量上不去,Client和Server我們調到1GiB。

InitialConnWindowSize基于Connection的滑動窗口,默認16 * 64KiB,吞吐量上不去,Client和Server我們也都調到1GiB。

KeepAliveTime每隔KeepAliveTime時間,發送PING幀測量最小往返時間,確定空閑連接是否仍然有效,我們設置為10S。

KeepAliveTimeout超過KeepAliveTimeout,關閉連接,我們設置為3S。

PermitWithoutStream如果為true,當連接空閑時仍然發送PING幀監測,如果為false,則不發送忽略。我們設置為true。

<a name="chapter5"></a>實現細則

代碼:https://github.com/shimingyah/pool

基于GRPC的多路復用、超時重連特性,我們很容易實現GRPC連接池。

接口設計

提供簡潔的Pool和Conn的接口設計。 GRPC連接池如何實現 GRPC連接池如何實現

連接復用

GRPC是支持多路復用的,所以在設計GRPC池的時候和其他連接池區別之一是支持連接復用,通過MaxConcurrentStreams控制,默認64。我們稱單個的GRPC為物理連接,復用的連接為邏輯連接。池的實際有效連接邏輯連接=物理連接 * MaxConcurrentStreams

擴縮容

擴容初始化池的有效連接數(邏輯連接)為:最大空閑連接數 * MaxConcurrentStreams,每一次請求都會對池的引用計數原子++,同時hash求取選取連接,當引用計數超過邏輯連接數時,就需要進行擴容了,如果最大空閑連接沒有達到最大活躍連接數,則按照double的方式擴容,如果達到了最大活躍連接數,我們會根據Reuse參數的值來做進一步操作:如果為true,則繼續使用池中的連接,即使用的是物理連接的邏輯連接,關閉連接時,對引用計數原子--即可,如果為false,則新建連接,關閉連接時還需要對連接進行真正的Close。

縮容如果池的引用計數為0時,便會觸發縮容操作,是連接維持到最大空閑連接數。

超時保活

基于GRPC的Keepalived特性,我們不需要自己實現保活機制,也無需關注連接池中的連接是否有效,因為就算失效,GRPC會自動重連的,此時只不過耗時會略微增加,即認為除了服務器一直處于down狀態等原因,連接池中的連接是始終有效的。

Tips
  • 由于使用hash求余,每個GRPC上并發的Stream可能會超過MaxConcurrentStreams。

  • 不同場景對應的連接池配置也不一樣,需要根據自己的場景壓測得出連接池的最佳參數配置。

感謝各位的閱讀,以上就是“GRPC連接池如何實現”的內容了,經過本文的學習后,相信大家對GRPC連接池如何實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万山特区| 剑川县| 巴塘县| 苏尼特右旗| 蓬莱市| 长宁县| 二手房| 启东市| 崇明县| 苏尼特右旗| 广宗县| 吴忠市| 建水县| 曲阜市| 孟州市| 拉孜县| 兴城市| 内乡县| 乐亭县| 江山市| 康定县| 开江县| 隆德县| 高雄县| 阿克陶县| 古交市| 崇礼县| 托克托县| 南通市| 特克斯县| 永昌县| 长岭县| 杭锦旗| 满城县| 北流市| 新昌县| 宜君县| 巴东县| 西乌珠穆沁旗| 抚松县| 临泉县|