微服務架構的前世今生

傳統行業向互聯網行業的轉型

背景

2012年以後,因爲移動互聯網的興起,隨着網名數量的增多,需求變化大,用戶羣體大。導致已有的應用程序無法抗住大規模的併發,且版本迭代麻煩,擴展不夠靈活,應對外界環境能力薄弱,所以微服務思想就應運而生了。

2014年微服務的概念傳入中國,2015年左右國內大廠開始進行項目升級,轉戰微服務。2018年中小型企業也開始進行微服務架構升級。

傳統行業的產品是必然要向互聯網行業進行轉型的,馬雲爸爸曾經說過:如果說傳統制造業不擁抱互聯網的話,那註定是死路一條。而轉型的過程當中,底層的架構模式也不再是傳統的單體架構了,而是全新的微服務架構模式。

馬雲曾說道:十五年以前,我在全國各地,至少兩三年內講過兩三百次這樣的演講,提醒大家互聯網、電子商務對各行各業會有衝擊,但是沒有人把這個話當回事情,那個時候我是Nobody,講話等於白講。但是今天,既然我已經有這樣的資源,我還是要告訴大家,未來二三十年,這個世界的變化超過所有人的想象力,而且絕大部分人是很倒黴的。今天的傳統企業如果依然固步自封,不接受新時代和新的商業模式,勢必會被淘汰。

傳統行業與互聯網行業的區別

互聯網發展史

web 1.0

用戶只能搜索和閱讀網絡信息。比如中國的幾大門戶網站:搜狐、新浪、網易、騰訊,平臺提供內容和數據,用戶被動接受,和用戶缺乏交互。

web 2.0

用戶能夠創造內容,並分享在網路平臺上跟大家進行互動,而不再只是單純的訪問者;這種範式的發展重新定義了市場和商業模式。比如QQ、天涯、微博、淘寶、美團、滴滴,提供一個平臺,用戶你們自己玩。用戶需要註冊,用戶和平臺交互變得很強,用戶和用戶之間可以交流,數據幾乎由用戶產生。

web 3.0

網絡在接受信息的同時,通過數據分析,能夠根絕用戶的喜好產生出新的數據和信息並推送給用戶。比如網易雲音樂的推薦,搜索引擎的推薦,淘寶的商品推薦,地圖應用的出行規劃,堵車預測等等。其特徵是使用 web 2.0 時代所產生的大量數據,更加精準、實時和深入的爲用戶提供服務。一個簡單的例子:當你在淘寶上買了某件商品後,訂單下方會出現很多類似商品推送。

總結

比如:你家樓下餐館代表互聯網,你飾演互聯網用戶。

  • WEB1.0時代:你晚上一進餐館,老闆給你上了一桌子菜,說兄弟都是你的喫吧!(不分析)你自己挨個嘗試,因爲你不知道哪個菜好喫。(缺乏交互)
  • WEB2.0時代:你晚上一進餐館,你說:老闆來斤餃子。老闆說:沒有餃子有面條。你說來碗麪條,老闆給你上了一碗麪條。(被動分析)或者,你不知道喫什麼好,但是坐在你旁邊的食客會告訴你哪個好喫。(用戶交互)
  • WEB3.0時代:你晚上一進餐館,一進門老闆就說:客官,來碗麪條吧!你問爲啥,老闆說,你連續喫一禮拜麪條了。(主動分析)WEB 3.0 是微服務、大數據、雲計算、人工智能的時代。

技術架構演變

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

單一應用架構

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

特點

  • 所有的功能集成在一個項目工程中;
  • 所有的功能打一個 war 包部署到服務器;
  • 應用與數據庫分開部署;
  • 通過部署應用集羣和數據庫集羣來提高系統的性能。

優點:

  • 開發簡單:一個 IDE 就可以快速構建單體應用;

  • 便於共享:單個歸檔文件包含所有功能,便於在團隊之間以及不同的部署階段之間共享;

  • 易於測試:單體應用一旦部署,所有的服務或特性就都可以使用了,這簡化了測試過程,因爲沒有額外的依賴,每項測試都可以在部署完成後立刻開始;

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

缺點:

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

垂直應用架構

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

