微服務入門概念

此文章很大部分轉載https://www.mrhelloworld.com/,博主均測試經過

 

技術架構演變

下圖表示從單體應用逐漸轉變爲微服務應用。前端

 

 

 

 通俗地講,「單體應用(monolith application)」就是將應用程序的全部功能都打包成一個獨立的單元。當網站流量很小時,只需一個應用,將全部功能都部署在一塊兒,以減小部署節點和成本。spring

  • 全部的功能集成在一個項目工程中;
  • 全部的功能打一個 war 包部署到服務器;
  • 應用與數據庫分開部署;
  • 經過部署應用集羣和數據庫集羣來提升系統的性能。
  • 開發簡單:一個 IDE 就能夠快速構建單體應用;數據庫

  • 便於共享:單個歸檔文件包含全部功能,便於在團隊之間以及不一樣的部署階段之間共享;編程

  • 易於測試:單體應用一旦部署,全部的服務或特性就均可以使用了,這簡化了測試過程,由於沒有額外的依賴,每項測試均可以在部署完成後馬上開始;後端

  • 容易部署:整個項目就一個 war 包,Tomcat 安裝好以後,應用扔上去就好了。羣化部署也很容易,多個 Tomcat + 一個 Nginx 分分鐘搞定。api

  • 妨礙持續交付:隨着時間的推移,單體應用可能會變得比較大,構建和部署時間也相應地延長,不利於頻繁部署,阻礙持續交付。在移動應用開發中,這個問題會顯得尤其嚴重;
  • 不夠靈活:隨着項目的逐漸變大,整個開發流程的時間也會變得很長,即便在僅僅更改了一行代碼的狀況下,軟件開發人員須要花費幾十分鐘甚至超過一個小時的時間對全部代碼進行編譯,並接下來花費大量的時間從新部署剛剛生成的產品,以驗證本身的更改是否正確。若是多個開發人員共同開發一個應用程序,那麼還要等待其餘開發人員完成了各自的開發。這下降了團隊的靈活性和功能交付頻率;
  • 受技術棧限制:項目變得愈來愈大的同時,咱們的應用所使用的技術也會變得愈來愈多。這些技術有些是不兼容的,就好比在一個項目中大範圍地混合使用 C++ 和 Java 幾乎是不可能的事情。在這種狀況下,咱們就須要拋棄對某些不兼容技術的使用,而選擇一種不是那麼適合的技術來實現特定的功能。
  • 可靠性差:某個環節出現了死循環,致使內存溢出,會影響整個項目掛掉。
  • **伸縮性差:**系統的擴容只能針對應用進行擴容,不能作到對某個功能進行擴容,擴容後必然帶來資源浪費的問題。
  • 技術債務:假設個人代碼庫中有一個混亂的模塊結構。此時,我須要添加一個新功能。若是這個模塊結構清晰,可能我只須要2天時間就能夠添加好這個功能,可是現在這個模塊的結構很混亂,因此我須要4天時間。多出來的這兩天就是債務利息。隨着時間推移、人員變更,技術債務必然也會隨之增多。

 

 

當訪問量逐漸增大,單一應用增長機器帶來的加速度愈來愈小,將應用拆成互不相干的幾個應用,以提高效率。跨域

  

  • 以單體結構規模的項目爲單位進行垂直劃分,就是將一個大項目拆分紅一個一個單體結構項目。
  • 項目與項目之間存在數據冗餘,耦合性較大,好比上圖中三個項目都存在用戶信息。
  • 項目之間的接口多爲數據同步功能,如:數據庫之間的數據庫,經過網絡接口進行數據庫同步。
  • 開發成本低,架構簡單;瀏覽器

  • 避免單體應用的無限擴大;緩存

  • 系統拆分實現了流量分擔,解決了併發問題;安全

  • 能夠針對不一樣系統進行擴容、優化;

  • 方便水平擴展,負載均衡,容錯率提升;

  • 不一樣的項目可採用不一樣的技術;

  • 系統間相互獨立。

  • 系統之間相互調用,若是某個系統的端口或者 IP 地址發生改變,調用系統須要手動變動;
  • 垂直架構中相同邏輯代碼須要不斷的複製,不能複用。
  • 系統性能擴展只能經過擴展集羣結點,成本高、有瓶頸。

 

 

當垂直應用愈來愈多,應用之間交互不可避免,將核心業務抽取出來,做爲獨立的服務,逐漸造成穩定的服務中心。當服務愈來愈多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增長一個調度中心基於訪問壓力實時管理集羣容量,提升集羣利用率。

