一、信息技術的發展趨勢
信息技術從出現到逐漸成為主流,主要經歷了軟件、開源、雲三個階段的發展。從軟件到開源,再到雲,這也是信息技術的發展趨勢。
1. 軟件改變世界
縱觀人類社會漫長的發展歷史,農耕時代、工業時代與信息時代可謂是明顯的三個分水嶺,每個時代都會出現很多新興的領域,作為信息時代最重要的載體,互聯網越來越成為當今社會關注的焦點,互聯網的基石之一——軟件,正在迅速地改變着這個世界。
2. 開源改變軟件
隨着軟件行業的成熟,相比於“重復造輪子”,“站在巨人的肩膀上”明顯可以更加容易和快速地創造出優秀的新產品。隨着開源文化越來越被認可,以及社區文化越來越成熟,使用優秀的開源產品作為基礎架構來快速搭建系統以實現市場戰略,成為當今最優的資源配比方案。
3. 雲吞噬開源
僅通過開源產品搭建並運維一個高可用、高度彈性化的平台,進而實現互聯網近乎100%的可用性,難度可想而知。因此,在提供技術思路的同時,進一步提供整套雲解決方案以保證不斷擴展的非功能需求,便成了當今新一代互聯網平台的追求。
隨着用戶集群規模的進一步加大,單純的分布式系統已經難以駕馭,因此技術圈開啟了一個概念爆發的時代——SOA、DevOps、容器、CI/CD、微服務、Service Mesh等概念層出不窮,而 Docker、Kubernetes、Mesos、Spring Cloud、Istio 等一系列產品的出現,標志着雲時代已真正到來。
二、互聯網架構的核心問題
1. 海量用戶
當今的互聯網大潮,已經越來越難以估算用戶量以及由此產生的自然數據增長有多少了,區別於我們日常的生活(例如商場,僅有 10 個人和有 1000 人的購物體驗是明顯不同的),企業如何做到無差別地為全世界所有的用戶提供服務,成了一道難題。
2. 產品迅速迭代
面對當今快速增長的業務和需求,敏捷開發成為了熱門的選擇。在不斷迭代的過程中,時間成本就顯得尤為重要。如何敏捷地探知市場需求並將其實現,是互聯網行業的立命之本。產品快速升級必然會推動、測試、交付甚至系統迅速迭代。
3. 7x24 小時不間斷服務
我們要保證應用全天候不間斷的可用,必須要考慮到隨時可能發生的意外,例如光纜挖斷、機房失火等,每一次宕機都可能會造成巨大的損失。另外,如果系統設計得不夠健壯,對其升級和維護時就要停止服務。頻繁的系統升級同樣會對系統可用性產生很大的影響。
4. 流量突增
流量突增分為可預期型徒增和不可預期型徒增,像促銷活動、有計划的熱點事件等引起的流量突增屬於前者,可以通過提前擴容、預案演練等方式精心為這些流量突增准備應對方案。而意料之外的熱點事件(如地震)往往事發突然,系統來不及准備應對措施,因此若系統本身的可用性、彈性等非功能需求十分成熟,便可以在某種程度上應對這種突增。
5. 業務組合復雜
很多互聯網公司都是跨界巨頭,我們知道,即使不跨界,在單一領域編織一個大規模的成型業務系統也並不簡單。
三、單體架構與微服務架構
1. 單體架構
單體架構比較初級,典型的三級架構,前端(Web/手機端)+中間業務邏輯層+數據庫層。這是一種典型的 MVC 框架的應用。
單體架構的應用比較容易部署、測試, 在項目的初期,單體應用可以很好地運行。然而,隨着需求的不斷增加, 越來越多的人加入開發團隊,代碼庫也在飛速地膨脹。慢慢地,單體應用變得越來越臃腫,可維護性、靈活性逐漸降低,維護成本越來越高。下面是單體架構應用的一些缺點:
-
復雜性高: 以一個百萬行級別的單體應用為例,整個項目包含的模塊非常多、模塊的邊界模糊、 依賴關系不清晰、 代碼質量參差不齊、 混亂地堆砌在一起。可想而知整個項目非常復雜。 每次修改代碼都心驚膽戰, 甚至添加一個簡單的功能, 或者修改一個 Bug 都會帶來隱含的缺陷。
-
技術債務: 隨着時間推移、需求變更和人員更迭,會逐漸形成應用程序的技術債務, 並且越積 越多。“ 不壞不修”, 這在軟件開發中非常常見, 在單體應用中這種思想更甚。 已使用的系統設計或代碼難以被修改,因為應用程序中的其他模塊可能會以意料之外的方式使用它。
-
部署頻率低: 隨着代碼的增多,構建和部署的時間也會增加。而在單體應用中, 每次功能的變更或缺陷的修復都會導致需要重新部署整個應用。全量部署的方式耗時長、 影響范圍大、 風險高, 這使得單體應用項目上線部署的頻率較低。 而部署頻率低又導致兩次發布之間會有大量的功能變更和缺陷修復,出錯率比較高。
-
可靠性差: 某個應用Bug,例如死循環、內存溢出等, 可能會導致整個應用的崩潰。
-
擴展能力受限: 單體應用只能作為一個整體進行擴展,無法根據業務模塊的需要進行伸縮。例如,應用中有的模塊是計算密集型的,它需要強勁的CPU; 有的模塊則是IO密集型的,需要更大的內存。 由於這些模塊部署在一起,不得不在硬件的選擇上做出妥協。
-
阻礙技術創新: 單體應用往往使用統一的技術平台或方案解決所有的問題, 團隊中的每個成員 都必須使用相同的開發語言和框架,要想引入新框架或新技術平台會非常困難。
2. 分布式架構
中級架構,分布式應用,中間層分布式 + 數據庫分布式,是單體架構的並發擴展,將一個大的系統划分為多個業務模塊,業務模塊分別部署在不同的服務器上,各個業務模塊之間通過接口進行數據交互。數據庫也大量采用分布式數據庫,如 Redis、Elasticsearch、Solor 等。通過 LVS/Nginx 代理應用,將用戶請求均衡的負載到不同的服務器上。
該架構相對於單體架構來說,這種架構提供了負載均衡的能力,大大提高了系統負載能力,解決了網站高並發的需求。另外還有以下特點:
-
降低了耦合度: 把模塊拆分,使用接口通信,降低模塊之間的耦合度。
-
責任清晰: 把項目拆分成若干個子項目,不同的團隊負責不同的子項目。
-
擴展方便: 增加功能時只需要再增加一個子項目,調用其他系統的接口就可以。
-
部署方便: 可以靈活的進行分布式部署。
-
提高代碼的復用性: 比如 service 層,如果不采用分布式 REST 服務方式架構就會在手機 wap 商城,微信商城,PC,Android,IOS 每個端都要寫一個 service 層邏輯,開發量大,難以維護一起升級,這時候就可以采用分布式 REST 服務方式,公用一個 service 層。
缺點: 系統之間的交互要使用遠程通信,接口開發增大工作量,但是利大於弊。
3. 微服務架構
微服務架構,主要是中間層分解,將系統拆分成很多小應用(微服務),微服務可以部署在不同的服務器上,也可以部署在相同的服務器不同的容器上。當應用的故障不會影響到其他應用,單應用的負載也不會影響到其他應用,其代表框架有 Spring cloud、Dubbo 等。
-
易於開發和維護: 一個微服務只會關注一個特定的業務功能,所以它業務清晰、代碼量較少。 開發和維護單個微服務相對簡單。而整個應用是由若干個微服務構建而成的,所以整個應用也會被維持在一個可控狀態。
-
單個微服務啟動較快: 單個微服務代碼量較少, 所以啟動會比較快。
-
局部修改容易部署: 單體應用只要有修改,就得重新部署整個應用,微服務解決了這樣的問題。 一般來說,對某個微服務進行修改,只需要重新部署這個服務即可。
-
技術棧不受限: 在微服務架構中,可以結合項目業務及團隊的特點,合理地選擇技術棧。例如某些服務可使用關系型數據庫MySQL;某些微服務有圖形計算的需求,可以使用Neo4j;甚至可根據需要,部分微服務使用Java開發,部分微服務使用Node.js開發。
微服務雖然有很多吸引人的地方,但它並不是免費的午餐,使用它是有代價的。使用微服務架構面臨的挑戰。
-
運維要求較高: 更多的服務意味着更多的運維投入。在單體架構中,只需要保證一個應用的正常運行。而在微服務中,需要保證幾十甚至幾百個服務服務的正常運行與協作,這給運維帶來了很大的挑戰。
-
分布式固有的復雜性: 使用微服務構建的是分布式系統。對於一個分布式系統,系統容錯、網絡延遲、分布式事務等都會帶來巨大的挑戰。
-
接口調整成本高: 微服務之間通過接口進行通信。如果修改某一個微服務的API,可能所有使用了該接口的微服務都需要做調整。
-
重復勞動: 很多服務可能都會使用到相同的功能,而這個功能並沒有達到分解為一個微服務的程度,這個時候,可能各個服務都會開發這一功能,從而導致代碼重復。盡管可以使用共享庫來解決這個問題(例如可以將這個功能封裝成公共組件,需要該功能的微服務引用該組件),但共享庫在多語言環境下就不一定行得通了。
三、什么是微服務
“微服務”與“微服務架構”有着本質的區別: “微服務”強調的是服務的大小,它關注的是某一個點。而“微服務架構”則是一種架構思想,需要從整體上對軟件系統進行通盤的考慮。
微服務架構就是將一個完整的應用從數據存儲開始水平/垂直拆分成多個不同的服務。每個服務都能獨立部署、獨立維護、獨立擴展,各服務之間通過諸如RESTful API(http)的方式互相調用。即微服務是自理自治的服務單元。
說明:拆分角度有垂直拆分/水平拆分。
水平拆分:按照業務對系統進行划分。舉個例子,原系統包括了運營和支付,現水平拆分為運營系統和支付系統。優點是:不同業務,往往性能要求,以及請求量是不一樣的。拆分后保證業務之間的可用性影響最小化。
垂直拆分:將同樣的系統按照應用場景(調用方)進行拆分 。舉個例子,原系統的支付場景中包括了用戶支付,第三方調用 支付,現垂直拆分為用戶支付,商戶支付。優點:各個垂直服務調用之間相互不影響,自理自治;通過配置可以進行上游調用降級等。
為了解決單體應用的諸多問題,我們提出了分布式的概念,通過將單體應用拆分成諸多單獨的模塊來降低耦合以及提升系統性能,其實這里就涉及到一個服務化的概念,而微服務與之不同的是:
- 服務拆分粒度更細。微服務可以說是更細維度的服務化,小到一個子子模塊,只要該模塊依賴的資源與其他模塊都沒有關系,那么就可以拆分成一個微服務。
- 服務獨立部署。每個服務都嚴格遵循獨立打包部署的准則,互不影響。比如一台物理機上可以部署多個 Docker 實例,每個 Docker 實例可以部署一個微服務的代碼。
- 服務獨立維護。每個微服務都可以交由一個小團隊甚至個人來開發、測試、發布和運維,並對整個生命周期負責。
- 服務治理能力要求高。因為拆分為微服務之后,服務的數量變多,因此需要有統一的服務治理平台,來對各個服務進行管理。
盡管微服務和微服務架構有所不同,但我們通常也可以簡單理解為:
微服務是一種軟件架構風格,它是以專注於單一責任與功能的小型功能區塊為基礎,利用模組化的方式組合出復雜的大型應用程序,各功能區塊使用與語言無關的 API(例如 REST)集相互通訊,且每個服務可以被單獨部署,它具備以下三個核心特點:
- 微服務為大型系統而生。隨着業務的快速增長,會帶來系統流量壓力和復雜度的上升,系統的可維護性和可擴展性成為架構設計的主要考慮因素,微服務架構設計理念通過小而美的業務拆分,通過分而自治來實現復雜系統的優雅設計實現。
- 微服務架構是面向結果的。微服務架構設計風格的產生並非是出於學術或為標准而標准的設計,而是在軟件架構設計領域不斷演進過程中,面對實際工業界所遇到問題,而出現的面向解決實際問題的架構設計風格。
- 專注於服務的可替代性來設計。微服務架構設計風格核心要解決的問題之一便是如何便利地在大型系統中進行系統組件的維護和替換,且不影響整體系統穩定性。
四、微服務本質
微服務,關鍵其實不僅僅是微服務本身,而是系統要提供一套基礎的架構,這種架構使得微服務可以獨立的部署、運行、升級,不僅如此,這個系統架構還讓微服務與微服務之間在結構上“松耦合”,而在功能上則表現為一個統一的整體。這種所謂的“統一的整體”表現出來的是統一風格的界面,統一的權限管理,統一的安全策略,統一的上線過程,統一的日志和審計方法,統一的調度方式,統一的訪問入口等等。
微服務的目的是有效的拆分應用,實現敏捷開發和部署 。
微服務提倡的理念團隊間應該是 inter-operate, not integrate 。inter-operate是定義好系統的邊界和接口,在一個團隊內全棧,讓團隊自治,原因就是因為如果團隊按照這樣的方式組建,將溝通的成本維持在系統內部,每個子系統就會更加內聚,彼此的依賴耦合能變弱,跨系統的溝通成本也就能降低。