特點

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

優點

  • 開發成本低,架構簡單;

  • 避免單體應用的無線擴大;

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

  • 可以針對不同系統進行擴容、優化;

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

  • 不同的項目可採用不同的技術;

  • 系統間相互獨立。

缺點

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

SOA 面向服務架構

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

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

特點

  • 基於 SOA 的架構思想將重複公用的功能抽取爲組件,以服務的形式給各系統提供服務。
  • 各項目(系統)與服務之間採用 WebService、RPC 等方式進行通信。
  • 使用 ESB 企業服務總線作爲項目與服務之間通信的橋樑。

優點

  • 將重複的功能抽取爲服務,提高開發效率,提高系統的可重用性、可維護性。
  • 可以針對不同服務的特點制定集羣及優化方案;
  • 採用 ESB 減少系統中的接口耦合。

缺點

  • 系統與服務的界限模糊,不利於開發及維護。
  • 雖然使用了 ESB,但是服務的接口協議不固定,種類繁多,不利於系統維護。
  • 抽取的服務的粒度過大,系統與服務之間耦合性高。
  • 涉及多種中間件,對開發人員技術棧要求高。
  • 服務關係複雜,運維、測試部署困難

微服務架構

特點

  • 將系統服務層完全獨立出來,並將服務層抽取爲一個一個的微服務。
  • 微服務中每一個服務都對應唯一的業務能力,遵循單一原則。
  • 微服務之間採用 RESTful 等輕量協議傳輸。

優點

  • 團隊獨立:每個服務都是一個獨立的開發團隊,這個小團隊可以是 2 到 5 人的開發人員組成;
  • 技術獨立:採用去中心化思想,服務之間採用 RESTful 等輕量協議通信,使用什麼技術什麼語言開發,別人無需干涉;
  • 前後端分離:採用前後端分離開發,提供統一 Rest 接口,後端不用再爲 PC、移動端開發不同接口;
  • 數據庫分離:每個微服務都有自己的存儲能力,可以有自己的數據庫。也可以有統一數據庫;
  • 服務拆分粒度更細,有利於資源重複利用,提高開發效率;
  • 一個團隊的新成員能夠更快投入生產;
  • 微服務易於被一個開發人員理解,修改和維護,這樣小團隊能夠更關注自己的工作成果。無需通過合作才能體現價值;
  • 可以更加精準的制定每個服務的優化方案(比如擴展),提高系統可維護性;
  • 適用於互聯網時代,產品迭代週期更短。

缺點

  • 微服務過多,服務治理成本高,不利於系統維護;
  • 分佈式系統開發的技術成本高(網絡問題、容錯問題、調用關係、分佈式事務等),對團隊挑戰大;
  • 微服務將原來的函數式調用改爲服務調用,不管是用 rpc,還是 http rest 方式,都會增大系統整體延遲。這個是再所難免的,這個就需要我們將原來的串行編程改爲併發編程甚至異步編程,增加了技術門檻;
  • 多服務運維難度,隨着服務的增加,運維的壓力也在增大;
  • 測試的難度提升。服務和服務之間通過接口來交互,當接口有改變的時候,對所有的調用方都是有影響的,這時自動化測試就顯得非常重要了,如果要靠人工一個個接口去測試,那工作量就太大了,所以 API 文檔的管理尤爲重要。

總結

分享兩個小故事,幫助大家更好的理解 SOA 與微服務的區別。

故事一:

很久以前的一天,Martin 在跟好友的交流中悟到了一種很棒的架構設計。他總結了一下,然後告訴了好友,好友說,這不是新鮮東西,早有人總結了,叫做 SOA。

Martin 很高興,開始在公司內外推廣 SOA。結果,不停有人質疑和挑戰他。

你這不是 SOA 吧?SOA 這裏應該是如此這般的。對,這裏我對 SOA 的理解是這樣的。你看,這本 SOA 的書說的和你說的有出入。粒度?SOA 沒有談到這個呀,你這不是 SOA。分層跟 SOA 沒有關係,你爲什麼要說這個呢?…

Martin 沒辦法,心一橫,老子就叫它 Martin’s SOA。老子發明的詞,老子就是最高權威,有最終解釋權。還有誰不服?

