服務治理

轉於自己在公司的Blog: 
http://pt.alibaba-inc.com/wp/experience_1402/service-governance-process.html 

 

在大規模服務化之前,應用可能只是通過RMI或Hessian等工具,簡單的暴露和引用遠程服務,通過配置服務的URL地址進行調用,通過F5等硬件進行負載均衡。 

(1) 當服務越來越多時,服務URL配置管理變得非常困難,F5硬件負載均衡器的單點壓力也越來越大。 

此時需要一個服務註冊中心,動態的註冊和發現服務,使服務的位置透明。 

並通過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover,降低對F5硬件負載均衡器的依賴,也能減少部分成本。 

(2) 當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啓動,架構師都不能完整的描述應用的架構關係。 

這時,需要自動畫出應用間的依賴關係圖,以幫助架構師理清理關係。 

(3) 接着,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什麼時候該加機器? 

爲了解決這些問題,第一步,要將服務現在每天的調用量,響應時間,都統計出來,作爲容量規劃的參考指標。 

其次,要可以動態調整權重,在線上,將某臺機器的權重一直加大,並在加大的過程中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。 

(4) 規模繼續擴大,應用之間不再是扁平的對應關係,開始分層,比如核心數據層,業務集成層等,就算沒有出現循環依賴,也不允許從低層向高層依賴,以免後續被逼循環依賴。 

這時,需要在註冊中心定義架構體系,列明有哪些層的定義,每個服務暴露或引用時,都必須聲明自己應用屬於哪一層,這樣註冊中心能更快的發現架構的腐化現象。 

(5) 服務多了,溝通成本也開始上升,調某個服務失敗該找誰?服務的參數都有什麼約定? 

這時就需要登記每個服務都是誰負責的,並建立一個服務的文檔庫,方便檢索。 

(6) 慢慢一些敏感數據也都服務化了,安全問題開始變得重要,誰能調該服務?如何授權? 

這樣的服務可能需要一個密碼,訪問時需帶着此密碼,但如果用密碼,要改密碼時,就會很不方便,所有的消費方都要改,所以動態生成令牌(Token)可能會更好,提供方將令牌告之註冊中心,由註冊中心決定是否告之消費方,這樣就能在註冊中心頁面上做複雜的授權模型。 

(7) 就算是不敏感的服務,也不是能任意調用,比如某服務突然多了一個消費者,這個消費者的請求量直接把服務給拖跨了,其它消費者跟着一起故障。 

首先服務提供方需要流控,當流程超標時,能拒絕部分請求,進行自我保護。 

其次,消費者上線前和提供者約定《服務質量等級協定(SLA)》,SLA包括消費者承諾每天調用量,請求數據量,提供方承諾響應時間,出錯率等,將SLA記錄在監控中心,定時與監控數據對比,超標則報警。 

(8) 雖然有SLA約定,如果不能控制,就只是君子協定,如何確保服務質量? 

比如:一個應用很重要,一個不那麼重要,它們調用同一個服務,這個服務就應該向重要應用傾斜,而不是一視同仁,當支撐不住時,應限制不重要應用的訪問,保障重要應用的可用,如何做到這一點呢。這時,就需要服務路由,控制不同應用訪問不同機器,比如: 
應用分離: 
consumer.application = foo => provider.host = 1,2,3 
consumer.application != foo => provider.host = 5,6 
讀寫分離: 
method.name = find*,get* => provider.host = 1,2,3 
method.name != find*,get* => provider.host = 5,6 

(9) 服務上線後,需要驗證服務是否可用,但因防火牆的限制,線下是不能訪問線上服務的,不得不先寫好一個測試Main,然後放到線上去執行,非常麻煩,並且容易忘記驗證。 

所以線上需要有一個自動運行的驗證程序,用戶只需在界面上填上要驗證的服務方法,以及參數值和期望的返回值,當有一個服務提供者上線時,將自動運行該用例,並將運行結果發郵件通知負責人。 

(10) 服務應用和Web應用是有區別的,它是一個後臺Daemon程序,不需要Tomcat之類的Web容器。但因公司之前以Web應用爲主,規範都是按Web應用的,所以不得不把服務跑在一個根本用不上的Web容器裏,而搭一個這樣的Web工程也非常費事。 

所以需要實現一個非Web的容器,只需簡單的Main加載Spring配置即可,並提供Maven模板工程,只需mvn dubbo:generate 即可創建一個五臟俱全的服務應用。 

(11) 開發服務的人越來越多,更注重開發效率,IDE的集成支持必不可少。 

