荔枝微課基礎架構的演進與實踐

本文整理自又拍雲舉辦的微服務架構設計與實踐|Open Talk 線上公開課,荔枝微課基礎架構負責人王誠強作的題爲《荔枝微課基礎架構的演進與實踐 》 的分享。本次活動還邀請了Apache APISIX 和又拍雲等企業的技術專家分享 API、Service Mesh 等相關實戰經驗。html

近幾年,雲原生技術和理念獲得普遍接受,衆多企業開始探索雲原生架構轉型落地。本文將會詳細講述荔枝微課是如何作雲原生下的微服務基礎架構設計。數據庫

王誠強,荔枝微課基礎架構負責人。主要從事基礎技術研究開發、基於雲原生的基礎架構設計以及基礎架構團隊的管理建設。致力於雲原生理念下,以微服務搭建中臺。安全

雲原生:將來架構的演化方向

雲原生(Cloud Native)是將來架構的演化方向,包含了一組應用模式,用於幫助企業快速、持續、可靠、規模化地交付業務軟件,由微服務架構、DevOps 和以容器爲表明的敏捷基礎架構組成,其中包含不少有利於咱們作更多擴展持續演進的理念。我認爲雲原生是一種文化、一種理念, 也是一種生態,既包括技術(微服務、敏捷基礎設施 K8S),也包括管理(DevOps、持續交付), 範圍極其普遍,總得來說是一種圍繞雲計算時代的架構。服務器

雖然說出現得相對比早期的 Spring Cloud 要晚一些,但也是很是先進的,像谷歌最先期貢獻出來的 K8S,以後各大公司也都是在這個開源項目上不斷去迭代更新,所以它的生態很完善。下圖中完整的展現了雲原生的整個生態,包括了不少不一樣的環節,好比數據庫,還有消息流,網關、服務網格等等,這裏就再也不一一列舉了,你們有興趣能夠去深刻了解。微信

雲原生的生態

雲原生的演進歷程

雲原生的歷史變革

2001 年虛擬機進入到了一個可商用的階段, 2013 年 Docker 發佈後會發現不少開源項目、我的開發者都開始用 Docker 去發佈本身的應用;2015 年 CNCF(雲原生計算基金會)成立,2018 年 Kubernetes 從 CNCF 畢業,到了 2019 年咱們會發現它已經是你們時常談論的熱點。雲原生開始大熱,由於它已經造成了一個比較成熟的體系,各大雲廠商也開始把本身的雲服務、容器服務等開始推向市場,這時你們也不用從零開始自建,這也告訴咱們要去把握技術發展的趨勢,懂得借勢,而不是什麼都是從零開始。網絡

荔枝微課架構的演進歷程

荔枝微課架構的演進歷程,這裏將它分爲了五個階段,以下圖所示,咱們詳細展開來講。架構

上古時期:單體架構,業務優先負載均衡

所謂的上古時期能夠理解成公司的創始時期,這時優先以業務爲主,若是連業務都沒起來又談何去作更多的技術發展,這個階段可能使用單體架構更容易作到迭代。不過它的優勢是業務起步快,一我的單槍匹馬就能夠把整個項目給建起來了,可能就那麼一兩個服務,它的部署維護也要簡單不少,目的就是先把業務作起來。框架

單體架構的缺點也很明顯,一個單體項目功能太多,新人就不易上手,項目越作越複雜,耦合度愈來愈高,會給後期新進人員帶來不少難題,咱們私下稱之爲「死傷」,不利於擴展新功能。其中最麻煩的是後面的新人要去接手並開展新功能,若是代碼質量有問題,可能一個局部 BUG 就會影響到總體。並且有不少已經完成的功能,會重複使用到新的業務中,好比支付、帳號等這些一樣的功能,難道又要從新作一遍嗎?less

總體式架構

不過上古時期的總體架構也不必定只有一個服務器、一個服務,也是有一些伸縮性的。上圖中的Users、Threads、Posts 構成了整個單體結構的應用,它是可複製的,好比在負載均衡下面掛多個。另外它是無狀態的,所謂無狀態是指不會由於多一臺服務伸縮出來而致使服務不可用,其中須要特別注意的是一些須要設置白名單的,好比 IP 白名單,多一臺機器,可能 IP 就對不上了,會致使其餘的環節報錯。不過這能夠經過一些軟件設計的方法,好比代理、生產消費這種模式去處理。

初期:初步微服務,解耦化