同事們一看,這思想本身很不錯,值得推廣,但叫 Martin’s SOA 太沒品了吧?還是要取個好一點的名字,最好還能跟 SOA 有某種暗示傳承。乾脆就叫 Microservices 好了,又新,又有服務含在其中。

Martin 忿忿地接受了這個建議,心裏想着:孃的,明明就是 SOA,一羣**非要逼我取個新名字。

後來 Martin 發現每次提一個東西就會收到舊惡傻勢力對解釋權的挑戰,所以每次要提一個什麼概念,都去發明一個新詞,免得一羣人在那一邊質疑挑戰,一邊大談“我的理解”。

這就是微服務、敏捷、精益企業、持續集成、持續交付背後的故事。

一個名詞產生之後,命名者的解釋權就會隨着時間而弱化(比如 Cooper 發明的 Persona 就被無數設計師亂用)。敏捷已經有點爛了,等微服務也爛了,我們還會發明新詞。

實在沒轍,都是被逼的啊。

故事二:

話說1979年,又是一個春天,莆田鄉下的赤腳醫生吳大牛被改革的春風吹的心潮澎湃,說幹就幹,吳大牛趁着夜色朦朧找大隊支書彙報了彙報思想,第二天就承包了村衛生室,開啓了自己的在醫療圈的傳奇歷程。

鄉村診所大家都知道,沒什麼複雜的東東,房子只有一間,一個大櫃檯中間隔開,一半是診療兼候診區,一半是藥房,看病就直接找醫生,如果前面有人就自己找個位子坐下,排隊等一會,秩序倒也井然,看完病了醫生直接給抓藥,然後下一個繼續,也不需要護士和藥劑師,吳大牛一個人全部包辦。

辛辛苦苦忙碌了十年,時間來到了八九年,又是一個春天,昔日的單身漢吳大牛已成爲十里八鄉的知名人物,媳婦娶上了不說,家裏還增加了一對雙胞胎兒子,二層的小洋房也甚是氣派。可是也有煩心事,儘管鄉村診所擴大到了兩間,媳婦還偶爾能去幫幫忙,但是醫生還是隻有自己一個,天天從早忙到晚掙的都是一份錢,想多掙點怎麼辦?吳大牛日思夜想,還真給他想出來一招,怎麼辦,擴大規模,多招幾個醫生一起幹。原來吳大牛隻能治頭疼腦熱和跌打損傷,現在新招了一個醫科大學的畢業生劉小明專治感冒發燒,又從鄰村請來了老大夫李阿花專治婦科病,現在一個普通的小診所就變成了有三個獨立科室加一個公共藥房(吳大牛媳婦負責)的小醫院了,吳大牛是外科主任兼院長,收入那可比之前翻了三番。人逢喜事精神爽,大牛院長請縣裏的書法名家爲新醫院書寫了牌匾–“博愛醫院”,挑了一個黃道吉日正式掛了上去。

一晃十年過去了,又是一個春天,吳大牛的博愛醫院已經發展到了內科外科婦科五官科骨科生殖科六個科室,每個科室3到5名醫生不等,也耗費巨資購進了血化驗B超等先進儀器,大牛院長也早已脫離了醫療一線,成爲了專職的管理者,但是醫院的大事小事大家都找他,就這三十多號員工搞的他每天是焦頭爛額,想再擴大規模實在是有心無力了。要說還是大學生有水平,老部下劉小明給大牛院長獻了一計,把各個科室獨立出去,讓各個科室主任自己管理,大牛院長只管科室之間的協調和醫院發展的大事,這樣既能調動基層的積極性,又能把大牛院長解放出來擴大生產抓大事謀大事,豈不妙哉?就這樣,博愛醫院的新一輪改革轟轟烈烈的展開了。