P.S. 從軟件設計的角度上來講,ESB 是一個抽象的間接層,提取了服務調用過程當中調用與被調用動態交互中的一些共同的東西,減輕了服務調用者的負擔。Java 編程思想裏提到:「全部的軟件設計的問題均可以經過增長一個抽象的間接層而獲得解決或者獲得簡化!」簡單來講 ESB 就是一根管道,用來鏈接各個服務節點。爲了集成不一樣系統,不一樣協議的服務,ESB 作了消息的轉化解釋和路由工做,讓不一樣的服務互聯互通。

  • 基於 SOA 的架構思想將重複公用的功能抽取爲組件,以服務的形式給各系統提供服務。
  • 各項目(系統)與服務之間採用 WebService、RPC 等方式進行通訊。
  • 使用 ESB 企業服務總線做爲項目與服務之間通訊的橋樑。
  • 將重複的功能抽取爲服務,提升開發效率,提升系統的可重用性、可維護性。
  • 能夠針對不一樣服務的特色制定集羣及優化方案;
  • 採用 ESB 減小系統中的接口耦合。
  • 系統與服務的界限模糊,不利於開發及維護。
  • 雖然使用了 ESB,可是服務的接口協議不固定,種類繁多,不利於系統維護。
  • 抽取的服務的粒度過大,系統與服務之間耦合性高。
  • 涉及多種中間件,對開發人員技術棧要求高。
  • 服務關係複雜,運維、測試部署困難

 

  • 將系統服務層徹底獨立出來,並將服務層抽取爲一個一個的微服務。
  • 微服務中每個服務都對應惟一的業務能力,遵循單一原則。
  • 微服務之間採用 RESTful 等輕量協議傳輸。
  • 團隊獨立:每一個服務都是一個獨立的開發團隊,這個小團隊能夠是 2 到 5 人的開發人員組成;
  • 技術獨立:採用去中心化思想,服務之間採用 RESTful 等輕量協議通訊,使用什麼技術什麼語言開發,別人無需干涉;
  • 先後端分離:採用先後端分離開發,提供統一 Rest 接口,後端不用再爲 PC、移動端開發不一樣接口;
  • 數據庫分離:每一個微服務都有本身的存儲能力,能夠有本身的數據庫。也能夠有統一數據庫;
  • 服務拆分粒度更細,有利於資源重複利用,提升開發效率;
  • 一個團隊的新成員可以更快投入生產;
  • 微服務易於被一個開發人員理解,修改和維護,這樣小團隊可以更關注本身的工做成果。無需經過合做才能體現價值;
  • 能夠更加精準的制定每一個服務的優化方案(好比擴展),提升系統可維護性;
  • 適用於互聯網時代,產品迭代週期更短。
  • 微服務過多,服務治理成本高,不利於系統維護;
  • 分佈式系統開發的技術成本高(網絡問題、容錯問題、調用關係、分佈式事務等),對團隊挑戰大;
  • 微服務將原來的函數式調用改成服務調用,無論是用 rpc,仍是 http rest 方式,都會增大系統總體延遲。這個是再所不免的,這個就須要咱們將原來的串行編程改成併發編程甚至異步編程,增長了技術門檻;
  • 多服務運維難度,隨着服務的增長,運維的壓力也在增大;
  • 測試的難度提高。服務和服務之間經過接口來交互,當接口有改變的時候,對全部的調用方都是有影響的,這時自動化測試就顯得很是重要了,若是要靠人工一個個接口去測試,那工做量就太大了,因此 API 文檔的管理尤其重要。

CAP 原則

 

 

CAP 由 Eric Brewer 在 2000 年 PODC 會議上提出。該猜測在提出兩年後被證實成立,成爲咱們熟知的 CAP 定理。CAP 三者不可兼得。

CAP 原則又稱 CAP 定理,指的是在一個分佈式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。

Partition tolerance 中文叫作"分區容錯"。 大多數分佈式系統都分佈在多個子網絡。每一個子網絡就叫作一個區(partition)。分區容錯的意思是,區間通訊可 能失敗。

  好比,一臺服務器放在本地,另外一臺服務器放在外地(多是外省,甚至是外國),這就是兩個區,它們之間可能沒法通訊。

 

 上圖中,S1 和 S2 是兩臺跨區的服務器。S1 向 S2 發送一條消息,S2 可能沒法收到。系統設計的時候,必須考慮 到這種狀況。 通常來講,分區容錯沒法避免,

所以能夠認爲 CAP 的 P 老是成立。CAP 定理告訴咱們,剩下的 C 和 A 沒法同時作 到。

Consistency Consistency 中文叫作"一致性"。意思是,寫操做以後的讀操做,必須返回該值。舉例來講,某條記錄是 v0,用戶 向 S1 發起一個寫操做,將其改成 v1。

 

 接下來用戶讀操做就會獲得v1。這就叫一致性。

 

 問題是,用戶有可能會向S2發起讀取操做,因爲G2的值沒有發生變化,所以返回的是v0,因此S1和S2的讀操做不 一致,這就不知足一致性了

 

 爲了讓S2的返回值與S1一致,因此咱們須要在往S1執行寫操做的時候,讓S1給S2也發送一條消息,要求也變成 v1

 

 這樣子用戶向S2發起讀操做,就也能獲得v1

 

 Availability Availability 中文叫作"可用性",意思是隻要收到用戶的請求,服務器就必須給出迴應。