通過插件,可以在Eclipse中直接運行服務,提供方可以直接填入測試數據測試服務,消費方可以直接Mock服務不依賴提供方開發。 

(12) 因爲暴露服務很簡單,服務的上線越來越隨意,有時候負責服務化的架構師都不知道有人上線了某個服務,使得線上服務魚龍混雜,甚至出現重複的服務,而服務下線比上線還困難。 

需要一個新服務上線審批流程,必須經過服務化的架構師審批過了,纔可以上線。 

而服務下線時,應先標識爲過時,然後通知調用方儘快修改調用,直到沒有人調此服務,才能下線。 

(13) 因服務接口設計的經驗一直在慢慢的積累過程中,很多接口並不能一促而蹴,在修改的過程中,如何保證兼容性,怎麼判斷是否兼容?另外,更深層次的,業務行爲兼容嗎? 

可以根據使用的協議類型,分析接口及領域模型的變更是否兼容,比如:對比加減字段,方法簽名等。 

而業務上,可能需要基於自動迴歸測試用例,形成Technology Compatibility Kit (TCK),確保兼容升級。 

(14) 隨着服務的不停升級,總有些意想不到的事發生,比如cache寫錯了導致內存溢出,故障不可避免,每次核心服務一掛,影響一大片,人心慌慌,如何控制故障的影響面?服務是否可以功能降級?或者資源劣化? 

應用間聲明依賴強度,哪些功能強依賴,哪些弱依賴,然後基於依賴強度,計算出影響面,並定期測試複查,加強關鍵路徑上的服務的優化和容錯,清理不該在關鍵路徑上的服務。 

提供容錯Mock數據,Mock數據也應可以在註冊中心在運行時動態下發,當某服務不可用時,用Mock數據代替,可以減少故障的發生,比如某驗權服務,當驗權服務全部掛掉後,直接返回false表示沒有權限,並打印Error日誌報警。 

另外,前端的頁面也應採用Portal進行降級,當該Portal獲取不到數據時,直接隱藏,或替換爲其它模塊展示,並提供功能開關,可人工干預是否展示,或限制多少流量可以展示。 

(15) 當已有很多小服務,可能就需要組合多個小服務的大服務,爲此,不得不增加一箇中間層,暴露一個新服務,裏面分別調其它小服務,這樣的新服務業務邏輯少,卻帶來很多開發工作量。 

此時,需要一個服務編排引擎,內置簡單的流程引擎,只需用XML或DSL聲明如何聚合服務,註冊中心可以直接下發給消費者執行聚合邏輯,或者部署通用的編排服務器,所有請求有編排服務器轉發。 

(16) 並不是所有服務的訪問量都大,很多的服務都只有一丁點訪問量,卻需要部署兩臺提供服務的機器,進行HA互備,如何減少浪費的機器。 

此時可能需要讓服務容器支持在一臺機器上部署多個應用,可以用多JVM隔離,也可以用ClassLoader隔離。 

(17) 多個應用如果不是一個團隊開發的,部署在一臺機器上,很有可以誤操作,停掉了別人的服務。 

所以需要實現自動部署,所有的部署都無需人工干擾,最好是一鍵式部署。 

(18) 機器總是的閒時和忙時,或者冗餘機器防災,如何提高機器的利用率? 

即然已經可以自動部署了,那根據監控數據,就可以實現資源調度,根據應用的壓力情況,自動添加機器並部署。

如果你的應用是國際化的,有中文站,美國站之類,因爲時差,美國站的機器晚上閒的時候,可能正是中文站的白天忙時,可以通過資源調度,分時段自動調配和部署雙方應用。 

按關鍵詞歸納爲: 

1. 服務註冊與發現 

2. 軟負載均衡與容錯 

3. 服務監控與統計 

4. 服務容量評估 

5. 服務上線審批 

6. 服務下線通知 

7. 服務負責人 

8. 服務文檔 

9. 服務路由 

10. 服務編排 

11. 服務黑白名單 

12. 服務權限控制 

13. 服務依賴關係 

14. 服務分層架構 

15. 服務調用鏈跟蹤 

16. 故障傳導分析 

17. 服務降級 

18. 服務等級協定 

19. 服務自動測試 

20. 服務僞裝容錯 

21. 服務兼容性檢測 

22. 服務使用情況報告 

23. 服務權重動態調整 

24. 服務負載均衡調整 

25. 服務映射 

26. 服務模板工程 

27. 服務開發IDE 

28. 服務健康檢測 

29. 服務容器 

30. 服務自動部署 

31. 服務資源調度 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章