又是一個十年,又是一個春天,大牛院長已成爲本地知名的企業家,博愛醫院也發展到了二十三個科室數百名員工,發展中也出現了新問題,由於各個科室獨立掛號、收費、化驗,有的科室整天忙忙碌碌效益好,有的科室就相對平庸些,連分到的各種檢查儀器都不能滿負荷運行,整個醫院養了不少閒人。這時候大牛院長視野也開闊了,請來了管理專家進行了頂層設計,把原來分散到各個科室的非核心服務全部收歸集中管理,把原來二十三個掛號窗口整合爲十個,二十三個收費窗口整合爲八個,集中佈設在一樓大廳爲全院服務,還把分散在各個科室的檢查儀器集中起來成立獨立的檢驗科,也爲全院服務,這樣人人有活幹,整個醫院的服務能力又上了一個新臺階,這輪改革後博愛醫院通過了各級部門的鑑定成爲了遠近馳名的三甲醫院,吳大牛也換身一變成爲了博愛集團的CEO兼董事長,下一步就準備IPO上市了。

說到這裏大家可能有點糊塗,這個跟微服務有嘛關係?在孫老師看來,大牛診所的1.0階段就相當於軟件開發的單體結構,一個程序員打天下,從頭編到尾,很難做大做強。大牛診所的2.0階段就相當於軟件開發的垂直結構,各科室按照業務劃分,很容易橫向擴展。博愛醫院的1.0階段就相當於軟件開發的SOA結構,除了藥房(數據庫)外各個服務獨立提供(科室主任負責),但需要大牛院長(ESB總線)來協調。博愛醫院的2.0階段就相當於軟件開發的微服務結構,公共服務院內共享,科室主任管理功能弱化(只管醫生業務),優點是擴容方便,哪個部門缺人直接加,不用看上下游,資源利用率高,人員和設備效率高。

微服務就是將一個單體架構的應用按業務劃分爲一個個的獨立運行的程序即服務,它們之間通過 HTTP 協議進行通信(也可以採用消息隊列來通信,如 RabbitMQ,Kafaka 等),可以採用不同的編程語言,使用不同的存儲技術,自動化部署(如 Jenkins)減少人爲控制,降低出錯概率。服務數量越多,管理起來越複雜,因此採用集中化管理。例如 Eureka,Zookeeper 等都是比較常見的服務集中化管理框架。

**微服務是一種架構風格,架構就是爲了解耦,實際使用的是分佈式系統開發。**一個大型的複雜軟件應用,由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是松耦合的。每個微服務僅關注於完成一件任務並很好的完成該任務。

一句話總結:微服務是 SOA 發展出來的產物,它是一種比較現代化的細粒度的 SOA 實現方式。

微服務設計原則

AKF 拆分原則

業界對於可擴展的系統架構設計有一個樸素的理念,就是:通過加機器可以解決容量和可用性問題(如果一臺不行就兩臺)。

用個段子描述就是:世界上沒有什麼事是一頓燒烤解決不了的,如果有,那就兩頓。

《The Art of Scalability》一書提出了一個系統的可擴展模型——AKF 可擴展立方。這個立方體中沿着三個座標軸設置分別爲 X,Y,Z。

一個叫 AKF 的公司的技術專家抽象總結的應用擴展的三個維度。理論上按照這三個擴展模式,可以將一個單體系統,進行無限擴展。

Y 軸

就是我們所說的微服務的拆分模式,就是基於不同的業務拆分。Y 軸擴展會將龐大的整體應用拆分爲多個服務。每個服務實現一組相關的功能,如商品管理、訂單管理、用戶管理等。

X 軸

X 軸擴展指得是水平復制,通過絕對平等地複製服務與數據,以解決容量和可用性的問題。很好理解,就是將單體系統多運行幾個實例,成爲集羣加負載均衡的模式。

Z 軸

Z 軸擴展通常是指基於請求者或用戶獨特的需求,進行系統劃分,並使得劃分出來的子系統是相互隔離但又是完整的。以生產手機的工廠來舉例:蘋果公司爲了發展在中國的業務,或者利用中國的廉價勞動力,在中國建立一個完整的子工廠,與美國工廠一樣,負責完整的手機生產。這就是一種 Z 軸擴展。