用戶能夠選擇向 S1 或 S2 發起讀操做。無論是哪臺服務器,只要收到請求,就必須告訴用戶,究竟是 v0 仍是 v1, 不然就不知足可用性。

Consistency 和 Availability 的矛盾 一致性和可用性,爲何不可能同時成立?

答案很簡單,由於可能通訊失敗(即出現分區容錯)。 若是保證 S2 的一致性,那麼 S1 必須在寫操做時,鎖定 S2 的讀操做和寫操做。

只有數據同步後,才能從新開放讀寫。鎖按期間,S2 不能讀寫,沒有可用性不。 若是保證 S2 的可用性,那麼勢必不能鎖定 S2,因此一致性不成立。 綜上所述,S2 沒法同時作到一致性和可用性。

系統設計時只能選擇一個目標。若是追求一致性,那麼沒法保證全部節點的可用性;若是追求全部節點的可用性,那就無法作到一致性。

CAP 三個特性只能知足其中兩個,那麼取捨的策略就共有三種:

  • CA without P:若是不要求P(不容許分區),則C(強一致性)和A(可用性)是能夠保證的。但放棄 P 的同時也就意味着放棄了系統的擴展性,也就是分佈式節點受限,沒辦法部署子節點,這是違背分佈式系統設計的初衷的。
  • CP without A:若是不要求A(可用),至關於每一個請求都須要在服務器之間保持強一致,而P(分區)會致使同步時間無限延長(也就是等待數據同步完才能正常訪問服務),一旦發生網絡故障或者消息丟失等狀況,就要犧牲用戶的體驗,等待全部數據所有一致了以後再讓用戶訪問系統。設計成 CP 的系統其實很多,最典型的就是分佈式數據庫,如 Redis、HBase 等。對於這些分佈式數據庫來講,數據的一致性是最基本的要求,由於若是連這個標準都達不到,那麼直接採用關係型數據庫就好,不必再浪費資源來部署分佈式數據庫。
  • AP without C:要高可用並容許分區,則需放棄一致性。一旦分區發生,節點之間可能會失去聯繫,爲了高可用,每一個節點只能用本地數據提供服務,而這樣會致使全局數據的不一致性。典型的應用就如某米的搶購手機場景,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在 A(可用性)方面保證系統能夠正常的服務,而後在數據的一致性方面作了些犧牲,雖然多少會影響一些用戶體驗,但也不至於形成用戶購物流程的嚴重阻塞。

eureka對比Zookeeper:

Zookeeper在設計的時候遵循的是CP原則,即一致性,

Zookeeper會出現這樣一種狀況,當master節點由於網絡故 障與其餘節點失去聯繫時剩餘節點會從新進行leader選舉,

問題在於,選舉leader的時間太長:30~120s,且選舉 期間整個Zookeeper集羣是不可用的,這就致使在選舉期間註冊服務處於癱瘓狀態,

在雲部署的環境下,因網絡環 境使Zookeeper集羣失去master節點是較大機率發生的事情,雖然服務可以最終恢復,可是漫長的選舉時間致使 長期的服務註冊不可用是不能容忍的。

Eureka在設計的時候遵循的是AP原則,便可用性。

Eureka各個節點(服務)是平等的, 沒有主從之分,幾個節點 down掉不會影響正常工做,剩餘的節點(服務) 依然能夠提供註冊與查詢服務,

而Eureka的客戶端在向某個 Eureka註冊或發現鏈接失敗,則會自動切換到其餘節點,

也就是說,只要有一臺Eureka還在,就能註冊可用(保 證可用性), 只不過查詢到的信息不是最新的(不保證強一致),

除此以外,Eureka還有自我保護機制,若是在 15分鐘內超過85%節點都沒有正常心跳,那麼eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現一下 狀況:

1:   Eureka 再也不從註冊列表中移除由於長時間沒有收到心跳而過時的服務。

2:Eureka 仍然可以接收新服務的註冊和查詢請求,可是不會被同步到其它節點上(即保證當前節點可用)

3: 當網絡穩定後,當前實例新的註冊信息會被同步到其它節點中

BASE 理論

CAP 理論已經提出好多年了,難道真的沒有辦法解決這個問題嗎?也許能夠作些改變。好比 C 沒必要使用那麼強的一致性,能夠先將數據存起來,稍後再更新,實現所謂的 「最終一致性」。

這個思路又是一個龐大的問題,同時也引出了第二個理論 BASE 理論。

BASE:全稱 Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫,來自 ebay 的架構師提出。

