天天看點

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

微服務是⼀種分布式架構,系統内各部分(服務)被部署為單獨的應用程式,并通過某種遠端通路協定進⾏通訊。分布式應⽤的挑戰之⼀就是如何管理遠端服務的可用性和它們的響應。本⽂主要探讨服務的響應時間對系統的影響和應對。

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

上圖是簡化的微服務調用鍊路過程,為清晰闡述三個相關方,圖中的用戶端被限定為使用者端(如移動端應用、浏覽器頁面等),服務端被區分為服務消費方(網絡調用中用戶端)和服務提供方(網絡調用中服務端)。⼤部分服務既為服務消費方,⼜為服務提供方,如處于調⽤鍊路中間的業務服務,大機率需要去整合資料,是以通常會同時作為服務消費方和服務提供方,兩種資源消耗并存。小部分服務是純粹的服務提供方,如資料庫、緩存、ZooKeeper 等。下⽂先來分析服務響應時間過⻓對資源消耗問題。

資源消耗分析

靜态分析

微服務都有⾃身的硬體資源上限,直覺來看,響應時間會對資源消耗産⽣直接影響。

服務消費方

  • 協定消耗,每次發起 TCP 連接配接請求時,通常會讓系統選取⼀個空閑的本地端⼝(local port),該端⼝是獨占的,不能和其他 TCP 連接配接共享。TCP 端⼝的資料類型是 unsigned short,是以可⽤端⼝最多隻有 65535,是以在全部作為 client 端的情況下,最⼤TCP 連接配接數 65535。
  • 除端⼝消耗外,發起調⽤的業務程序、線程、協程等待過程中,⽆法釋放其所消耗的記憶體、CPU 等,是服務消費⽅發起調⽤的主要消耗。

服務提供方

  • 協定消耗,主要是建⽴連接配接的消耗,每接收每⼀個 tcp 連接配接都要占⼀個⽂件描述符,理論上是 server 端單機最⼤tcp 連接配接數約為 2 的 48 次方。
  • 業務邏輯消耗。在複雜的業務邏輯、機器資源和⽹絡帶寬條件下,最⼤并發 tcp 連接配接數遠不能達到理論上限,有時候會發現,單機 1w 并發往往也是⽐較困難。是以,服務提供⽅主要是業務邏輯的⼤量資源消耗,如 CPU、⽹絡帶寬、磁盤 IO 等。

動态分析

在調⽤持續發⽣且服務提供⽅不及時傳回的情況下,未觸發性能拐點前,可以簡化認為資源的消耗是線性增⻓。微服務發起⼀個請求,會占⽤⼀個空閑的本地端⼝,當然,每個連接配接所對應的業務處理過程,也會對應消耗記憶體、IO、CPU 消耗等資源,

簡化為如下公式:

RR = RT - QPS * RCPR * Duration- Release * Tinny_T

其中,資源容量(rt, Resource Total )受單機性能影響,可以簡化為固定值;單請求消耗資源數(rcpr , ResourceCostPerRequest)受業務影響,也可以簡化為固定值。

那麼,資源剩餘數(RR, Resource Remaining),将受這三個變量影響:每秒請求數(QPS)、請求持續時間 (Duration )和資源釋放的速度( Release *Tinny_T)。

在連接配接不釋放的情境下,Release 簡化為 0,則上⾯公式簡化為:

RR = RT - QPS * RCPR * Duration

可以看到,系統所剩餘資源,随 Duration 線性減少,最終被耗盡。

這⾥額外讨論下池化技術,池化技術是⼀個⾮常重要的技術,如連接配接池可以避免 重新建立連接配接,在提⾼效率的同時也限制資源不受控的消耗。Redis、資料庫 (Mysql、Mongo)等中間件連接配接驅動⼤都采⽤連接配接池。如 Golang Mysql 連接配接池設定 如下:

db.SetConnMaxLifetime(time.Minute * 3)              db.SetMaxOpenConns(10)              db.SetMaxIdleConns(10)           

複制代碼

雖然有池化技術,但是如果連接配接未得到及時釋放,且連接配接池未設定最⼤連接配接數的情況 下,⽤戶不斷的請求仍會導緻不斷建立新連接配接,急劇消耗資源。限定最⼤連接配接數最⼤連接配接數的情況下,造成連接配接池拒絕連接配接,或進⾏排隊等待,雖然會避免系統當機風險,但也造成業務⽆法使⽤。對于對外提供實時服務的系統來講,池化的隊列上限, 也可以看作是資源對外提供服務的上限。

設定逾時

在設定逾時時間後。由于資源釋放速度較快,可以假設為⼀旦主動關閉連接配接,資源⽴即釋放。那麼,系統内所保留的資源可以簡化為設定逾時時間(TV,Timeout Value)時間段内連接配接所保持的資源:

RR = RT - QPS * RCPR * TV

對參數進⾏歸⼀簡化:

rr = 1 - k * qps * tv

示意圖如下:

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