場景說明:比如單體打車應用,一個集羣撐不住時,分了多個集羣,後來用戶激增還是不夠用,經過分析發現是乘客和車主訪問量很大,就將打車應用拆成了三個,分別爲乘客服務、車主服務、支付服務。三個服務的業務特點各不相同,獨立維護,各自都可以再次按需擴展。我們可以水平擴展三個服務,形成各自服務的集羣模式。實在不行最後根據北上廣熱門地區劃分爲多份,你在哪個城市打車,就給你展示哪個城市的司機數據分區。

前後端分離原則

以前的 Java Web 項目大多都是程序員既當爹又當媽,既搞前端,又搞後端。隨着時代的發展,漸漸的許多大中小公司開始把前後端的界限分的越來越明確,前端工程師只管前端的事情,後端工程師只管後端的事情。正所謂術業有專攻,大中型公司需要專業人才,小公司需要全才,但是對於個人職業發展來說,前後端需要分離,畢竟一個人如果什麼都會,那麼他可能什麼都不精。

未分離

在前後端不分離的應用模式中,前端頁面看到的效果都是由後端控制,由後端渲染頁面或重定向,也就是後端需要控制前端的展示,前端與後端的耦合度很高。

這種應用模式比較適合純網頁應用,但是當後端對接 App 時,App 可能並不需要後端返回一個 HTML 網頁,而僅僅是數據本身,所以後端原本返回網頁的接口不再適用於前端 App 應用,爲了對接 App 後端還需再開發一套接口。

該時期代表:Servlet + Jsp + JavaBean

<body>
   <%
       request.setCharacterEncoding("utf-8");
       String username = request.getParameter("username");
       System.out.print(username);
   %>
</body>

半分離

前後端半分離,前端負責開發頁面,通過接口(Ajax)獲取數據,採用 Dom 操作對頁面進行數據綁定,最終是由前端把頁面渲染出來。步驟如下:

  1. 打開 WEB,加載基本資源,如 CSS,JS 等;
  2. 發起一個 Ajax 請求再到服務端請求數據,同時展示 Loading;
  3. 得到 Json 格式的數據後再根據邏輯選擇模板渲染出 DOM 字符串;
  4. 將 DOM 字符串插入頁面中渲染出 DOM 結構;

然而,在這種架構下,還是存在明顯的弊端的。最明顯的有如下幾點:

  1. JS 存在大量冗餘,在業務複雜的情況下,頁面的渲染部分的代碼,非常複雜;
  2. 在 Json 返回的數據量比較大的情況下,渲染的十分緩慢,會出現頁面卡頓的情況;
  3. 資源消耗嚴重,在業務複雜的情況下,一個頁面可能要發起多次 HTTP 請求才能將頁面渲染完畢。PC 端建立多次 HTTP 請求也沒啥。這裏需要考慮一下移動端的感受。

該時期代表:SSM(Spring + SpringMVC + Mybatis)和 SSH(Spring + Struts2 + Hibernate)

分離

在前後端分離的應用模式中,後端僅返回前端所需的數據,不再渲染 HTML 頁面,不再控制前端的效果。至於前端用戶看到什麼效果,從後端請求的數據如何加載到前端中,都由前端自己決定,網頁有網頁的處理方式,App 有 App 的處理方式,但無論哪種前端,所需的數據基本相同,後端僅需開發一套邏輯對外提供數據即可。

瀏覽器不再直接請求 JSP 的 API,而是:

  1. 瀏覽器請求服務器端的 NodeJS;
  2. NodeJS 再發起 HTTP 去請求後端;
  3. 後端依然原樣 API 輸出 JSON 給 NodeJS;
  4. NodeJS 收到 JSON 後再渲染出 HTML 頁面;
  5. NodeJS 直接將 HTML 頁面 flush 到瀏覽器;

這樣,瀏覽器得到的就是普通的 HTML 頁面,而不用再發 Ajax 去請求服務器了。

該時期代表:VueJS、AngularJS、ReactJS

總結