BASE 理論是對 CAP 中一致性和可用性權衡的結果,其來源於對大型互聯網分佈式實踐的總結,是基於 CAP 定理逐步演化而來的。其核心思想是:

既然沒法作到強一致性(Strong consistency),但每一個應用均可以根據自身的業務特色,採用適當的方式來使系統達到最終一致性(Eventual consistency)。

  基本可用是指分佈式系統在出現故障的時候,容許損失部分可用性(例如響應時間、功能上的可用性)。須要注意的是,基本可用毫不等價於系統不可用。

  • 響應時間上的損失:正常狀況下搜索引擎須要在 0.5 秒以內返回給用戶相應的查詢結果,但因爲出現故障(好比系統部分機房發生斷電或斷網故障),查詢結果的響應時間增長到了 1~2 秒。
  • 功能上的損失:購物網站在購物高峯(如雙十一)時,爲了保護系統的穩定性,部分消費者可能會被引導到一個降級頁面。

  什麼是軟狀態呢?相對於原子性而言,要求多個節點的數據副本都是一致的,這是一種 「硬狀態」。

  軟狀態是指容許系統存在中間狀態,而該中間狀態不會影響系統總體可用性。分佈式存儲中通常一份數據會有多個副本,容許不一樣副本數據同步的延時就是軟狀態的體現。

  系統不可能一直是軟狀態,必須有個時間期限。在期限事後,應當保證全部副本保持數據一致性。從而達到數據的最終一致性。這個時間期限取決於網絡延時,系統負載,數據複製方案設計等等因素。

  實際上,不僅是分佈式系統使用最終一致性,關係型數據庫在某個功能上,也是使用最終一致性的,好比備份,數據庫的複製都是須要時間的,這個複製過程當中,業務讀取到的值就是舊值。固然,最終仍是達成了數據一致性。這也算是一個最終一致性的經典案例。

 BASE 理論面向的是大型高可用可擴展的分佈式系統,和傳統事務的 ACID 是相反的,它徹底不一樣於 ACID 的強一致性模型,而是經過犧牲強一致性來得到可用性,並容許數據在一段時間是不一致的。

什麼是微服務?

微服務就是把本來臃腫的一個項目的全部模塊拆分開來並作到互相沒有關聯,甚至能夠不使用同一個數據庫。

好比:項目裏面有User模塊和Power模塊,可是User模塊和Power模塊並無直接關係,僅僅只是一些數據須要交互,

那麼就能夠吧這2個模塊單獨分開來,當user須要調用power的時候,power是一個服務方,可是power須要 調用user的時候,user又是服務方了,

因此,他們並不在意誰是服務方誰是調用方,他們都是2個獨立的服務,這 時候,微服務的概念就出來了。

經典問題:微服務和分佈式的區別

談到區別,咱們先簡單說一下分佈式是什麼,

所謂分佈式,就是將偌大的系統劃分爲多個模塊(這一點和微服務很像)部署到不一樣機器上(由於一臺機器可能承受不了這麼大的壓力或者說一臺很是好的服務器的成本可可以好幾臺普通的了),各個模塊經過接口進行數據交互,其實分佈式也是一種微服務。 由於都是把模塊拆分開來變爲獨立的單元,提供接口來調用,那麼 他們本質的區別在哪呢?

他們的區別主要體如今「目標」上, 何爲目標,就是你這樣架構項目要作到的事情。 分佈式的目標是什麼? 咱們剛剛也看見了, 就是一臺機器承受不了的,或者是成本問 題 , 不得不使用多臺機器來完成服務的部署, 而微服務的目標只是讓各個模塊拆分開來,不會被互相影響,好比模塊的升級亦或是出現BUG等等... 講了這麼多,能夠用一句話來理解:分佈式也是微服務的一種,而微服務他能夠是在一臺機器上。

