
Dubbo 開發者日活動成都站
本文整理自謝延澤先生在 Dubbo 開發者日成都站活動中的演講,主要分享關于微服務轉型的内容,也總結一下這些年作者在微服務領域的一些經驗。
2012 年 James Lewis 在波蘭第 33 次 Degree in Kraków 會議上分享了一個案例,名稱是 “Micro Services - Java, the Unix Way”。在這個分享裡,James Lewis 分享了在 2011 年中參與的一個項目中所采用的一系列實踐,以 UNIX 的哲學重新看待企業級 Java 應用程式,并且把其中的一部分稱之為“ Micro-Services ”。總結了五大特征:
Small with a single responsibility —— “小到隻有單一原則”
- Containerless and installed as wellbehaved Unix services —— “去容器化并且作為 Unix Service 安裝”
- Located in different VCS roots ——“分布在不同的版本控制代碼庫裡”
- Provisioned automatically ——“自動初始化”
- Status aware and auto-scaling ——“關注狀态和自動擴充”
2014 Martin Fowler 試圖将 James Lewis 的微服務定義進行一般化推廣,使其不光可以在不同的語言架構和技術棧上使用。又可以兼顧靈活、DevOps 等其它技術,成為一個架構的“最佳實踐”集合。提出 9 大特征:通過服務元件化、圍繞業務能力組織、是産品不是項目、智能端點和啞管道、去中心化治理、去中心化資料管理、基礎設施自動化、為失效設計、演進式設計
2016年 Sam Newman 《Building Microservice》4個特征 7大原則。
4 大特征:可以獨立部署。通過網絡通信。對消費方的透明。盡可能降低耦合,使其自治。
7 大原則:圍繞業務概念模組化、接受自動化文化、隐藏内部實作細節、讓一切都去中心化、可獨立部署、隔離失敗、高度可觀察。
這裡澄清一個觀點,在工作過程中偶爾會聽到某些同學說,我使用了 Dubbo ,使用了 spring-boot ,或者使用了 Spring-Cloud ,我開發出來的系統就是微服務。個人觀點,微服務是一個架構風格或者架構原則,與實作系統的架構無關。比如:一個系統滿足了上面的特征和原則,使用 WebService 通訊,難道就不是微服務嗎?當然實際實施過程中應該選擇一個輕量級的通訊架構。
微服務從 2014 年在國内開始傳播,到現在已經有 5 年時間裡,關于微服務的優點論述的文章有很多,比如邏輯清晰、簡化部署、可擴充、靈活組合、技術易購、故障隔離等等這就不做詳細展開。
全面微服務化帶來的挑戰
1. 可用率降低
全面微服務化之後,原先的單個應用可能會拆分為多個獨立程序。為避免程序之間争用資源,一般公司都會獨立部署,即單個虛拟機内隻部署一個 jvm 程序。由此帶來了更多伺服器、網絡裝置、安全裝置,這些硬體裝置的可靠性都會影響到業務連續性。
服務跨程序間通訊,必然要選擇一種通訊協定、序列化架構,額外引入的代碼可靠性也會對整體的可用性造成影響。
是以,微服務的設計是需要面向故障進行設計,在設計要考慮重試、幂等、故障隔離、熔斷、降級等等。
2. 事務複雜度
微服務拆分後,雖然按照領域模型做了解耦,但不可避免會帶來分布式事務問題。目前分布式事務在社群也有一些解決方案和開源架構,方案有基于消息隊列最終一緻、TCC 分布式事務架構以及自動化的分布式事務架構,例如 Seata 等,但分布式事務的處理,對開發人員設計要求比較高,使用成本較高。
在拆分的時候,建議還是盡可能避免分布式事務,引入分布式事務架構要評估成本和收益。
3. 運維複雜度
當一個單體應用拆分為多個微服務之後,應用數量會大幅增加。如果沒有一個可靠穩定的運維平台或資源編排平台(如 k8s ),全面微服務化,對運維就是一個災難,工作量的大幅增加,直接會影響系統穩定性進而影響到業務連續性。
4. 調試優化複雜度
應用拆分後,業務調用關系變複雜,調用鍊整體變長。如果沒有一套合适的調用鍊追蹤平台,很難定位到整個系統的性能瓶頸,調優成本很高。另一個問題是,生産環境業務資料異常時,由于調用鍊過長,如果沒有規範的 Request、Response 日志,很容易造成各服務之間互相甩鍋,難以定位問題。全面微服務化之後,由于衆多的服務節點,調優排查錯誤更加依賴于日志平台,高性能的日志平台也會提高效率。
5. 測試難度
在單體應用的時候,調用鍊路短,一般都是做黑盒測試,測試人員無需了解複雜的業務實作。而進行微服務改造後,單個業務可能會由多個服務組合編排完成,如果繼續做黑盒測試,意味着必須等待所有服務開發完成之後才能進行,導緻測試周期邊長、定位困難,做邊界測試需要更多的測試用例才能覆寫,測試整體成本會變高。這種情況下,單元測試、單系統測試的重要性就凸顯出來了。如果需要做單系統測試,可能需要 mock 被調用的服務,通訊協定使用 http 還好,社群有很多開源的架構可以使用。如果是 RPC 架構,意味着需要準備一套好用的 mock 測試系統才能支撐單系統測試。
6. 聚合查詢
在領域模組化的時候,一般是按照使用者角度去劃分,而營運需求與使用者需求天生不是一個次元的。舉個例子:按使用者次元領域模組化,會劃分使用者服務、訂單服務,使用者和訂單資料存儲在不同的資料庫,假設營運有一個需求是查詢某個年齡段使用者的訂單,在使用者達到千萬級的時候,這種需求對微服務體系是個災難。需要一個強大的大資料平台對資料按業務次元進行聚合,才能滿足營運的查詢需求和報表功能。
微服務拆分原則
微服務拆分原則中,特别需要提到的是康威定律。
康維定律簡單來說就是系統設計(産品結構)等同組織形式,每個設計系統的組織,其産生的設計等同于組織之間的溝通結構。如果單個服務由不同組織管理,需求無法達成統一,面臨着令出多頭、需求幹擾的風險。
伸縮需求,同一個程序之内的不同業務功能,有時在業務量方面會出現較大的差異,具體要求的程序數量會有較大差别,這樣的子產品鎖定在同一程序之内,勢必會造成資源的浪費。
部署頻率,同一個傳遞物内不同的元件有着不同的上線頻率,會大大的提高上線流程的發生頻率,會造成較大的人員浪費。
修改的相關性,如果同一傳遞物内的不同元件,經常會被同步修改,這可能說明,如果發生拆分,這兩個子產品應該是”在一起“的。
領域模組化,針對業務領域,引入限界上下文(Bounded Context)和上下文映射 (Context Map)對業務領域進行合理的分解,識别出核心領域(Core Domain) 與子領域(SubDomain),并确定領域的邊界以及它們之間的關系。依據核心領域和子領域劃分微服務邊界。
對于一個單體應用,拆分過程應該是循序漸進、逐漸拆分、由簡到繁、由粗到細,是一個漸進的過程。例如先将有明顯邊界的業務拆分為獨立服務,無法明細邊界的先混在一起,等業務需求逐漸清晰後再拆。拆分時先拆分為幾個相對較粗粒度的服務,根據業務需求情況,逐漸将粗粒度的服務中相對穩定,可以沉澱的業務拆分為獨立服務。在這個過程中,原有的單體應用也可以承擔部分相容能力,在改造完成前,不對外部系統造成過大的影響。
微服務的拆分是跟業務需求強相關的,如果業務需求變更不多、相對穩定,處理的請求并發量不高,單體應用的穩定性和可維護性更好,更加适用。
總結
微服務不是銀彈,是用來處理海量使用者、業務複雜和需求頻繁變更場景下的一種架構風格。引用一句話“好的架構是演化出來的,而不是設計出來的”。任何一種架構的引入,都會帶來利弊兩個方面的影響,如何平衡才最重要。
四川新網銀行是全國三家網際網路銀行之一,于 2016 年 12 月 28 日正式開業。新網銀行注冊資本 30 億元,由新希望集團、小米、紅旗連鎖等股東發起設立,是銀監會準許成立的全國第七家民營銀行,也是四川省首家民營銀行,同時也是全國第二家獲得國家高新技術企業認定的銀行。新網銀行堅持“移動互聯、普惠補位”的差異化定位,以及“數字普惠、開放連接配接”的特色化經營,着力打造成為一家數字科技普惠銀行,依托領先的金融科技能力、穩健的大資料風控技術和高效的網際網路開放平台營運模式,服務小微群體、支援實體經濟、踐行普惠金融。截止目前服務使用者數 2900 多萬,累計放款 9000 多萬筆。
作者資訊:謝延澤,目前就職于新網銀行,負責技術中台建設,核心系統技術架構設計。關注雲原生領域,探索在金融行業實踐思路。