從經典的 Servlet + Jsp + JavaBean 的 MVC 時代,到 SSM(Spring + SpringMVC + Mybatis)和 SSH(Spring + Struts2 + Hibernate)的 Java 框架時代,再到前端框架(VueJS、AngularJS、ReactJS)爲主的 MVVM 時代,然後是 Nodejs 引領的全棧時代,技術和架構一直都在進步。創新之路不會止步,無論是前後端分離模式還是其他模式,都是爲了更方便地解決需求,但它們都只是一個“中轉站”。前端項目與後端項目是兩個項目,放在兩個不同的服務器,需要獨立部署,兩個不同的工程,兩個不同的代碼庫,不同的開發人員。前端只需要關注頁面的樣式與動態數據的解析及渲染,而後端專注於具體業務邏輯。

  • 前後端技術分離,可以由各自的專家來對各自的領域進行優化,這樣前端的用戶體驗優化效果更好。
  • 前後端分離模式下,前後端交互界面更清晰,就剩下了接口模型,後端的接口簡潔明瞭,更容易維護。
  • 前端多渠道集成場景更容易實現,後端服務無需變更,採用統一的數據和模型,可以支持多個前端:例如:微信 h5 前端、PC 前端、安卓前端、IOS 前端。

無狀態服務

對於無狀態服務,首先說一下什麼是狀態:如果一個數據需要被多個服務共享,才能完成一筆交易,那麼這個數據被稱爲狀態。進而依賴這個“狀態”數據的服務被稱爲有狀態服務,反之稱爲無狀態服務。

這個無狀態服務原則並不是說在微服務架構裏就不允許存在狀態,表達的真實意思是要把有狀態的業務服務改變爲無狀態的計算類服務,那麼狀態數據也就相應的遷移到對應的“有狀態數據服務”中。

場景說明:例如我們以前在本地內存中建立的數據緩存、Session 緩存,到現在的微服務架構中就應該把這些數據遷移到分佈式緩存中存儲,讓業務服務變成一個無狀態的計算節點。遷移後,就可以做到按需動態伸縮,微服務應用在運行時動態增刪節點,就不再需要考慮緩存數據如何同步的問題。

也就是對同一個 url 請求沒有上下文關係。舉個生活中的例子:

比如空調遙控器,你按上下調整溫度時,空調溫度設定值會變化,遙控器信號到空調是單向傳輸。現在空調顯示溫度 20 度,遙控器 20 度。如果遙控器與空調之間是有狀態的,假設你離開空調接收範圍調整了遙控器溫度,變成 19,那回到範圍內你按一次升高一度,基於原先溫度狀態,遙控器給空調發送一個“提高1度”的指令,就會出現遙控器提高到 20,而空調變成21。如果要空間與空調之前是無狀態的,假設你離開空調接收範圍調整了遙控器溫度,變成 19,那回到範圍內你按一次升高一度,遙控器給空調發送一個“設定溫度值20”,這樣兩者最終還是相同的值。

Restful 通信風格

基於**“無狀態通信原則”**,在這裏我們直接推薦一個實踐優選的 Restful 通信風格 ,因爲他有很多好處:

  • 無狀態協議 HTTP,具備先天優勢,擴展能力很強。例如需要安全加密時,有現成的成熟方案 HTTPS 可用。
  • JSON 報文序列化,輕量簡單,人與機器均可讀,學習成本低,搜索引擎友好。
  • 語言無關,各大熱門語言都提供成熟的 Restful API 框架,相對其他的一些 RPC 框架生態更完善。

CAP 原則與 BASE 理論

CAP 原則

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

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

特性 定理
Consistency 一致性,也叫做數據原子性,系統在執行某項操作後仍然處於一致的狀態。在分佈式系統中,更新操作執行成功後所有的用戶都應該讀到最新的值,這樣的系統被認爲是具有強一致性的。等同於所有節點訪問同一份最新的數據副本。
Availability 可用性,每一個操作總是能夠在一定的時間內返回結果,這裏需要注意的是"一定時間內"和"返回結果"。一定時間內指的是在可以容忍的範圍內返回結果,結果可以是成功或者是失敗,且不保證獲取的數據爲最新數據。
Partition tolerance 分區容錯性,分佈式系統在遇到任何網絡分區故障的時候,仍然能夠對外提供滿足一致性和可用性的服務,除非整個網絡環境都發生了故障。

取捨策略

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

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

總結