初期階段單體結構會變得愈來愈複雜,維護起來也會愈來愈難。想象一下,一個系統裏面可能有幾十甚至上百個不一樣的模塊,不一樣的文件夾,一個新人看完這些代碼都須要花不少的時間,又談何瞭解總體並作維護呢?甚至整個要跑起來所要了解的知識也不少。所以後面就須要會作解耦化,也就是咱們所說的初步微服務化。不過初期仍是由業務來推進的,這個時候的目標仍是拓展不一樣的項目,解耦的話也不會一步就到容器化。該階段須要先對服務作鬆耦合,方便新人進來後去維護代碼,另外就是作不少像監控這類兜底的能力。

說到服務作鬆耦合(解耦),由於早期沒有很好的統籌,不少應用是解耦了,但它的技術棧多而雜,甚至連部署方式也都不同,若是是原來維護項目的開發人員走了,由你來接手,它的語言、框架、部署方式都不一樣,維護工做會很難進行。拆分後也會面臨到服務關係問題,服務少的時候還能明確服務之間的調用關係,當服務多了後,調用關係就會比較亂,特別是爲了方便調用,快速上線將配置跟代碼混合一塊兒的狀況,這樣拆分後反而會帶來更多麻煩。所以上古時期以業務爲主,須要衡量一下是否拆分,業務有沒有這個需求,不能由於作拆分而影響業務,另外一個是若是人員不夠也不適合去作拆分,維護起來會更麻煩。

如何拆分總體式架構

總體式架構拆分如上圖所示,這裏寫到是 Container Ports,與之前相比更理想化了一些,須要先進行容器化,拆分以後將 Users 服務、Threads 服務、Posts 服務分別對應不一樣的 API 入口,分別去擴展會更利於去維護。好比負責 Posts 開發的,就只需專一於這一塊。

領域驅動設計與微服務

拆分中有一個詞叫領域驅動設計(Domain-Driven Design,簡稱 DDD),是一種由域模型來驅動系統設計的思想,最先前的仍是經過數據庫等數據源來驅動系統設計 (Model-Driven Design,簡稱 MDD)。領域驅動則會劃分業務和功能,好比說支付、訂單或者是用戶等,拆分後的可複用性就更強了,相互調用就能夠。領域模型是對業務模型的抽象,領域驅動設計相對比較複雜,有興趣的能夠去深刻了解,總的來講規劃設計不是一成不變的,按本身最適合的來就行了。

拆分後也會面臨一些問題,由於服務變多了,部署、管理、資源規劃會特別麻煩,指望每個微服務有本身的專用數據庫,前面說到了要衡量是否拆分,規模很小的話作這個是得不償失的,應該先把量作起來,好比單表過億、超大量了,對數據庫作組成、只讀、讀寫分離、分表都沒有用的時候再去考慮分庫。並且拆分以後使用了專用數據庫,它們之間的調用會是個麻煩,特別是分佈式事務,下面會再詳細講解。

中期:深水期改革,實現集羣化

中期是集羣化的過程,也能夠說是容器化。我我的認爲在當時的時間節點上,順序多是反了,應該是容器化作得越早越好,這樣解耦的時候會減小不少沒必要要的麻煩,固然這個也跟歷史時間的趨勢有關係,可能以前沒有興趣,你們以爲這個技術不成熟,不敢用,所以仍是按老的方式解耦。但若是是如今還未開展這些工做,須要以後再去作的,是能夠把容器化提早一些的。

對咱們而言,中期要作的是要把初步微服務化過程當中存在的一些問題糾正過來,須要統一配置中心,分離代碼和配置;統一開發測試流程,統一持續集成持續部署方式,作容器化、集羣化改造,提供更爲全面的監控告警體系。雖然在初期微服務化時也作了一些監控方面的工做,但既然進到了雲原生,相比在單臺的 vm 機上作監控,形式會不太同樣,可是理念都是相通的,須要升級到更適合集羣化上的監控告警能力。

改革都是向雲原生靠攏的,具體措施在於初步微服務化後,經過引入 K8S 以解決服務管理、資源管理問題,並進入雲原生生態,這樣不少東西都能用起來,避免重複建設;引入 DevOps 解決自動化流程問題,包括自動測試、代碼質量評估、構建、部署等;引入 Istio 解決網關和服務治理問題。

