成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你了解微服務的超時傳遞嗎?

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

[[429473]]

本文轉載自微信公眾號「微服務實踐」,作者zhoushuguang。轉載本文請聯系微服務實踐公眾號。

為什么需要超時控制?

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

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

服務間超時傳遞

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

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

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

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

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

進程內超時傳遞

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

context實現超時傳遞

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

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

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

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

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

服務間超時傳遞主要是指 RPC 調用時候的超時傳遞,對于 gRPC 來說并不需要要我們做額外的處理,gRPC 本身就支持超時傳遞,原理和上面差不多,是通過 metadata 進行傳遞,最終會被轉化為 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 

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

go-zero 中的超時傳遞

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

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

參考

《SRE:Google運維解密》

項目地址

 

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

 

責任編輯:武曉燕 來源: 微服務實踐
相關推薦

2024-06-04 07:58:31

架構本質微服務

2016-09-26 14:45:46

微服務

2024-05-10 08:46:13

微服務架構技術

2018-10-28 18:09:22

微服務Microservic架構

2022-11-11 17:09:55

微服務RPC

2018-03-19 09:13:16

2018-07-30 08:23:30

微服務架構設計

2024-05-17 16:18:45

微服務灰度發布金絲雀發布

2019-10-31 08:36:59

線程內存操作系統

2018-11-21 09:32:10

IT云計算

2012-02-06 13:52:33

JavaScript

2012-09-27 10:24:22

監控機房

2012-09-06 17:54:28

2014-04-17 16:42:03

DevOps

2022-07-26 00:00:22

HTAP系統數據庫

2025-01-03 08:09:15

2010-09-07 14:54:01

PPP幀中繼

2023-11-09 08:22:38

2023-01-07 10:17:06

微服務架構模式

2024-06-12 08:05:06

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级二级三级视频 | 亚洲人成在线观看 | 午夜免费在线观看 | 在线播放国产一区二区三区 | 久久一二| 黄视频网址| 男女羞羞在线观看 | 免费成人在线网 | 国产免费a视频 | 国产精品免费一区二区三区四区 | jdav视频在线观看免费 | 91国内精品久久 | 亚洲中午字幕 | 99亚洲综合 | 国产真实精品久久二三区 | 久久久久国色av免费观看性色 | 精品国产乱码久久久久久闺蜜 | 亚洲精品视频免费观看 | 天天躁日日躁狠狠很躁 | 欧美一区二区大片 | 国产一区二区在线播放视频 | 亚洲精品久久久久久一区二区 | 欧美影院| 亚洲国产精品成人久久久 | 天天干视频 | 手机三级电影 | 午夜午夜精品一区二区三区文 | 伊人狠狠 | 四季久久免费一区二区三区四区 | 国产精品视频一区二区三 | 91精品久久久久久久久久小网站 | 性色视频在线观看 | 亚洲欧美日韩一区 | 日本精品一区二区在线观看 | 国产精品免费av | 欧美区日韩区 | 久久久久亚洲精品 | 精品国产久 | 国产精品女人久久久 | 中文字幕一区二区三区不卡 | 91在线观看网址 |