現如今,對於多數大型互聯網應用的場景,主機衆多、部署分散,而且現在的集羣規模越來越大,節點只會越來越多,所以節點故障、網絡故障是常態,因此分區容錯性也就成爲了一個分佈式系統必然要面對的問題。那麼就只能在 C 和 A 之間進行取捨。但對於傳統的項目就可能有所不同,拿銀行的轉賬系統來說,涉及到金錢的對於數據一致性不能做出一絲的讓步,C 必須保證,出現網絡故障的話,寧可停止服務,可以在 A 和 P 之間做取捨。而互聯網非金融項目普遍都是基於 AP 模式。

總而言之,沒有最好的策略,好的系統應該是根據業務場景來進行架構設計的,只有適合的纔是最好的。

BASE 理論

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

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

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

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

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

Basically Available(基本可用)

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

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

Soft state(軟狀態)

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

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

Eventually consistent(最終一致性)

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

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

總結

總的來說,BASE 理論面向的是大型高可用可擴展的分佈式系統,和傳統事務的 ACID 是相反的,它完全不同於 ACID 的強一致性模型,而是通過犧牲強一致性來獲得可用性,並允許數據在一段時間是不一致的。

微服務架構帶來的問題

客戶端如何訪問服務?

傳統的開發方式,所有的服務都是本地的,客戶端可以直接調用,現在按功能拆分成獨立的服務,客戶端如何訪問?

後臺有 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 網關更專注於安全、流量、路由等問題。

服務調用

在微服務架構中,通常存在多個服務之間的遠程調用的需求。目前主流的遠程調用技術有基於 HTTP 的 RESTful 接口和基於 TCP 的 RPC 協議。以上兩種都屬於同步通信,還有基於隊列模式的異步通信。

  • REST(Representational State Transfer):一種 HTTP 調用的格式,更標準,更通用,無論哪種語言都支持 http 協議。
  • RPC(Remote Promote Call):一種進程間通信方式,允許像調用本地服務一樣調用遠程服務。RPC 框架的主要目標就是讓遠程服務調用更簡單、透明。RPC 框架負責屏蔽底層的傳輸方式、序列化方式和通信細節。開發人員在使用的時候只需要瞭解誰在什麼位置提供了什麼樣的遠程服務接口即可,並不需要關心底層通信細節和調用過程。

比較項 REST RPC
通訊協議 HTTP 一般使用 TCP
性能 略低 較高
靈活度
應用 微服務架構 SOA 架構

服務治理

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

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

負載均衡

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

負載均衡策略

輪詢策略

實現原理:輪詢策略表示每次都順序取下一個 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 在倫敦的微服務大會上提出了四種解決方案:

單點登錄(SSO)

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

分佈式 Session 方案

分佈式會話方案原理主要是將關於用戶認證的信息存儲在共享存儲中,且通常由用戶會話作爲 Key 來實現的簡單分佈式哈希映射。當用戶訪問微服務時,用戶數據可以從共享存儲中獲取。這種方案的缺點在於共享存儲需要一定保護機制,因此需要通過安全鏈接來訪問,這時解決方案的實現就通常具有相當高的複雜性了。

客戶端 Token 方案

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

客戶端 Token 與 API 網關結合

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

總結

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

JWT 更加輕巧,在微服務之間進行認證&鑑權已然足夠,並且可以避免和身份認證服務直接打交道。當然,從能力實現角度來說,類似於分佈式 Session 在很多場景下也是完全能滿足需求,具體怎麼去選擇鑑權方案,還是要結合實際的需求來。

微服務架構技術支持