微服務架構帶來的問題

  傳統的開發方式,全部的服務都是本地的,客戶端能夠直接調用,如今按功能拆分紅獨立的服務,客戶端如何訪問?

  後臺有 N 個服務,前臺就須要管理 N 個服務,一個服務下線/更新/升級,前臺就要從新部署,這明顯不符合咱們拆分的理念,另外,N 個服務的調用也是一個不小的網絡開銷。還有通常微服務在系統內部,一般是無狀態的,用戶登陸信息和權限管理最好有一個統一的地方維護管理(OAuth2)。

  因此,通常在後臺 N 個服務和客戶端之間通常會一個代理(API Gateway),做用以下:

  • 提供統一服務入口,聚合接口使得服務對調用者透明,客戶端與後端的耦合度下降
  • 聚合後臺服務,節省流量,提升性能,提高用戶體驗
  • 提供安全、流控、過濾、緩存、計費、監控等 API 管理功能

  由於服務都是獨立部署的,因此通訊也就成了問題,不過好在業界已經有不少成熟的解決方案,好比:

  • 同步通訊:
    • REST(JAX-RS,Spring Boot)
    • RPC(Dubbo,Thrift)
  • 異步通訊:
    • RabbitMQ,Kafka

  在微服務架構中,爲了高可用,廣泛採用集羣方式構建服務。一個服務可能隨時下線,也可能應對臨時訪問壓力增長新的服務節點。

  服務之間如何相互感知?服務如何管理?這就是服務發現的問題了。基本都是經過相似 ZooKeeper 等相似技術作服務註冊信息的分佈式管理。當服務上線時,服務提供者將本身的服務信息註冊到 ZooKeeper(或相似框架),並經過心跳維持長連接,實時更新連接信息。服務調用者經過 ZooKeeper 尋址,找到一個服務,還能夠將服務信息緩存在本地以提升性能。當服務下線時,ZooKeeper 會發通知給服務客戶端。

  在微服務架構中,一個請求須要調用多個服務是很是常見的。如客戶端訪問 A 服務,而 A 服務須要調用 B 服務,B 服務須要調用 C 服務,因爲網絡緣由或者自身的緣由,若是 B 服務或者 C 服務不能及時響應,A 服務將處於阻塞狀態,直到 B 服務 C 服務響應。此時如有大量的請求涌入,容器的線程資源會被消耗完畢,致使服務癱瘓。服務與服務之間的依賴性,故障會傳播,形成連鎖反應,會對整個微服務系統形成災難性的嚴重後果,這就是服務故障的「雪崩」效應。

  雪崩是系統中的蝴蝶效應致使,其發生的緣由多種多樣,從源頭咱們沒法徹底杜絕雪崩的發生,可是雪崩的根本緣由來源於服務之間的強依賴,因此咱們能夠提早評估作好服務容錯。

解決方案大概能夠分爲如下幾種:

  • 請求緩存:支持將一個請求與返回結果作緩存處理;
  • 請求合併:將相同的請求進行合併而後調用批處理接口;
  • 請求限流:當請求過多時,可能會拖垮整個網站,一般會採起限流措施,下降機器的負載;
  • 服務隔離:限制調用分佈式服務的資源,某一個調用的服務出現問題不會影響其餘服務調用;
  • 服務熔斷:犧牲局部服務,保全總體系統穩定性的措施;
  • 服務降級:服務熔斷之後,客戶端調用本身本地方法返回缺省值。

服務網關

隨着微服務的不斷增多,不一樣的微服務通常會有不一樣的網絡地址,而外部客戶端可能須要調用多個服務的接口才能完成一個業務需求,若是讓客戶端直接與各個微服務通訊可能出現:

  • 客戶端會屢次請求不一樣的微服務,增長了客戶端的複雜性
  • 存在跨域請求,在必定場景下處理相對複雜
  • 身份認證問題,每一個微服務須要獨立身份認證
  • 難以重構,隨着項目的迭代,可能須要從新劃分微服務
  • 某些微服務可能使用了防火牆/瀏覽器不友好的協議,直接訪問會有必定的困難

  針對這些問題,API網關順勢而生。

  API 網關直面意思是將全部 API 調用統一接入到 API 網關層,由網關層統一接入和輸出。

一個網關的基本功能有:統一接入、安全防禦、協議適配、流量管控、長短連接支持、容錯能力。

有了網關以後,各個 API 服務提供團隊能夠專一於本身的的業務邏輯處理,而 API 網關更專一於安全、流量、路由等問題。

 

 

服務治理

服務治理就是進行服務的自動化管理,其核心是服務的自動註冊與發現。

  • 服務註冊:服務實例將自身服務信息註冊到註冊中心。
  • 服務發現:服務實例經過註冊中心,獲取註冊到其中的服務實例的信息,經過這些信息去請求它們提供的服務。
  • 服務剔除:服務註冊中心將出問題的服務自動剔除到可用列表以外,使其不會被調用到。

負載均衡

服務高可用的保證手段,爲了保證高可用,每個微服務都須要部署多個服務實例來提供服務,此時就須要根據不一樣的負載均衡策略對服務進行調用。

  實現原理:輪詢策略表示每次都順序取下一個 provider,好比一共有 5 個 provider,第 1 次取第 1 個,第 2 次取第 2 個,第 3 次取第 3 個,以此類推。

  實現原理:

  • 根據每一個 provider 的響應時間分配一個權重,響應時間越長,權重越小,被選中的可能性越低。
  • 原理:一開始爲輪詢策略,並開啓一個計時器,每 30 秒收集一次每一個 provider 的平均響應時間,當信息足夠時,給每一個 provider 附上一個權重,並按權重隨機選擇 provider,高權越重的 provider 會被高几率選中。

  實現原理:從 provider 列表中隨機選擇一個。

  實現原理:選擇正在請求中的併發數最小的 provider,除非這個 provider 在熔斷中。

  實現原理:其實就是輪詢策略的加強版,輪詢策略服務不可用時不作處理,重試策略服務不可用時會從新嘗試集羣中的其餘節點。

  實現原理:過濾性能差的 provider

  • 第一種:過濾掉在 Eureka 中處於一直鏈接失敗的 provider。
  • 第二種:過濾掉高併發(繁忙)的 provider。

  實現原理:

  • 以一個區域爲單位考察可用性,對於不可用的區域整個丟棄,從剩下區域中選可用的 provider。
  • 若是這個 ip 區域內有一個或多個實例不可達或響應變慢,都會下降該 ip 區域內其餘 ip 被選中的權重。