固然上述這些改革能夠根據本身的狀況去適配,不過也會面臨一些問題。咱們不只要着眼於軟件架構,還須要有更多基礎架構的視野,有些問題須要基礎架構的能力去解決,又或是軟件架構能解決但實現起來特別複雜的,這時交給基礎架構去作會簡單不少。另外,設計如此多的改造、變動開發設施流程須要更多的跨部門溝通與資源,形成成本增長;改造後也會帶來一些風險,須要檢測評估出臺兜底方案。此外,改造中要用到不少新的東西,須要咱們持續不斷的學習去汲取知識才能一直往前走。

雲原生應用與傳統應用的區別

雲原生應用與傳統應用的區別

雲原生在一個更好的基礎平臺與設施上提供了更多的應用。由於作了容器化就不須要指定操做系統,K8S 的資源調度更有彈性,以前須要經過代碼來協調實現伸縮策略,比較麻煩,藉助DevOps 會容易達成協做,由於它整個流程都是自動的,可以敏捷開發。還有微服是都是各自獨立的,具備高內聚、低耦合的原則,具備自動化運維、快速恢復的特色,自愈能力強。當集羣宕掉了,它會自動拉起,好比以前深夜業務故障可能須要定位到哪一個服務宕掉了,再從新啓動起來,如今就不用這麼麻煩,它會自動從新掛起,用戶甚至都不會感知。

荔枝微課基礎架構的演進

如上圖所示,原有架構是沒有集羣化的,比較亂;新架構作了集羣化,甚至是作了網絡隔離。提及網絡隔離,有些公司可能以爲不必,當測試環境跟生產環境在同一個網絡,會引入一些不肯定的因素,若是是上面的應用出現漏洞,有可能會被挖礦,甚至影響到生產環境,而網絡隔離能有效的防止這種狀況。新架構的優點在於經過集羣化的過程能夠實現有序管理、安全隔離,功能也更強大,像上面說到的自愈、資源編排等,生態也更加好了。固然咱們不只是關注外部服務,其餘雲原生上的應用能夠直接經過 Helm 之類的去安裝。

再提到 DevOps,這是經過不一樣的環節去建設的,從編碼到上線監控作服務治理,都是按下圖的流程走完,到後面的能力也愈來愈強。在編碼開發環節,關注的是代碼倉庫、代碼質量,像代碼質量監測,是以後一步步去往上加的。測試也是同樣,最先是本身作一個功能去測試,後面加了不少自動化測試的手段,好比壓測,能夠保證代碼上線的質量。

DevOps 上線之路

你們也許會以爲上線以前加那麼多環節,那迭代速度不就變慢了嗎?其實這是一個錯誤的認知,真正會變慢的是代碼質量不行,帶着 BUG 上線,發現後回滾甚至可能會直接帶來損失。這要是放在在之前的工廠,這種叫返工、召回,會更加影響效率,只有成功的發佈纔算是有效率的迭代

構建環節最先是本身把文件、代碼、環境依賴等打包好,傳到服務器,須要依賴服務器的自啓動手段去維護應用。作了容器化後,經過容器鏡像,打包成鏡像,它的環境會處於一個隔離的狀態,不易受到影響,再利用 DevOps 的 pipline+K8S 去發佈。環境作了更明確切分,發佈形式從最先的灰度到能夠滾動升級。

監控方面,最先只有日誌採集和 statsd 監控,上了集羣后就有 prometheus 去提供更多的監控信息。告警環節,從最先的郵件到企業微信,如今能更直接及時地收到事件信息,sentry 把報錯收集過來,就能夠及時定位到問題。分析也是這樣,若是對流程不熟悉,出問題後查找定位可能要花不少時間來分析,而如今作到了一鍵分析、慢查詢分析、RDB 分析,甚至監控曲線更智能的分析,固然如今雲廠商出售的服務器也會提供這些能力。

上線治理中,最先是當發現某個服務有異常,除了在 LB 負載均衡調權重,沒有其餘更好的辦法,只能經過代碼發版去作降級。有服務治理以後,就能夠在這一層作像熔斷之類的處理,例若有 K8S 以後,資源的調度、伸縮都更自動化了,再引入 Istio 、鏈路追蹤、訪問控制等能夠獲得更好的增強。

分佈式事務

分佈式事務是相對本地事務而言的,而數據庫本地事務有A(原子性)、C(一致性)、I(隔離性)、D(持久性)等四大特性。通俗來說就是一次性把全部事情打包作完,它是一個分佈式的。說到分佈式確定要提到布魯爾定理(CPA 定理),具備 C (一致性)、A ( 可用性)、P (分區容錯性)的特性。

