欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang在GRPC中設(shè)置client的超時時間

 更新時間:2021年04月27日 14:32:44   作者:hzzyu  
這篇文章主要介紹了golang在GRPC中設(shè)置client的超時時間,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

超時

建立連接

主要就2函數(shù)Dail和DialContext。

// Dial creates a client connection to the given target.
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
    return DialContext(context.Background(), target, opts...)
}
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error){...}

DialContext 太長了不帖了.看Dial實際上也是調(diào)用DialContext來實現(xiàn)的.如果你想在建立連接的時候使用超時控制.就使用

DialContext傳入一個Timeout的context,就像下面的例子

ctx1, cel := context.WithTimeout(context.Background(), time.Second*3)
defer cel()
conn, err := grpc.DialContext(ctx1, address, grpc.WithBlock(), grpc.WithInsecure())

另外調(diào)用Dial建立連接默認(rèn)只是返回一個ClientConn的指針,相當(dāng)于new了一個ClientConn 把指針返回給你。并不是一定要建立真實的h2連接.至于真實的連接建立實際上是一個異步的過程。

當(dāng)然了如果你想等真實的鏈接完全建立再返回ClientConn可以通過WithBlock傳入Options來實現(xiàn),當(dāng)然了這樣的話鏈接如果建立不成功就會一直阻塞直到Contex超時。

真正的建立鏈接的代碼后面介紹重試的時候會再詳細(xì)介紹。

調(diào)用超時

這個比較簡單

ctx, cancel := context.WithTimeout(context.TODO(), time.Second*3)
defer cancel()
 r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})

如上代碼傳入一個timeout context就可以。

Server

type SearchService struct{}
 
func (s *SearchService) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
    for i := 0; i < 5; i++  {
        if ctx.Err() == context.Canceled {
            return nil, status.Errorf(codes.Canceled, "SearchService.Search canceled")
        }
 
        time.Sleep(1 * time.Second)
    }
 
    return &pb.SearchResponse{Response: r.GetRequest() + " Server"}, nil
}
 
func main() {
    ...
}

而在 Server 端,由于 Client 已經(jīng)設(shè)置了截止時間。Server 勢必要去檢測它

否則如果 Client 已經(jīng)結(jié)束掉了,Server 還傻傻的在那執(zhí)行,這對資源是一種極大的浪費

因此在這里需要用 ctx.Err() == context.Canceled 進(jìn)行判斷,為了模擬場景我們加了循環(huán)和睡眠 ?

驗證

重新啟動 server.go 和 client.go,得到結(jié)果:

$ go run client.go
2018/10/06 17:45:55 client.Search err: deadline
exit status 1

總結(jié)

本章節(jié)比較簡單,你需要知道以下知識點:

怎么設(shè)置 Deadlines

為什么要設(shè)置 Deadlines

你要清楚地明白到,gRPC Deadlines 是很重要的,否則這小小的功能點就會要了你生產(chǎn)的命。

補充:golang使用grpc超時控制和對沖策略

超時控制

grcp超時控制設(shè)置在客戶端調(diào)用服務(wù)時,如果設(shè)定了超時時間,客戶端會立即返回超時。超時控制一般有三個因素:鏈路超時:上有調(diào)用端通過協(xié)議字段把自己允許的超時時間傳給當(dāng)前服務(wù),表示在該時間內(nèi)返回數(shù)據(jù),超時返回已無意義。流程如下圖A調(diào)用B的總超時情況。

消息超時:服務(wù)端收到請求消息到返回響應(yīng)數(shù)據(jù)的最長消息處理時間。下圖的B內(nèi)部的當(dāng)前請求整體超時時間。調(diào)用超時:當(dāng)前服務(wù)調(diào)用下游服務(wù)設(shè)置的每一個rpc請求的超時時間。如下圖B調(diào)用C的單個超時時間。通常一次請求會連續(xù)調(diào)用多次rpc,這個調(diào)用超時控制的是每個rpc的獨立超時時間。

全鏈路超時控制模型原理圖

發(fā)起rpc調(diào)用請求時,需要計算此次rpc調(diào)用的超時時間。真正生效的超時時間是通過以上三個因素實時計算的最小值,計算過程

如下:

1、首先計算鏈路超時和消息超時的最小值,如鏈路超時2s,消息超時1s,則當(dāng)前消息的最長處理時間為1s。

2、發(fā)起rpc調(diào)用時,再次計算當(dāng)前消息最長處理時間和單個超時時間的最小值,比如:上圖的B->C設(shè)置的單個超時時間為5s,則實際上B調(diào)用C的真實超時仍然是1s,其實只要超時時間大于當(dāng)前最長處理時間都是無效的,都會取最小值。再比如B->C單個超時時間為500ms,這種情況B調(diào)用C的真實超時即為500ms,此時500ms這個值也會通過協(xié)議字段傳給C,在服務(wù)端C的視角來看就是他的鏈路超時時間。鏈路超時時間會在整個rpc調(diào)用鏈上一直傳遞下去,并逐漸減少,直至為0,這樣避免出現(xiàn)死循環(huán)調(diào)用的問題。

3、因為每一次rpc調(diào)用都會實際消耗一部分時間,所以當(dāng)前消息最長處理時間需要實時計算剩余時間,比如上面B調(diào)用C真實耗時200ms,此時最長處理時間就只剩下800ms了。此時發(fā)起第二次rpc調(diào)用時,則需要計算此時剩余的消息超時時間和單個調(diào)用時間的最小值。如上圖的B->D設(shè)置的單個超時時間為1s,則實際生效的超時時間仍然為800ms。鏈路超時設(shè)置:golang的context.Context根據(jù)協(xié)議里面的timeout字段和框架配置的timeout字段。設(shè)置好當(dāng)前請求的最長處理時間,然后交給用戶使用,并在處理函數(shù)結(jié)束時會立馬cancel掉當(dāng)前context。所以在創(chuàng)建新的goroutine時,需要重新設(shè)定新的context。

對沖策略

對沖策略不是被動的等待上一次請求超時或者失敗,在對沖延時時間內(nèi)(或小于超時時間)如果沒有收到回復(fù)的包就會再觸發(fā)一個請求。

與重試策略不同的是同一時間內(nèi)in-fliaght可能有多個,當(dāng)接收到第一回復(fù)時,其他的回復(fù)會被忽略。

一、重試策略:

對失敗的請求,進(jìn)行重新請求。

在這里插入圖片描述

由圖中可以看出,client一共進(jìn)行了三次請求,前兩次均失敗,并且在重新請求時都會隨機避段時間,防止請求毛刺,第三次請求成功,返回給應(yīng)用層。對于每次嘗試,我們都會盡可能地將請求發(fā)往不同的節(jié)點。

通常重試策略有三種配置:

1、失敗重新請求的最大次數(shù),達(dá)到最大次數(shù)仍然失敗,不再進(jìn)行重試;

2、退避時間:退避時間取的是 random(0, delay);

3、可重試錯誤碼:設(shè)置可錯誤碼,對于不可重試的,立即停止重試并將錯誤返回應(yīng)用層。

二、對沖策略

在這里插入圖片描述

上圖中client一共進(jìn)行了4次,橙、藍(lán)、綠、紫

橙色是第一次嘗試。在由 client 發(fā)起后,server2 很快便收到了。但是 server2 的因為網(wǎng)絡(luò)等問題,直到綠色請求成功,并返回給應(yīng)用層后,它的正確回包才姍姍來遲。盡管它成功了,但我們必須丟棄它,因為我們已經(jīng)將另一個成功的回包返回給應(yīng)用層了。

藍(lán)色是第二次嘗試。因為橙色請求在對沖時延(hedging delay)后還沒有回包,因此我們發(fā)起了一次新的嘗試。這次嘗試選擇了 server1(我們會盡可能地為每次嘗試選擇不同的節(jié)點)。藍(lán)色嘗試的回包比較快,在對沖時延之前便返回了。但是卻失敗了。我們立刻發(fā)起了新一次嘗試。

綠色是第三次嘗試。盡管它的回包可能有點慢(超過了對沖時延,因此又觸發(fā)了一次新的嘗試),但是它成功了!一旦我們收到第一個成功的回包,便立刻將它返回給了應(yīng)用層。

