佟業(yè)新,曲新奎
(中航信移動科技有限公司,北京 100029)
隨著業(yè)務的發(fā)展,企業(yè)規(guī)模擴大,單體的架構已經無法滿足企業(yè)對系統(tǒng)的需求,需要根據組織的實際情況進行相應的架構調整[1].采用微服務架構的系統(tǒng)是由一系列協(xié)同工作且獨立的服務組成[2],與傳統(tǒng)的的單體架構相比,微服務架構具有很多的優(yōu)點,如靈活性更高,具有更高的彈性和擴展性,各個模塊獨立開發(fā)部署,互不影響等.
同時也帶來了一些問題,采用微服務架構的應用屬于分布式系統(tǒng),復雜性較高.在實際應用過程中,會碰到如下的一些問題,包括服務調用鏈條較長,存在重復資源調用問題;對異常時協(xié)議的容錯處理不足,被依賴的服務出現異常時,協(xié)議的失敗率波動很大魯棒性差;對一些服務依賴程度較高,缺少降級策略;服務調用的參數定義的不合理,少量的服務調用導致整體服務不可用.
鑒于上述問題,與單體架構相比,在實際的應用中,需要有更多的技術手段如分布式追蹤、熔斷隔離、實時監(jiān)控等來保證微服務架構可靠性[3].為了保證系統(tǒng)的可靠性,文中制定了質量評價指標,圍繞這些指標,文中通過多線程并發(fā)調用以及分布式緩存的方法實現縮短響應服務時間的目的.為了提升服務的可靠性,從服務調用失敗處理,熔斷隔離保護以及無損上線三個方面進行了研究,并提出了熔斷隔離參數的計算模型,以對服務調用過程中的熔斷隔離參數進精細化計算,以便更加合理的調配多個服務對線程池等資源的使用.這些研究在實際的項目中進行應用,在服務質量提升方面起到了很好的效果.
本文中服務質量的保障,重點圍繞縮短服務響應時間和提升服務可靠性展開,同時需要提供實時的服務質量監(jiān)控及評估和改進,以達到服務質量的持續(xù)提升,并在服務質量評價指標方面達到一定的標準.
在實際的生產運行中,服務運行的速度、成敗等因素直接影響到用戶的體驗,因此將響應時間以及失敗率作為本文重點關注服務質量評價指標進行定義.同時系統(tǒng)的處理量會對響應時間以及失敗率的指標產生影響.
在文中提出熔斷隔離參數的計算模型,以實際生產中的文中提到的關鍵質量指標為基礎進行設計,由于生產數據每時每刻都在變化,為了應對這種情況,需要進行實時數據的收集,并基于模型進行實時計算,并將計算結果在線推送給業(yè)務方,進行在線生效變更.
質量評價指標用于對系統(tǒng)的實際運行情況進行量化,以實現對服務質量的監(jiān)控以及評估[4].本文針對服務質量的保障,重點關注如下幾個指標:
1) 平均響應時間(avg):在一段時間內所有請求響應時間的平均值,平均響應時間越小,說明處理速度越快,服務效率越高.
2) 95 線響應時間(95Line):在一段時間內95%請求響應時間的最大值.
3) 99 線響應時間(99Line):在一段時間內99%請求響應時間的最大值.
4) 失敗率:在一段時間內失敗次數與總請求量的比值,失敗率越高說明服務可靠性越低.
5)QPS:在一段時間內的服務器每秒所處理的查詢量.
1.2.1 多線程并發(fā)調用
策略一.多線程調用,靜態(tài)托底
(1) 應用場景:需要對多個不同數據源的服務進行調用,并對資源進行聚合,需要在有限時間內完成.
(2) 策略描述:多個服務通過多線程同時發(fā)起請求,對返回的結果進行聚合.設定響應時間的閾值,對于超過閾值的服務,對服務進行丟棄,并對該服務中需要的數據進行容錯處理.
(3) 優(yōu)點:解決了多服務并行調用帶來的性能問題,在服務質量得到保證的同時在規(guī)定時間內返回內容.
(4) 應用案例:航旅縱橫APP 中的首頁,需要以服務推薦的形式為不同的業(yè)務提供運營位置,進行功能展示.各個服務需要按照要求提供服務,由服務推薦模塊進行服務聚合,此處采用了該策略,在規(guī)定時間內不滿足性能要求的服務,將無法獲得推薦,并保證了性能正常的服務可以正常展示.調用過程如圖1所示.
圖1 多線程調用過程
策略二.多路保證,優(yōu)先選用
(1)應用場景:可用性和響應時間有極高要求的服務,同時存在多個提供相似數據源的服務.
(2)策略描述:對于一次服務請求,多個獨立服務提供支持,在請求處理過程中,多路并發(fā)調用,優(yōu)先選用先返回的結果;
(3)優(yōu)點:多路保證系統(tǒng)的穩(wěn)定性;以最先返回的結果優(yōu)先,一定程度上,提高了響應時間;
(4)缺點:多路調用,資源的消耗會根據同時調用的服務數量而倍數增長;
(5)案例:在航旅縱橫APP 中為旅客提供高可用的安檢服務,響應時間需要在100 ms 以下,并達到容錯高可用能力,考慮服務壓力以及系統(tǒng)資源的情況下,往往使用速度較快的服務代替資源緊張的服務.
1.2.2 分布式緩存
內存的訪問性能明顯優(yōu)于磁盤.把數據放入內存中,可以提供更快的讀取效率.但在互聯網業(yè)務的場景下,將所有數據數據都裝入內存,顯然是不明智的[5].
同時大部分的業(yè)務場景下,80%的訪問量都集中在20%的熱數據上(適用二八原則).因此,通過引入緩存組件,將高頻訪問的數據,放入緩存中,可以大大提高系統(tǒng)整體的承載能力,提高響應速度,提高用戶體驗.原有單層DB 的數據存儲結構,也變?yōu)镃ache+DB 的結構,如圖2所示.
圖2 Cache+DB 結構圖
在數據層引入緩存,有以下幾個好處:
(1)提升數據讀取速度;
(2)提升系統(tǒng)擴展能力,通過擴展緩存,提升系統(tǒng)承載能力;
(3)降低存儲成本,Cache+DB 的方式可以承擔原有需要多臺DB 才能承擔的請求量,節(jié)省機器成本.
根據業(yè)務場景,通常緩存有以下幾種使用方式:
(1)懶漢式(讀時觸發(fā)):寫入DB 后,然后把相關的數據也寫入Cache;
(2)饑餓式(寫時觸發(fā)):先查詢DB 里的數據,然后把相關的數據寫入Cache;
(3)定期刷新:適合周期性的跑數據的任務,或者列表型的數據,而且不要求絕對實時性;
(4)實時刷新:通過監(jiān)聽數據表的實時變更,旁路推送到應用,并進行緩存的實時更新.
提升服務質量的另外一個重要任務是提升服務的可靠性.重點對服務調用失敗以及流量異常的處理方式進行了研究.
1.3.1 服務調用失敗處理
針對調用失敗有Failfast 和Failover 兩種處理方式.
(1) Failfast:快速失敗只發(fā)起一次調用,失敗立即報錯,現在服務調用方的默認調用方式;
(2) Failover:失敗自動切換,當出現失敗,重試其它服務器.此種情況也支持,慎用,在某個服務提供方出現故障后,會放大壓力.
在實際應用中,Failfast 和Failover 兩種方式都進行了實現,失敗的處理方式通過分布式配置中心進行配置,默認使用Failfast.如果各個業(yè)務有個性化需求,可配置為Failover 模式,并設置重試次數的配置key FailoverRetryCount,即可實時切換為該模式.
1.3.2 熔斷隔離保護
1.3.2.1 熔斷隔離介紹
服務熔斷,類似于電路中的“保險絲”,是指由于某些原因(如用戶大量請求、程序Bug、硬件故障等)造成目標服務調用慢或者有大量超時,此時停用對該服務的調用,等到服務情況好轉時再恢復調用[6].
線程池隔離就是艙壁隔離模式,貨船通常利用艙壁將不同的船艙隔離起來,防止一個船艙進水對其他船艙的影響,這種資源隔離減少風險的方式就是艙壁隔離模式的一種應用場景.該模式使用一個線程池來存儲當前的請求,線程池對請求作處理,設置任務返回處理超時時間,堆積的請求堆積入線程池隊列,需要為每個依賴的服務申請線程池,有一定的資源消耗,好處是可以應對突發(fā)流量.
1.3.2.2 熔斷隔離參數計算
在實際應用中,可以引入Hystrix 組件,該組件采用線程池隔離機制,實現對系統(tǒng)對穩(wěn)定性保護.通過隔離服務之間的依賴關系,限制對其中任何一個的并發(fā)訪問.
客戶端請求會在單獨的線程中執(zhí)行,執(zhí)行依賴代碼的線程與請求線程分離,這樣在某個依賴調用執(zhí)行時間很長時,請求線程可以自由控制離開的時間.Hystrix 通過為每個依賴服務分配獨立的線程池進行資源隔離,當某個服務不可用時,即使為該服務獨立分配的線程都處于等待狀態(tài),也不會影響其他服務的調用.
服務啟用線程池和熔斷功能,需要配置線程池大小和超時時間.參數的準確程度會直接影響到熔斷隔離的實際效果.為了提升準確性,結合現有的應用監(jiān)控數據,設計了服務調用參數的計算公式.如公式(1) 所示,該公式用于計算被調用服務需要配置的線程數:
其中,s(thread)代表應用所依賴服務的線程數,m代表計算的冗余度,95Line表示某一天的95 線響應時間,max(QPS)表示某一天的QPS峰值.通過該公式計算的數值,具有一定的冗余度,可以保證在QPS達到峰值,服務響應時間達到95Line時,線程數可以足夠使用.
如式(2) 所示,用于計算服務的調用超時時間:
其中,s(timeout)代表應用所依賴服務的超時時間,使用99Line作為時間基準,n為時間冗余度,通過調整n的數值,保證99%以上的請求不會因為超時而導致失敗.
兩個式子中計算的數值在極端情況下可能存在一定的沖突,通過95Line作為基數計算的線程數,如果使用99Line作為基數作為超時時間,全部超時的情況下,線程肯定不夠用.但實際中,絕大多數請求都在平均響應時間上下,同時通過應用監(jiān)控系統(tǒng)及時發(fā)現調用的波動情況,可以將響應時間控制在一定范圍內,保證了服務的穩(wěn)定運行.
圖3的參數計算流程展示了基于計算模型從數據收集到最終應用的全過程.
圖3 參數計算流程
(1) 從生產系統(tǒng)中實時收集到業(yè)務運行監(jiān)控數據,主要包括模型計算所需要的95Line,99Line以及QPS.
(2) 參數計算模型使用收集到的數據進行并行計算,得到每個應用所依賴服務所需的線程數s(thread)以及超時時間s(timeout).
(3) 考慮到系統(tǒng)性能問題,設定所有被調用服務的線程數s(thread)之和需要小于系統(tǒng)所在容器如Tomcat所設定的線程數c(thead),如果超出了c(thread)則進行系統(tǒng)報警,提醒當前所需線程數總和超過了最大容量,需要進行干預.
(4) 如果被調用服務的線程數s(thread)之和小于c(thread),則在線更改配置并實時生效.
(5) 生效以后,進入下一個計算周期.
在進行參數計算的過程中,考慮到實時收集數據數值的波動,計算所用數值采用一段時間的數據,在實際應用中為每隔1 分鐘會基于前1 分鐘的數值進行計算,并將計算的結果根據上述流程進行計算和應用,整個過程可以在秒級完成,以保證系統(tǒng)安全,及時應對流量突變.
1.3.3 無損上線
1.3.3.1 優(yōu)雅停機
在應用重啟過程中,需要保證正在處理的請求能正常結束,并且在停機前主動通知調用方不在繼續(xù)向將要停機的服務器發(fā)送新請求,待所有請求處理完畢之后,進行應用的重啟.流程如圖4所示.
圖4 優(yōu)雅停機流程
通過這樣的流程,避免了在應用重啟或者上線過程中的請求失敗,提高服務質量.在航旅微服務體系中,主要通過在Web 容器中添加Socket 服務接收停止指令,在收到停止指令后,主動在Zookeeper 上下線該服務器對應的所有相關服務,利用Zookeeper 的實時通知機制,通知到所有調用方停止向這臺機器發(fā)送新的請求,并保證處理完所有已經接收的請求后,進行Web 容器的重啟.
1.3.3.2 流量預熱
在Web 容器啟動結束之后,端口已經暴露成功,但是部分應用會進行基礎數據的預熱加載,而且JVM 也需要預熱加載相關的類,所以在Web 容器啟動后,并不完全具備承載高并發(fā)請求的能力,這種請求下如果有大量流量涌入,輕則部分請求響應超時,重則拖垮整個應用.針對此類問題,在航旅微服務體系中,增加了啟動預熱模塊,針對某個服務的某臺機器重啟之后,根據服務注冊的時間,前5 分鐘之內(可在分布式配置中心進行動態(tài)調整),服務調方會根據啟動時間和這臺機器的具體權重,計算出一個相對合理的預熱權重,QPS會在5 分鐘內逐步遞增到正常速度.預熱過程中的權重計算如式(3) .
其中,w代表預熱權重,now表示當前請求時間,registerTime表示服務重新注冊時間,timeWindow表示預熱時間窗口,weight表示當前機器權重.
通過本文研究的內容在航旅縱橫中進行了實際應用,通過近一年的時間,對航旅縱橫的200 多個應用,1000 多個服務質量的改造,通過文中的研究成果提升服務的響應時間,對協(xié)議調用鏈條中的響應時間、線程數進行計算和個性化設置,更大程度的保障協(xié)議的成功率和系統(tǒng)穩(wěn)定性.
如表1和表2所示,針對航旅縱橫APP 中的3 個核心業(yè)務航班動態(tài)、值機、行程改造前和改造后的數據進行了對比:
如表1和表2中數據所示,改造前與改造后的數據相比,3 個業(yè)務的服務可靠性大幅提升,失敗率降低了至少一個數量級,絕大多數都降到了0.001%以下.響應時間也有了較大的提高,其中航班動態(tài)以信息查詢?yōu)橹?,由提供數據源的多個服務聚合而成,改造后響平均響應時間和95 線縮短了1/2,值機響應時間縮短接近1/3.
表1 改造前
表2 改造后
本文在圍繞微服務架構中的服務質量保障展開研究,定義了服務質量的評價指標.圍繞評價指標,提出了縮短響應時間以及提升服務可靠性的方法,并在業(yè)務系統(tǒng)中進行了實際應用,取得了不錯的效果.通過本文的研究內容,形成了一套提升服務質量的標準方法,研發(fā)人員只需要遵循該方法,便可以開發(fā)出高質量的服務,可以將更多的精力投入到實際業(yè)務的研發(fā)中,大大提升了企業(yè)的研發(fā)效率.