服務容錯

在微服務中,一個請求常常會涉及到調用多個服務,若是其中某個服務不可用,沒有作服務容錯的話,極有可能會形成一連串的服務不可用,這就是雪崩效應。

最終的結果就是:一個服務不可用,致使一系列服務的不可用。

  形成雪崩的緣由能夠歸結爲如下三點:

  • 服務提供者不可用(硬件故障,程序 BUG,緩存擊穿,用戶大量請求等)
  • 重試加大流量(用戶重試,代碼邏輯重試)
  • 服務消費者不可用(同步等待形成的資源耗盡)

  咱們無法預防雪崩效應的發生,只能儘量去作好容錯。服務容錯的三個核心思想是:

  • 不被外界環境影響
  • 不被上游請求壓垮
  • 不被下游響應拖垮

鏈路追蹤

隨着微服務架構的流行,服務按照不一樣的維度進行拆分,一次請求每每須要涉及到多個服務。互聯網應用構建在不一樣的軟件模塊集上,這些軟件模塊,有多是由不一樣的團隊開發、可能使用不一樣的編程語言來實現、有可能布在了幾千臺服務器,橫跨多個不一樣的數據中心。所以,就須要對一次請求涉及的多個服務鏈路進行日誌記錄,性能監控等等。

單純的理解鏈路追蹤,就是指一次任務的開始到結束,期間調用的全部系統及耗時(時間跨度)均可以完整記錄下來。

鏈路追蹤系統作好了,鏈路數據有了,藉助前端解析和渲染工具,能夠達到下圖中的效果:

配置中心

配置文件是咱們再熟悉不過的,在微服務系統中,每一個微服務不只僅只有代碼,還須要鏈接其餘資源,例如數據庫的配置或功能性的開關 MySQL、Redis 、Security 等相關的配置。

除了項目運行的基礎配置以外,還有一些配置是與咱們業務有關係的,好比說七牛存儲、短信和郵件相關,或者一些業務上的開關。

  可是隨着微服務系統的不斷迭代,整個微服務系統可能會成爲一個網狀結構,這個時候就要考慮整個微服務系統的擴展性、伸縮性、耦合性等等。其中一個很重要的環節就是配置管理的問題。

  常規配置管理解決方案缺點:

  • 硬編碼(須要修改代碼、繁瑣、風險大)
  • properties 或者 yml(集羣環境下須要替換和重啓)
  • xml(從新打包和重啓)

  因爲常規配置管理有很大的缺點,因此採用 Spring Cloud Config 或 Consul 或 Apollo 或 Nacos 等配置中心集中式的來管理每一個服務的配置信息。

安全認證

從單體應用架構到分佈式應用架構再到微服務架構,應用的安全訪問在不斷的經受考驗。爲了適應架構的變化、需求的變化,身份認證與鑑權方案也在不斷的變革。面對數十個甚至上百個微服務之間的調用,

如何保證高效安全的身份認證?面對外部的服務訪問,該如何提供細粒度的鑑權方案?

  David Borsos 在倫敦的微服務大會上提出了四種解決方案:

  這種方案意味着每一個面向用戶的服務都必須與認證服務交互,這會產生大量很是瑣碎的網絡流量和重複的工做,隨着微服務應用的增多,這種方案的弊端會更加明顯。

  分佈式會話方案原理主要是將關於用戶認證的信息存儲在共享存儲中,且一般由用戶會話做爲 Key 來實現的簡單分佈式哈希映射。當用戶訪問微服務時,用戶數據能夠從共享存儲中獲取。這種方案的缺點在於共享存儲須要必定保護機制,所以須要經過安全連接來訪問,這時解決方案的實現就一般具備至關高的複雜性了。

  令牌在客戶端生成,由身份驗證服務進行簽名,而且必須包含足夠的信息,以即可以在全部微服務中創建用戶身份。令牌會附加到每一個請求上,爲微服務提供用戶身份驗證,這種解決方案的安全性相對較好,但身份驗證註銷是一個大問題,緩解這種狀況的方法可使用短時間令牌和頻繁檢查認證服務等。對於客戶端令牌的編碼方案,David Borsos 更喜歡使用 JSON Web Tokens(JWT),它足夠簡單且庫支持程度也比較好。

  這個方案意味着全部請求都經過網關,從而有效地隱藏了微服務。 在請求時,網關將原始用戶令牌轉換爲內部會話 ID 令牌。在這種狀況下,註銷就不是問題,由於網關能夠在註銷時撤銷用戶的令牌。

  在微服務架構下,咱們更傾向於 David Borsos 所建議的 JWT 方案,將 OAuth2 和 JWT 結合使用,OAuth2 通常用於第三方接入的場景,管理對外的權限,因此比較適合和 API 網關結合,針對於外部的訪問進行鑑權(固然,底層 Token 標準採用 JWT 也是能夠的)。

  JWT 更加輕巧,在微服務之間進行認證&鑑權已然足夠,而且能夠避免和身份認證服務直接打交道。固然,從能力實現角度來講,相似於分佈式 Session 在不少場景下也是徹底能知足需求,具體怎麼去選擇鑑權方案,仍是要結合實際的需求來。