理解了概念以後才能提出更好的解決手段,由於 CPA 中理論上沒有網絡延遲,而實際現實裏是有的,因此在 CPA 定理上加一個 BASE,即 Basically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent (最終一致性),能夠理解是對 CAP 中 AP 的一個擴展,這些更切合實際的理論在 BASE 中用軟狀態和最終一致,保證了延遲後的一致性。

分佈式事務處理手段

- 分佈式數據庫:能夠直接進行處理,但因爲分表機制不太同樣,可能會帶來一些麻煩;

- TCC:即 Try、Confirm、Cancel 模式,它不依賴關係數據庫,可是要按模式去實現 TCC 接口;

- 事務消息:咱們所知最多的就是 MQ 消息隊列也能夠去作分佈式事務處理,由於它能夠在不一樣的服務之間作異步的通知機制;

- 本地的消息表:經過定時輪詢或 Binlog 去觸發,保持兩個庫或兩個服務之間的一致性,前提是接口必須冪等性。

後期:服務網格化,提升服務治理能力

解決掉中期的麻煩後,後期則須要提升服務治理能力。以前是讓一個應用起來很簡單,可能一個命令就能夠,當微服務擴展了不少應用,拆分的服務愈來愈多,每一個服務的狀態都要管理,這時治理會變得愈來愈複雜,因此這階段會進行服務網格化。固然這個時間順序不是絕對的,當你足夠了解徹底掌握了,就會明白像雲原生 K8S 跟服務網格實際上是能夠合在一塊的。

這裏用了 Istio 官網上的介紹,智能控制服務之間的流量和 API 調用,經過不一樣 API 的流量管控能夠實現紅/黑部署,也稱爲藍綠部署、金絲雀部署。它提供建羣、流量增發,可以實現不一樣版本、不一樣服務之間流量比例的管控,能夠觀測,具備全鏈路追蹤的能力。

在有老服務、新服務的狀況下,能夠在流量管控的能力上作流量轉移,過程像是一邊行駛一邊換輪胎,用戶從外部訪問,咱們在網關這層作一個規則判斷。若是符合規則就走新服務,好比白名單或者灰度去匹配,進入集羣走新服務去運行;若是不符合則走默認的,即原來的老系統。

將來:持續演進,永無止境

將來會是一個持續演進的過程,永遠不會停留,沒有什麼最完美、最理想的架構,最理想的架構就是它能夠不斷的去演進。隨着咱們整個世界的技術潮流,它也會一步步往前推,而不是停滯不前。有些概念前面沒有提到,好比 Servceless、中臺等,經過業務中臺、基礎中臺、數據中臺的拆分來提供一些更通用的功能,還有像 AIOps/NoOps 都是在後面能夠去演化的。總之,技術方案老是有不少種,適合本身、適合現階段的就是好的。

如何肯定架構方向

架構的方向始終是圍繞需不須要、方不方便、穩不穩定、適不適合等展開的。單體架構也不必定不適合,主要看業務、成本、效率是否須要,如須要則是能夠保留的,或是當達到了必定規模有需求時再去考慮。在考慮如何規劃架構時,能夠從研發效率、擴展性等方面考慮是否更方便,固然最關鍵的是保持穩定性。

微服務的五大原則

  • 不要構建微服務,即不要爲了微服務而微服務,視實際狀況而定
  • 不要在沒有 DevOps 或者雲服務的狀況下進行微服務,要順勢而爲,借力打力
  • 不要經過使它們變得過小來製造太多的微服務
  • 不要把將微服務轉變爲 SOA
  • 不要嘗試成爲 Netflix,不須要什麼都從頭開始

架構的評價方法

  • 性能測試,好比網絡耗時
  • 壓力測試,檢測架構漏洞和需改進的
  • 按期演練,按期檢測
  • 團隊、用戶是否滿意,要根據反饋不斷的改進

穩定性總體趨勢

從一年前的事故頻發到中間一段時間的誤報,這個過程咱們也作了不少改進,由於毛刺會直接影響咱們的判斷。還有些是第三方平臺事故,針對第三方的問題首先是要溝通迫使對方去改進,再者本身也作好一些災備方案,好比選擇更多的合做商。今年咱們步入平穩增加期,基本上就沒有毛刺了。

以上是王誠強在又拍雲 Open Talk 公開課上的主要內容分享,視頻觀看、PPT 下載請點擊

推薦閱讀

看視頻常見的 720p、1080p、4k,這些分辨率到底包含了什麼

HTTP/3 來了,你瞭解它麼?