從圖中可以看到,在資源總量、QPS 固定、且發⽣逾時的情況下,逾時時間和資源消耗的速度和成近似線性正⽐。是以從盡快釋放消耗資源的⻆度來看,逾時時間的設定 應當和 QPS 成反⽐,QPS 越⾼,逾時時間應當越短。

逾時時間設定治理

從資源靜态和動态分析看,我們應當規範設定調⽤逾時時間。設定逾時時間的意義, 是在極端情況下,采⽤主動的快速失敗政策,使得資源消耗與釋放資源之間達到平衡,避免調⽤雙⽅因資源耗盡⽽當機。逾時時間設定不當引發,容易引發⽣産故障, 線上已經有諸多血的教訓。

設定過長

逾時時間過⻓容易引起降級失效、系統崩潰、連接配接池爆滿等問題。如下圖,内容服務是⾯向⽤戶直接提供知識内容的核⼼服務。收藏服務傳回⽤戶對内容的是否收藏,屬于低優先級服務。如果内容服務請求收藏服務設定逾時時間過⻓,如圖中,雖然設定 1S 逾時,但是重試累計 3S,則⼀旦收藏服務發⽣當機(通常是由于上遊 QPS 異常導緻),則内容服務會失效,⽆法傳回給⽤戶資料,甚⾄發⽣串聯雪崩。

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

設定過短

逾時時間設定過短,實際⽣産中容易因⽹絡抖動⽽告警頻繁,造成服務不穩定等⽤戶體驗問題。如内容服務調⽤資源服務逾時時間設定 200ms,資源服務調⽤ID 發号器服務逾時時間設定為 300ms,⼀旦⽹絡抖動後,資源服務 200ms 即逾時傳回,資源服務對下遊的調⽤ 300ms 逾時也⽆實際意義。

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

合理設定

合理設定逾時時間,對系統的穩定來⾔,非常重要,我們可以從以下⻆度來考慮設定值:

  • ⽤戶⻆度。微服務最終為服務對象是⽤戶,從⽤戶互動資料來講,服務響應時間在 300ms 内最佳, 2000ms 内仍可接受。通常情況下,建議逾時的上限值為 2000ms,超過 2000ms 的非重要請求,則有必要被降級處理。
  • 技術⻆度。同時考慮到 TCP 算法中 Delayed ACK + Nagle 算法開啟的場景,最小 delay 值 40 ms,建議下限值設定為 50ms; 在 RTT 較⼩的正常網絡環境中,TCP 資料包丢包,逾時重傳的最⼩值,200 ms,是以我們建議 300ms 可以視為逾時設定的最佳選擇,為重傳保留⼀定的餘量。
  • 資源消耗⻆度。依據資源消耗的分析,逾時時間⻓短應當和 QPS 成反⽐例。我們設定基礎值逾時設定為 300ms、100QPS,并根據實際 QPS 做調整。

綜合⽽⾔,我們簡單的給出以下參考值,也可以根據自己的情況設定基準值後進⾏調整:

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

⾃動化設定

前⽂給出了合理設定逾時時間的參考值,接下來,我們要考慮如何将逾時時間的設定與業務解耦。逾時時間的設定,和熔斷、限流⼀樣,是異常狀況下系統的⼀種⾃我保護機制,熔斷、限流都已經從業務解耦⾄架構層,如利⽤API ⽹關可以統⼀處理微服務之間調⽤的熔斷、限流。逾時時間的設定,也可以借助運維體系内其他架構,實作解耦并⾃動設定,如下圖。

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

這⾥我們建構了逾時治理系統,它⾃身包含三個子產品:推薦設定子產品,分析治理子產品、UI 界⾯。并對外部依賴監控系統(Prometheus 等)、告警系統、配置中⼼(Consul、etcd)、及統⼀的⽹絡調⽤架構(Http)。該系統還可以嵌⼊監控系統内 作為其内部功能來實作,或在響應時間監控的基礎性進⾏改造。

下⽂對每個子產品及依賴進⾏簡述:

推薦設定子產品

該子產品,以響應監控系統的資料為輸⼊,産出每⽇/周等固定周期内 P99.9(根據實際 情況來要求)的響應時間,除去異常偏離點,并添加⼀定的 Buffer,⾃動産出 API 調⽤逾時時間的設定參考值。

⽇常中,線上正常的響應時間 P99.9 代表該系統穩定狀态下的值,超出該值意味着系統出現異常。但必須明确指出,該推薦值可能并⾮理想狀态下的逾時設定值。

分析治理子產品

由于服務響應時間可以粗略認為是對資源的消耗量成正⽐,分析治理子產品依賴監控系 統産出的服務響應時間、流量峰值、以及對應的系統資源⽔位,對響應時間及逾時時 間設定進⾏分析,輸出最終的設定值後,通過配置中⼼下發⾄調⽤架構。

  • 從簡處理的話,可以基于上⽂推薦的 QPS 和 逾時時間設定值,來進⾏預警提示偏離點。
  • 更加精細化的處理,可以按接⼝的響應時間 * QPS 來均攤服務資源,對于明顯超出均攤值的點,進⾏異常提示。
  • 回報上下遊調⽤鍊路中,下遊逾時時間設定⾼于上遊逾時時間的異常點。
  • 收集線上真實告警資料,并依據政策對持續發⽣的逾時問題進⾏彙總反 饋。如産⽣逾時異常周報等。