Spring Cloud

  • 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:阿里巴巴開源產品,一個易於使用的高性能微服務分佈式事務解決方案。
  • Spring Cloud Alibaba OSS:阿里雲對象存儲服務(Object Storage Service,簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。您可以在任何應用、任何時間、任何地點存儲和訪問任意類型的數據。
  • Spring Cloud Alibaba SchedulerX:阿里中間件團隊開發的一款分佈式任務調度產品,提供秒級、精準、高可靠、高可用的定時(基於 Cron 表達式)任務調度服務。
  • Spring Cloud Alibaba SMS:覆蓋全球的短信服務,友好、高效、智能的互聯化通訊能力,幫助企業迅速搭建客戶觸達通道。

其他大哥

  • RibbitMQ:RabbitMQ 是部署最廣泛的開源消息中間件。是實現了高級消息隊列協議(AMQP)的開源消息中間件。
  • Kafka:Kafka 是由 Apache 軟件基金會開發的一個開源流處理平臺,由Scala和Java編寫。Kafka 是一種高吞吐量的分佈式發佈訂閱消息系統。
  • Redis:Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用 ANSI C 語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value 數據庫,並提供多種語言的 API。
  • MongoDB:MongoDB 是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。它支持的數據結構非常鬆散,是類似 json 的 bson 格式,因此可以存儲比較複雜的數據類型。
  • Elasticsearch:Elasticsearch 是一個基於 Lucene 的搜索服務器。它提供了一個分佈式多用戶能力的全文搜索引擎,基於 RESTful web 接口。Elasticsearch 是最受歡迎的企業搜索引擎,其次是 Apache Solr,也是基於 Lucene。
  • MySQL:MySQL 是一種開放源代碼的關係型數據庫管理系統(RDBMS),免費、簡單、佔資源少、強大好用。
  • Oracle:世界上最昂貴的數據庫,一般金融系統使用居多。
  • FastDFS:FastDFS是一個開源的輕量級分佈式文件系統,它對文件進行管理,功能包括:文件存儲、文件同步、文件訪問(文件上傳、文件下載)等,解決了大容量存儲和負載均衡的問題。特別適合以文件爲載體的在線服務,如相冊網站、視頻網站等等。
  • HDFS:Hadoop 生態組件,可以支持千萬級的大型分佈式文件系統。
  • XX-JOB:輕量級分佈式任務調度平臺,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼並接入多家公司線上產品線,開箱即用。
  • TX-LCN:分佈式事務解決防範,LCN 並不生產事務,LCN 只是本地事務的搬用工(事務的協調工)。LCN 是一個高性能的分佈式事務框架,兼容 Dubbo、Spring Cloud,支持 RPC 框架拓展,支持各種 ORM 框架、NoSQL、負載均衡、事務補償。
  • Zipkin:Twitter 公司開發貢獻的一款開源的分佈式實時數據追蹤系統(Distributed Tracking System),基於 Google Dapper 的論文設計而來,其主要功能是聚集各個異構系統的實時監控數據。
  • Skywalking:Apache Skywalking 是一個開源的,用於收集、分析,聚合,可視化來自於不同服務和本地基礎服務的數據的可觀察的平臺。特別爲分佈式系統而設計的數據觀察和監控系統。
  • Apollo:攜程框架部門研發的分佈式配置中心,能夠集中化管理應用不同環境、不同集羣的配置,配置修改後能夠實時推送到應用端,並且具備規範的權限、流程治理等特性,適用於微服務配置管理場景。
  • ConfigKeeper:隨行付架構部基於 Spring Cloud 研發的分佈式配置中心。與 Spring Boot、Spring Cloud 應用無縫兼容。
  • JWT:JSON Web Token(JWT)是一個非常輕巧的規範。這個規範允許我們使用 JWT 在用戶和服務器之間傳遞安全可靠的信息。
  • Nginx:Nginx 是一款輕量級的 Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,其特點是佔有內存少,併發能力強,中國大陸使用 Nginx 網站用戶有:百度、淘寶、騰訊、京東、新浪、網易等。
  • Git:開源的分佈式版本控制系統,可以有效、高速地處理從很小到非常大的項目版本管理。
  • Docker:Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然後發佈到任何流行的 Linux 或 Windows 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何接口。
  • Kubernetes:Kubernetes,簡稱 k8s,是用 8 代替 8 個字符“ubernete”而成的縮寫。Kubernetes 脫胎於 Google 的 Borg 系統,是一個開源的功能強大的容器編排系統,用於管理雲平臺中多個主機上的容器化的應用,實現了容器集羣的自動化部署、擴容以及運維的開源平臺。Kubernetes 的目標是讓部署容器化的應用簡單並且高效。

本文采用 知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議

大家可以通過 分類 查看更多關於 Spring Cloud 的文章。


🤗 您的點贊轉發是對我最大的支持。

📢 掃碼關注 哈嘍沃德先生「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~

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