微服務與Spring-Cloud的關係(區別)

微服務只是一種項目的架構方式,或者說是一種概念,就如同咱們的MVC架構同樣, 那麼Spring-Cloud即是對這 種技術的實現。

微服務必定要使用Spring-Cloud嗎?

咱們剛剛說過,微服務只是一種項目的架構方式,若是你足夠了解微服務是什麼概念你就會知道,其實微服務就算不借助任何技術也能實現,只是有不少問題須要咱們解決罷了例如:負載均衡,服務的註冊與發現,服務調用,路 由。。。。等等等等一系列問題,因此,Spring-Cloud 就出來了,Spring-Cloud將處理這些問題的的技術所有打包好了,就相似那種開袋即食的感受。。

Spring Cloud 是什麼

Spring Cloud 是一個服務治理平臺,提供了一些服務框架。包含了:服務註冊與發現、配置中心、消息中心 、負載均衡、數據監控等等。

Spring Cloud 是一個微服務框架,相比 Dubbo 等 RPC 框架,Spring Cloud 提供了全套的分佈式系統解決方案。

Spring Cloud 是一個基於 Spring Boot 實現的雲應用開發工具,

它爲開發中的配置管理、服務發現、斷路器、智能路由、微代理、控制總線、全局鎖、決策競選、分佈式會話和集羣狀態管理等操做提供了一種簡單的開發方式。

Spring Cloud 爲開發者提供了快速構建分佈式系統的工具,開發者能夠快速的啓動服務或構建應用、同時可以快速和雲平臺資源進行對接。

Spring Cloud Netflix 第一代

Netflix是一家美國公司,在美國、加拿大提供互聯網隨選流媒體播放,定製DVD、藍光光碟在線出租業務。

針對多種 Netflix 組件提供的開發工具包,其中包括 Eureka、Hystrix、Ribbon、Zuul、Archaius 等。

 

  1. Netflix Eureka:一個基於 Rest 服務的服務治理組件,包括服務註冊中心、服務註冊與服務發現機制的實現,實現了雲端負載均衡和中間層服務器的故障轉移。
  2. Netflix Hystrix:容錯管理工具,實現斷路器模式,經過控制服務的節點,從而對延遲和故障提供更強大的容錯能力。
  3. Netflix Ribbon:客戶端負載均衡的服務調用組件。
  4. Netflix Feign:基於 Ribbon 和 Hystrix 的聲明式服務調用組件。
  5. Netflix Zuul:微服務網關,提供動態路由,訪問過濾等服務。
  6. Netflix Archaius:配置管理 API,包含一系列配置管理 API,提供動態類型化屬性、線程安全配置操做、輪詢框架、回調機制等功能。

Spring Cloud Alibaba 第二代

Spring Cloud Alibaba 致力於提供微服務開發的一站式解決方案。此項目包含開發分佈式應用微服務的必需組件,方便開發者經過 Spring Cloud 編程模型輕鬆使用這些組件來開發分佈式應用服務。