UI 界面

通過管理 UI 界⾯,以微服務為機關,對其調⽤情況,展示分析治理子產品異常點,以及告警問題彙總。賦予使⽤者進⾏⼈⼯調整逾時時間⼊⼝,并以⼈⼯設定為⾼優先級。

配置中心

逾時時間設定的下發通常有配置中⼼來實作,配置中⼼有⾃身的⾼可⽤和⼀緻性保障,同時有 Watch 機制來確定及時下發配置⾄調⽤架構使⽤。

調用架構

⽹絡調⽤架構,接受從配置中⼼下發的配置并實作指定的⾏為,與逾時設定⾏為相關的配置有三類,降級、阻塞、設定逾時時間。

  • 降級,即降級開關,開關下發後,對依賴服務直接進⾏降級,不再進⾏調⽤,該狀态在緊急狀态或重⼤活動時候使⽤。
  • 阻塞開關,服務調⽤内部架構會按照設定逾時時間進⾏阻塞,該能⼒⽤于尋找在目前逾時時間設定下,系統性能瓶頸。通過壓測,為重要服務線上逾時時間設定提供最真實的資料。
  • 逾時配置,由逾時治理系統所最終輸出的逾時配置,會由配置中⼼⾃動下發⾄各個服務,并在調⽤過程中使⽤。

另外,調⽤架構還應當實作,逾時時間⾃動遞減機制,如上遊每次發起請求,到下遊開始發起請求前,如果剩餘可⽤時間已經為 0 ,則應當主動失敗,參考下圖。

服務逾時時間如何設定、如何對逾時時間治理、逾時設計原則一文揭秘!

告警和優化

逾時時間設定是系統的第⼀重保護,逾時時間設定後,需要配合逾時告警和響應時間優化,才能形成構成的完整的系統⾃我修複的閉環。

告警

逾時告警,會直接回報逾時設定的效果,⽽且也是⻓耗時請求被逾時設定攔截後,系 統⾃我保護的下⼀個重要環節。系統調⽤發⽣逾時告警,可以通過運維體系監控告警 讓⼈⼒及時介⼊排查問題,以避免更⼤損失。

逾時告警通常隻是告警監控系統⾥⼀個⼦監控項,從實際⽣産中來看,逾時告警 往往也是最頻繁發⽣的告警,逾時告警如何在保障靈敏度的同時,避免過渡告警,需 要專⻔考慮。對此,我們建議從範圍和時間兩個次元來區分逾時告警:

從範圍來看,可以将局部性逾時和⼤⾯積逾時告警區分對待:

  • 大面積告警,緊急⼈⼒介⼊,通常是運維⽹絡故障等原因,可以結合⽹絡 監控來具體定位。
  • 局部小範圍告警,作為⾮緊急重要事情處理。

從時間來看,将波動性和持續性逾時告警區分對待:

  • 持續性問題,⼤機率是業務問題,緊急人力介入進而避免業務發⽣重⼤損失。
  • 波動性問題,根據出現頻率,排查隐藏線上問題并解決,作為⾮緊急重要事情處理。

對于如何定義短暫性的波動,可以由運維評估出⽇常⽹絡抖動平均抖動時⻓ ,超過⽹ 絡波動的時⻓⼀定門檻值後,則觸發緊急告警。如果運維體系資源充⾜,建議将逾時告 警波動性監控細化到具體接⼝。

優化

響應時間優化是逾時治理的治本措施。理想情況下,服務的響應時間當然是越快越 好,但也要和目前業務發展相比對,要保障系統穩定,也要避免為優化響應時間耗費過多成本。

原則上,應當依據逾時設定時間來優化響應時間,⽽⾮以響應時間來決定逾時時 間。服務逾時,可能是應⽤層代碼錯誤、⽹絡丢包,伺服器⾃身硬體異常、或⼤量數 據庫操作慢查詢等問題導緻。可以采⽤的措施有:

  • 排查異常問題,如排查業務逾時重試次數、排查錯誤⽇志、排查庫表操作是否有慢查詢等。
  • 調整軟體設計架構,提⾼業務響應速度,如使⽤緩存、拆分調整架構減少調⽤層級等。
  • 調整運維⽅式,如發版引發的告警,則可以從調⽤架構的重試中進⾏解決,也可以依賴滾動釋出進⾏解決。
  • 縱向或橫向擴充資源,提⾼單機性能,如 CPU、記憶體,以期望在性能拐點達到前獲得消耗與釋放平衡。橫向在降低單機 QPS 的同時,适當增加逾時時間。

總結

單體服務内部隻有對庫、Redis 等⽹絡調⽤,相⽐之下,微服務系統内部發⽣的⽹絡調 ⽤頻度呈⼏何倍數增加。是以⽹絡逾時參數的設定治理,在微服務體系治理體系内也 ⾮常重要。

繼續閱讀