紫色是第四次嘗試。剛發(fā)起后,我們便收到了綠色成功的回包。對紫色來說,它可能處于很多狀態(tài):請求還在 client gRPC 內(nèi),這時,我們有機會取消它;請求已經(jīng)進(jìn)入了 client 的內(nèi)核或者已經(jīng)由網(wǎng)卡發(fā)出,無論如何,我們已經(jīng)沒有機會取消它了。紫色請求上的 ✘ 表示我們會盡可能地取消紫色請求。注意,即使紫色請求最終成功地到達(dá)了 server2,它的回包也會像橙色一樣被丟棄。

由以上可知對沖策略更像是添加了等待時間的重試,但是他沒有退避機制,一旦收到錯誤的包,立刻發(fā)起重試。這種對于需要解決長尾問題時推薦使用,一般情況建議使用重試策略。

對沖策略一般有三種配置

1、對沖延時:在對對沖時延內(nèi)沒有收到回包時便會立刻發(fā)起新的嘗試;

2、最大請求次數(shù):一旦耗盡,便等待并返回最后一個回包,無論它是否成功或失??;

3、非致命錯誤:返回致命錯誤會立刻中止對沖,等待并返回最后一個回包,無論它是否成功或失敗。返回非致命錯誤會立刻觸發(fā)一次新的嘗試(對沖時延計時器會被重置)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Go語言中的包Package詳解

    Go語言中的包Package詳解

    本文詳細(xì)講解了Go語言中的包Package,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • 利用golang進(jìn)行OpenCV學(xué)習(xí)和開發(fā)的步驟

    利用golang進(jìn)行OpenCV學(xué)習(xí)和開發(fā)的步驟

    目前,OpenCV逐步成為一個通用的基礎(chǔ)研究和產(chǎn)品開發(fā)平臺,下面這篇文章主要給大家介紹了關(guān)于利用golang進(jìn)行OpenCV學(xué)習(xí)和開發(fā)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-09-09
  • Go連接數(shù)據(jù)庫操作基礎(chǔ)講解

    Go連接數(shù)據(jù)庫操作基礎(chǔ)講解

    這篇文章主要為大家介紹了Go連接數(shù)據(jù)庫操作基礎(chǔ)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 淺析Go語言中的同步與異步處理

    淺析Go語言中的同步與異步處理

    在開發(fā)過程中,當(dāng)需要同時處理多個操作時,開發(fā)者經(jīng)常面臨同步和異步兩種處理方式的選擇,下面小編就來和大家詳細(xì)介紹一下Go語言中的同步與異步處理吧
    2023-11-11
  • Go語言metrics應(yīng)用監(jiān)控指標(biāo)基本使用說明

    Go語言metrics應(yīng)用監(jiān)控指標(biāo)基本使用說明

    這篇文章主要為大家介紹了Go語言metrics應(yīng)用監(jiān)控指標(biāo)的基本使用說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • go語言中的指針自動解引用

    go語言中的指針自動解引用

    Go語言中,編譯器會自動解引用指針來訪問字段,自動解引用使得使用指針訪問結(jié)構(gòu)體字段和方法變得更加直觀,降低了編程錯誤的風(fēng)險,并使代碼更易于理解和維護
    2024-10-10
  • Go?1.21新內(nèi)置函數(shù)min、max和clear的用法詳解

    Go?1.21新內(nèi)置函數(shù)min、max和clear的用法詳解

    Go?1.21?版本已經(jīng)正式發(fā)布,它帶來了許多新特性和改進(jìn),其中引入了的三個新內(nèi)置函數(shù):max、min?和?clear,接下來我們就來看看這些函數(shù)的用途和特點吧
    2023-08-08
  • 一篇文章說清楚?go?get?使用私有庫的方法

    一篇文章說清楚?go?get?使用私有庫的方法

    這篇文章主要介紹了go?get?如何使用私有庫,本文會明確指出Git?、golang的配置項,附送TortoiseGit?+?Git混合配置,需要的朋友可以參考下
    2022-09-09
  • Go語言生成隨機數(shù)的方法

    Go語言生成隨機數(shù)的方法

    這篇文章主要介紹了Go語言生成隨機數(shù)的方法,實例分析了Go語言生成隨機數(shù)的原理與實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 使用GO操作MongoDB的方法

    使用GO操作MongoDB的方法

    這篇文章主要介紹了使用GO操作MongoDB,包括安裝MongoDB驅(qū)動程序連接mongodb的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05

最新評論