依託 Spring Cloud Alibaba,只須要添加一些註解和少許配置,就能夠將 Spring Cloud 應用接入阿里微服務解決方案,經過阿里中間件來迅速搭建分佈式應用系統。

  • Nacos:阿里巴巴開源產品,一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。

  • Sentinel:面向分佈式服務架構的輕量級流量控制產品,把流量做爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。

  • RocketMQ:一款開源的分佈式消息系統,基於高可用分佈式集羣技術,提供低延時的、高可靠的消息發佈與訂閱服務。

  • Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。

  • Seata:阿里巴巴開源產品,一個易於使用的高性能微服務分佈式事務解決方案。

  • Alibaba Cloud ACM:一款在分佈式架構環境中對應用配置進行集中管理和推送的應用配置中心產品。

  • Alibaba Cloud OSS:阿里雲對象存儲服務(簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。您能夠在任何應用、任什麼時候間、任何地點存儲和訪問任意類型的數據。

  • Alibaba Cloud SchedulerX:阿里中間件團隊開發的一款分佈式任務調度產品,提供秒級、精準、高可靠、高可用的定時(基於 Cron 表達式)任務調度服務。

  • Alibaba Cloud SMS:覆蓋全球的短信服務,友好、高效、智能的互聯化通信能力,幫助企業迅速搭建客戶觸達通道。

做爲 Spring Cloud 體系下的新實現,Spring Cloud Alibaba 跟官方的組件或其它的第三方實現如 Netflix,Consul,Zookeeper 等對比,具有了更多的功能:

 

 

經常使用組件

  • Spring Cloud Netflix Eureka:服務註冊中心。
  • Spring Cloud Zookeeper:服務註冊中心。
  • Spring Cloud Consul:服務註冊和配置管理中心。
  • Spring Cloud Netflix Ribbon:客戶端負載均衡。
  • Spring Cloud Netflix Hystrix:服務容錯保護。
  • Spring Cloud Netflix Feign:聲明式服務調用。
  • Spring Cloud OpenFeign(可替代 Feign):OpenFeign 是 Spring Cloud 在 Feign 的基礎上支持了 Spring MVC 的註解,如 @RequesMapping等等。OpenFeign 的 @FeignClient 能夠解析 SpringMVC 的 @RequestMapping 註解下的接口,並經過動態代理的方式產生實現類,實現類中作負載均衡並調用其餘服務。
  • Spring Cloud Netflix Zuul:API 網關服務,過濾、安全、監控、限流、路由。
  • Spring Cloud Gateway(可替代 Zuul):Spring Cloud Gateway 是 Spring 官方基於 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術開發的網關,Spring Cloud Gateway 旨在爲微服務架構提供一種簡單而有效的統一的 API 路由管理方式。Spring Cloud Gateway 做爲 Spring Cloud 生態系中的網關,目標是替代 Netflix Zuul,其不只提供統一的路由方式,而且基於 Filter 鏈的方式提供了網關基本的功能,例如:安全,監控/埋點,和限流等。
  • Spring Cloud Security:安全認證。
  • Spring Cloud Config:分佈式配置中心。配置管理工具,支持使用 Git 存儲配置內容,支持應用配置的外部化存儲,支持客戶端配置信息刷新、加解密配置內容等。
  • Spring Cloud Bus:事件、消息總線,用於在集羣(例如,配置變化事件)中傳播狀態變化,可與 Spring Cloud Config 聯合實現熱部署。
  • Spring Cloud Stream:消息驅動微服務。
  • Spring Cloud Sleuth:分佈式服務跟蹤。
  • Spring Cloud Alibaba Nacos:阿里巴巴開源產品,一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。
  • Spring Cloud Alibaba Sentinel:面向分佈式服務架構的輕量級流量控制產品,把流量做爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
  • Spring Cloud Alibaba RocketMQ:一款開源的分佈式消息系統,基於高可用分佈式集羣技術,提供低延時的、高可靠的消息發佈與訂閱服務。
  • Spring Cloud Alibaba Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架,用於實現服務通訊。
  • Spring Cloud Alibaba Seata:阿里巴巴開源產品,一個易於使用的高性能微服務分佈式事務解決方案。

 

 雖然 Eureka,Hystrix 等再也不繼續開發或維護,可是目前來講不影響使用,無論怎麼說感謝開源,向 Netflix 公司的開源致敬。

爲何 Spring Cloud 版本用的是單詞而不是數字?

 

 

這樣設計的目的是爲了更好的管理每一個 Spring Cloud 的子項目的清單。避免總版本號與子項目的版本號混淆。

例如:Spring Cloud 2.2.0.RELEASE 的 Spring Cloud Netflix 2.2.2.RELEASE 若是使用這種方式會讓開發者混淆版本號。

 

 

發佈計劃

 

 

子項目版本說明

例如:Spring Cloud Alibaba 2.1.0.RELEASE

  • 2:主版本號。當功能模塊有較大更新或者總體架構發生變化時,主版本號會更新。
  • 1:次版本號。次版本表示只是局部的一些變更。
  • 0:修改版本號。通常是 bug 的修復或者是小的變更。
  • RELEASE:希臘字母版本號。標註當前版本的軟件處於哪一個開發階段。

希臘字母版本說明

  • Base:設計階段。只有相應的設計沒有具體的功能實現。
  • Alpha:軟件的初級版本。存在較多的 bug。
  • Bate:表示相對 Alpha 有了很大的進步,消除了嚴重的 bug,還存在一些潛在的 bug。
  • Gamma:是 Beta 版作過一些修改,成爲正式發佈的候選版本(Release Candidate)
  • Release:該版本表示最終版。
相關文章
相關標籤/搜索