日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
你了解微服務(wù)的超時傳遞嗎?

[[429473]]

本文轉(zhuǎn)載自微信公眾號「微服務(wù)實踐」,作者zhoushuguang。轉(zhuǎn)載本文請聯(lián)系微服務(wù)實踐公眾號。

成都創(chuàng)新互聯(lián)公司10多年成都企業(yè)網(wǎng)站建設(shè)服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及高端網(wǎng)站定制服務(wù),成都企業(yè)網(wǎng)站建設(shè)及推廣,對成都混凝土攪拌罐等多個行業(yè)擁有豐富的營銷推廣經(jīng)驗的網(wǎng)站建設(shè)公司。

為什么需要超時控制?

很多連鎖故障的場景下的一個常見問題是服務(wù)器正在消耗大量資源處理那些早已經(jīng)超過客戶端截止時間的請求,這樣的結(jié)果是,服務(wù)器消耗大量資源沒有做任何有價值的工作,回復(fù)已經(jīng)超時的請求是沒有任何意義的。

超時控制可以說是保證服務(wù)穩(wěn)定性的一道重要的防線,它的本質(zhì)是快速失敗(fail fast),良好的超時控制策略可以盡快清空高延遲的請求,盡快釋放資源避免請求的堆積。

服務(wù)間超時傳遞

如果一個請求有多個階段,比如由一系列 RPC 調(diào)用組成,那么我們的服務(wù)應(yīng)該在每個階段開始前檢查截止時間以避免做無用功,也就是要檢查是否還有足夠的剩余時間處理請求。

一個常見的錯誤實現(xiàn)方式是在每個 RPC 服務(wù)設(shè)置一個固定的超時時間,我們應(yīng)該在每個服務(wù)間傳遞超時時間,超時時間可以在服務(wù)調(diào)用的最上層設(shè)置,由初始請求觸發(fā)的整個 RPC 樹會設(shè)置同樣的絕對截止時間。例如,在服務(wù)請求的最上層設(shè)置超時時間為3s,服務(wù)A請求服務(wù)B,服務(wù)B執(zhí)行耗時為1s,服務(wù)B再請求服務(wù)C這時超時時間剩余2s,服務(wù)C執(zhí)行耗時為1s,這時服務(wù)C再請求服務(wù)D,服務(wù)D執(zhí)行耗時為500ms,以此類推,理想情況下在整個調(diào)用鏈里都采用相同的超時傳遞機制。

如果不采用超時傳遞機制,那么就會出現(xiàn)如下情況:

  • 服務(wù)A給服務(wù)B發(fā)送一個請求,設(shè)置的超時時間為3s
  • 服務(wù)B處理請求耗時為2s,并且繼續(xù)請求服務(wù)C
  • 如果使用了超時傳遞那么服務(wù)C的超時時間應(yīng)該為1s,但這里沒有采用超時傳遞所以超時時間為在配置中寫死的3s
  • 服務(wù)C繼續(xù)執(zhí)行耗時為2s,其實這時候最上層設(shè)置的超時時間已截止,如下的請求無意義
  • 繼續(xù)請求服務(wù)D

如果服務(wù)B采用了超時傳遞機制,那么在服務(wù)C就應(yīng)該立刻放棄該請求,因為已經(jīng)到了截止時間,客戶端可能已經(jīng)報錯。我們在設(shè)置超時傳遞的時候一般會將傳遞出去的截止時間減少一點,比如100毫秒,以便將網(wǎng)絡(luò)傳輸時間和客戶端收到回復(fù)之后的處理時間考慮在內(nèi)。

進程內(nèi)超時傳遞

不光服務(wù)間需要超時傳遞進程內(nèi)同樣需要進行超時傳遞,比如在一個進程內(nèi)串行的調(diào)用了Mysql、Redis和服務(wù)B,設(shè)置總的請求時間為3s,請求Mysql耗時1s后再次請求Redis這時的超時時間為2s,Redis執(zhí)行耗時500ms再請求服務(wù)B這時候超時時間為1.5s,因為我們的每個中間件或者服務(wù)都會在配置文件中設(shè)置一個固定的超時時間,我們需要取剩余時間和設(shè)置時間中的最小值。

context實現(xiàn)超時傳遞

context原理非常簡單,但功能卻非常強大,go的標(biāo)準(zhǔn)庫也都已實現(xiàn)了對context的支持,各種開源的框架也實現(xiàn)了對context的支持,context已然成為了標(biāo)準(zhǔn),超時傳遞也依賴context來實現(xiàn)。

我們一般在服務(wù)的最上層通過設(shè)置初始context進行超時控制傳遞,比如設(shè)置超時時間為3s

 
 
 
 
  1. ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) 
  2. defer cancel() 

當(dāng)進行context傳遞的時候,比如上圖中請求Redis,那么通過如下方式獲取剩余時間,然后對比Redis設(shè)置的超時時間取較小的時間

 
 
 
 
  1. dl, ok := ctx.Deadline() 
  2. timeout := time.Now().Add(time.Second * 3) 
  3. if ok := dl.Before(timeout); ok { 
  4.  timeout = dl 

服務(wù)間超時傳遞主要是指 RPC 調(diào)用時候的超時傳遞,對于 gRPC 來說并不需要要我們做額外的處理,gRPC 本身就支持超時傳遞,原理和上面差不多,是通過 metadata 進行傳遞,最終會被轉(zhuǎn)化為 grpc-timeout 的值,如下代碼所示 grpc-go/internal/transport/handler_server.go:79

 
 
 
 
  1. if v := r.Header.Get("grpc-timeout"); v != "" { 
  2.   to, err := decodeTimeout(v) 
  3.   if err != nil { 
  4.    return nil, status.Errorf(codes.Internal, "malformed time-out: %v", err) 
  5.   } 
  6.   st.timeoutSet = true 
  7.   st.timeout = to 

超時傳遞是保證服務(wù)穩(wěn)定性的一道重要防線,原理和實現(xiàn)都非常簡單,你們的框架中實現(xiàn)了超時傳遞了嗎?如果沒有的話就趕緊動起手來吧。

go-zero 中的超時傳遞

go-zero 中可以通過配置文件中的 Timeout 配置 api gateway 和 rpc 服務(wù)的超時,并且會在服務(wù)間自動傳遞。

之前的 一文搞懂如何實現(xiàn) Go 超時控制 里面有講解超時控制如何使用。

參考

《SRE:Google運維解密》

項目地址

https://github.com/zeromicro/go-zero


本文題目:你了解微服務(wù)的超時傳遞嗎?
分享URL:http://m.5511xx.com/article/ccsccjs.html