近年來,微服務在互聯網應用開發和部署層面已經很是流行,而在此以前的至關長的一段時間裏,市場上都流行笨重的單體的應用。
隨着近年來互聯網應用和需求爆發式的增加,快速迭代,高併發,高業務複雜度也是開發人員須要面臨的難題。同時,服務器技術也迅速革新,
微服務,雲計算,容器管理,負載均衡,持續集成等技術的興起,也改變了最初的開發模式。微服務架構已經成爲了一種趨勢,應用開發或者重構成微服務,經過API的方式來交互,使得應用開發變得快捷且容易管理,能夠更快更高效地部署。
相較於單體應用,應用程序設計爲微服務,能夠更加容易在具備負載均衡的服務器集羣上平穩運轉,可以輕鬆應對時間敏感度較高的互聯網需求高峯,以及軟硬件故障致使的宕機事件。
使人痛苦的"單體噩夢"
在傳統開發模式下,咱們都會簡單實現一個應用,這個應用包含了全部模塊功能,通過多年的開發和迭代以後,應用會變得
很臃腫,依賴多,邏輯分支多,逐漸變成一個複雜而龐大的單體。
-
首先,這會讓開發人員陷入一個很是痛苦的境地,不只僅在重構和新業務開發上會有困難,就連應用啓動時間都變得冗長。
-
其次,全部模塊都發布在同一個應用裏,因爲不一樣模塊的職責不一樣,服務器CPU和內存的選型難以肯定。例若有模塊是計算密集型會須要高性能CPU,有些模塊是存儲型須要大內存,會
擠壓其餘模塊甚至其餘進程的剩餘
系統資源,爲了應對應用需求去購置高性能計算機,擴容,升級換代也意味着成本升高,是很不現實的。
-
同時,想要讓這種單體應用支持
持續部署,分佈式部署等。就比較麻煩了,由於只是修改應用其中一個模塊,可是
卻須要發佈整個應用。且發佈後是否會對其餘模塊產生影響也是未知的,須要
手工測試去跑完整個應用的case。
-
另外,單體應用的可靠性也難以保證,這些模塊都在同一個進程中,任何一個模塊出現bug,好比
cpu佔用率超標,內存泄露,都會拖垮
整個進程。
-
最後,單體應用的
可遷移性不佳,單體應用想要採用新的框架/中間件,也變得極爲困難,即便新框架的性能很是好,可是大量的歷史業務邏輯,想要
遷移就基本等於重建。
單體模型和微服務模型
舉個全局實例,好比一個"打車應用",主要有用戶端模塊,司機端模塊,支付模塊,訂單模塊,行程模塊等。前端
若是在單體應用當中,這些模塊都在一個應用裏就搞定了,傳統思惟,只須要一個應用,一個數據訪問層,一個數據庫,就能夠在此基礎上進行全部的開發了。
而在微服務架構裏,模塊職責拆分明確,模塊
單獨做爲一個應用,必要時,按照數據存儲需求給應用分配不一樣的數據庫。
接下來咱們對比和分析一下這兩種模型的實例表現
該模型是典型的模塊化六邊形架構的模型,至少作了模塊化,有統一的REST入口,已是單體應用中表現比較好的種類了。
應用核心是有核心業務服務,領域對象和消息事件等,同時伴隨着UI組件和外部接口適配器。
儘管有了完善的邏輯化模型,可是應用仍是須要做爲一個單體應用進行打包部署,獨立部署到服務器上時,咱們就將面臨"單體噩夢"中提到的全部弊端。
咱們用如今流行的微服務架構模式去代替臃腫的單體應用,思路是經過
業務拆分,將每一個有本身特定的功能的模塊都做爲一個微服務,每一個微服務
單獨部署,而且各個微服務之間可以
互聯。例如將乘客管理,訂單管理等等業務模塊做爲單獨的服務,每一個服務有本身的REST訪問入口,供其餘服務調用。
微服務架構:「噩夢」的救世主
分析
實例中,咱們已經將應用拆分爲用戶管理,帳單,用戶UI,司機管理,支付,司機UI,行程管理,通知等多個微服務,每個微服務都暴露了API供其餘微服務調用。例如乘客UI能夠經過REST API調用乘客管理,乘客管理又能夠經過REST API調用支付模塊,這樣就讓乘客業務流程完成,使相關微服務互聯了。同理司機也能調用支付模塊,甚至是通知。每一個業務流程能夠經過應用之間的
API調用完成本身的
閉環。這裏咱們還能夠注意到有個
API網關(Gateway),整個模塊裏,相關API是經過API網關暴露給移動端,移動端訪問API,就能訪問全部相關接口,對於移動端來講,這就實現了先後分離。
在模型中,大部分服務能夠做爲消費者,例如司機使用通知服務來告知司機有新的訂單,再例如乘客UI服務調用了訂單服務的數據來做爲渲染頁面的依據。
值得一提的是,服務間的通訊,可使用
響應式,註冊/訂閱式等異步手段,也可使用消息隊列。另外API網關(GateWay)不只僅是負責微服務的通訊中介,還負責
訪問控制,監控,埋點,日誌,負載均衡等功能。
關鍵詞
部署:爲了實現高可用,微服務通常使用
Docker部署,且每一個微服務通常部署
多個實例,每一個Docker承載一個實例。用戶請求時,使用
Nginx反向代理服務器,去分發請求到不一樣的實例去。所以,乘客,司機等模塊化的微服務的測試/發佈流程,就沒有關聯性,讓持續部署成爲可能。
分佈式:微服務能夠
解決複雜問題,將龐大的單體應用分解成一套包含多個子服務的體系,實現了
強制模塊化。這樣的好處是,子服務能夠被快速開發,而且
單一職責也便於維護。同時,分佈式部署也能很好地應對
高併發需求,減小部署開銷。例如,乘客模塊是併發量特別大的,所以也須要大量實例,而其餘模塊可能沒有很大的併發量。以往的單體服務,就須要根據最大需求量也就是乘客模塊的需求量去部署實例,而換作具備分佈式特性的微服務架構了之後,其餘模塊並
不須要去適配乘客模塊的實例部署量。
鬆耦合:微服務架構拆分了業務模型,影響到了應用和數據庫的關係,其實應用之間的耦合,也都是由於數據依賴形成的。以前的單體應用中,全部模塊能夠共用一個mysql數據庫。但到了微服務架構,都是分開部署的,就不得不將數據庫也拆分了,而且利用
數據冗餘,
解除掉單體數據庫中的
數據耦合。
例如以前的
乘客表Passenger(ID,NAME)
mysql
司機表Driver(ID,NAME)
sql
行程表Trip(ID,NAME,PID,DID)
數據庫
它們在同一個數據中,固然是能夠用PID和DID外鍵進行關聯。可是換作微服務部署後,這三張表實際上是分別部署到不一樣的服務器上的,這樣就無法使用傳統的外鍵進行關聯。因此要引進數據冗餘,好比在Passenger表和Driver表中,把他們相關的trip記錄,做爲json存入,變爲json
Passenger(ID,NAME,TRIP)
緩存
Driver(ID,NAME,TRIP)
服務器
這種作法和傳統的企業級關係型數據庫的數據模型相違背,甚至是
反範式的。
技術選型:上文得知,持久化數據庫咱們已經分開部署。每一個服務擁有本身的數據庫,咱們在這裏就能夠根據微服務的特性
選擇最適合該應用的
數據庫/持久化框架,好比乘客數據量比較大,咱們選擇能夠高效查詢Mysql做爲持久化數據庫,而假如訂單服務涉及大量查詢要求快速響應,咱們就能夠選擇Redis做爲存儲手段。
同理,根據不一樣需求,微服務能夠具備各類特性,也能夠驅動咱們選用的RPC策略,使用消息隊列,甚至引入搜索引擎。以此來達到性能的最大化。
獨立擴展:咱們以前說過單體應用的擴展,
受限於整個應用的
"長板定理",假如其中一個模塊功能須要更多的硬件指標來知足,那麼我須要對整個服務器進行換代。而換作微服務模式之後,每一個模塊獨立部署,咱們能夠依據各個微服務的特色來選擇服務器。例如,行程管理中,可能涉及大量的地理信息估測和預算,是一種計算密集型,咱們就能夠把行程管理單獨部署到CPU性能比較強的計算機上。訂單模塊,對內存要求比較高,那麼咱們就能夠部署在內存比較大的服務器上,且往後能夠根據訂單的體量
自由擴容/縮容。
微服務的不足
複雜度較高:因爲微服務是分佈式系統,總體會變得比較複雜,開發者須要去選擇基於消息或者RPC的進程間通訊機制。相較於進程內通訊,會顯得複雜一些,由於要處理各個微服務之間的因爲調用鏈產生的極端狀況,這其中就包括要
保證各個微服務都
高可用,若是不可用或者響應很是慢,怎麼作備選和降級措施。
網絡和高可用性要求高:微服務分佈式部署,是比較
分散的,若是各個核心功能的機房不在一個地方,網絡就會成爲
瓶頸因素或者隱患因素。好比核心訂單服務部署在上海,而支付服務部署在北京,這樣,網絡傳輸可能會成爲系統影響調用效率的一個重要因素。且各個地方的機房都有掉電宕機的風險,又部署了核心模塊,這就是很大的隱患。固然,能夠有容災備份的手段去緩解這種突發狀況,可是這又是另一個問題了。
分區數據庫架構:
分佈式事務在微服務中是很
難實現的,在單體應用中,只存在一個單獨的數據庫,事務很容易實現。可是在微服務中,通常不會選擇分佈式事務,根據CAP定理,數據一致性,可用性,和分區容錯性,只能三選二,要捨棄哪一個就顯得很痛苦。另外,分佈式事務根本不支持高度可擴展的NoSQL數據庫和消息代理。只能使用「最終一致性」的辦法來進行折中。
做業複雜度:微服務架構拆分出了不少小粒度的微服務,且部分微服務還要求多實例部署。這就給增長了埋點,配置,監控,負載均衡等做業的
工做量。與此同時,接口自動化測試、手工測試等任務量也相應增長。
延伸:和SOA的區別
其實兩種架構是比較相像的,都屬於分佈式組件化的結構,且都有鬆耦合的目標。網絡
SOA更注重集成複用性,強調服務的綜合治理,架構水平劃分爲前端,服務層,數據層。
微服務剔除了ESB企業服務總線,強調獨立部署組件化,架構垂直劃分,按照業務能力,每一個服務完成本身特定的功能,服務即產品。
功能
|
SOA
|
微服務
|
組件大小
|
大塊業務邏輯
|
單獨任務或小塊業務邏輯
|
耦合
|
一般鬆耦合
|
老是鬆耦合
|
公司架構
|
任何類型
|
小型、專一於功能交叉團隊
|
管理
|
着重中央管理
|
着重分散管理
|
目標
|
確保應用可以交互操做
|
執行新功能、快速拓展開發團隊
|
總結:迴歸
經過解讀了推動微服務架構演變的因素,以及微服務架構的優缺點,以及同類架構的橫向比較,咱們發現,微服務架構仍是有運用場景的範圍的,微服務比較適合業務比較複雜,模塊劃分多樣,且存在高併發,計算密集,存儲密集等多種類特性的場景。而簡單的小規模服務,其實單體應用更加適合。換句話說,就是不能濫用微服務。架構
其實現有技術發展,已經衍生出了不少和微服務架構配合度很高的技術,好比微服務的自動化部署,可以使用現成的平臺即服務(PaaS),亦可開發本身的
PaaS集羣方案,配合K8s和Docker的使用。固然還有高性能RPC框架,消息中間件等。
迴歸開頭拋出的問題,微服務架構的出現,仍是爲了迎合快速迭代的互聯網產品,架構只是一個基礎要素,要把產品作好,其實還有更多的環節,包括服務層面分佈式服務的高可用,監控,負載均衡。數據層面的數據冗餘方案,緩存方案,最終一致性方案。甚至是運維層面的DevOps,容災備份。產品一直在迭代,技術一直在革新,之後也許會有功能更強性能更好的架構出現,只要咱們的探索永不中止!
·end·
併發
技術學習,一塊兒進步
關注我,按期推送技術文章
![](http://static.javashuo.com/static/loading.gif)