阿里巴巴前架構師 360 度無死角剖析微服務

微服務是當前軟件架構領域很是熱門的詞彙,在社區中也有不少熱烈的討論。所以,在 OSC 第 130 期高手問答中,咱們策劃的主題是「究竟什麼纔是微服務」,並邀請了黃勇做爲高手嘉賓。前端

黃勇,現任特贊公司 CTO,曾任阿里巴巴公司系統架構師。對微服務架構與大數據技術有深刻研究,具備豐富的網站架構設計經驗與項目管理經驗,擅長敏捷開發模式。國內開源軟件推進者之一,活躍於「開源中國」社區網站,Smart 開源框架創始人,圖書《架構探險:從零開始寫Java Web框架》、《輕量級微服務架構(上冊)》做者。熱愛技術交流,樂於分享本身的工做經驗與生活感悟。數據庫

微服務是近年來備受關注的話題,它的出現讓咱們想起了十年前的 SOA(Service-Oriented Architecture,面向服務架構),但它比傳統的 SOA 更容易理解,也更容易實踐,它將「面向服務」的思想作得更加完全。小程序

尤爲是當國外的一些知名技術公司成功實踐了微服務之後,這股熱潮就吹遍了國內的大街小巷,咱們也看到不少的項目使用了微服務,但實際上依然有很多朋友對於微服務有着很多疑惑。後端

所以本篇文章,會介紹與微服務架構相關的一些基礎概念、適用場景以及如何解決在實踐中遇到的問題等內容。微信小程序

1、與微服務相關的一些基本概念

我之前作過微服務,基本框架是 Spring MVC,微服務之間和微服務與平臺之間的訪問是經過在 Zookeeper 上的 Dubbo 通信的,請問這算是微服務嗎?緩存

其實微服務架構的範圍是至關廣的,這些我認爲只是微服務架構的一部分。服務器

如何更好理解【微服務】這個「微」字。從設計之初,開發,部署,運維,監控,等有什麼地方(基於你的過往歷程)須要關注的?微信

我認爲「微」並不是它的體積足夠小,而是它的責任足夠單一,不少人誤解了「微」的真實含義,認爲服務拆分得足夠小就是微服務了,其實並不是這樣。此外,「微」還有「微不足道」的意思,也就是說,某個服務出現故障,它不會影響整個系統。網絡

據說微服務是個很大的概念,Dubbo 只是實現了其中一小部分,請問完善的微服務架構是什麼樣的?Spring Cloud 是否算是完善的微服務?session

微服務架構的範圍比較大,Dubbo 和 Spring Cloud 都只是解決了微服務的一部分問題,並未徹底覆蓋。

若是分佈式服務原本拆分的顆粒度就比較細,每個模塊都是獨立的服務,可不可就理解爲至關於微服務?

微服務並不是細粒度服務的組合,也就是說,粒度要細到什麼程度,這取決於對業務功能的把控能力。此外,微服務是一種架構思想,包括看得見的微服務,還包括看不見的基礎設施和自動化技術做爲支撐。

請問微服務的核心繫統是什麼?是微服務的發現和組織嗎?每一個微服務很好作,如何把他們組合起來,有沒有現成的系統能夠參考?

  1. 我認爲微服務的核心是:服務註冊中心(Service Registry)與服務網關(Service Gateway),它們配合完成服務註冊與服務發現。
  2. 將服務組合起來也成爲「服務編排」,有多重作法,能夠在服務網關中進行編排,也能夠經過中間服務進行編排,我更傾向於後者,這樣確保服務網關不包含任何業務,更加輕量級。

微服務比普通架構須要多作那些工做?OpenStack 的架構設計屬於什麼類型?微服務是否是須要更多的運行資源?

  1. 微服務架構比傳統架構更加依賴於對自動化運維的支持。
  2. OpenStack 是一款雲計算平臺,爲雲計算的 IaaS 層提供瞭解決方案。
  3. 在微服務架構中,須要相關的基礎設施與不少獨立運行的服務,我認爲相比較傳統架構而言,所消耗的硬件資源較高一些。但從如今來看,硬件資源的成本已經很是低了。

SOA、WebService、RESTful 這些概念有什麼本質的區別。開發者日常使用的那些 AJAX、HTTP 接口(含 session 狀態的)算得上 RESTful 接口嗎?

  1. RESTful 是一種架構風格,SOA 是一種架構思想,能夠認爲 RESTful 有助於 SOA 的落地化。
  2. RESTful 通常應用在 HTTP 協議上,在先後端分離架構中,前端經過 AJAX 技術發送 RESTful HTTP 請求到後端,獲取後端 JSON 數據,並進行界面渲染。一樣,RESTful 也用於微服務架構中,每一個服務對外暴露 REST API 做爲通訊接口。

從什麼角度能區分出或者劃分微服務和 RPC 分佈式之間的區別或者關係?

微服務是一種應用架構模式,而 RPC 是一種遠程調用方式,它們是不同的概念;而在微服務中會出現服務之間的調用,爲了確保性能,咱們通常採用 RPC 來調用。

是否有接觸過「領域驅動的分析與設計方法(DDD)」,你是如何理解「DDD」與「微服務」之間關係的?

DDD 是基於領域對象的設計思想,微服務是基於服務的業務架構,DDD 與微服務可相輔相成。

公司如今用的是 Dubbo 框架,這是微服務框架仍是 SOA?記得有些博客說微服務去中心化,那這個中心是否是就是 Dubbo 裏的註冊中心?

  1. Dubbo 從本質上來說屬於微服務框架,它有服務註冊與發現,也有服務之間不一樣協議的通訊,以及服務調用的監控。而傳統的 SOA 更傾向於使用 ESB 這類總線的方式來實現服務的註冊與通訊,能夠把 ESB 當作是一箇中心,所以相對微服務而言,傳統 SOA 更加劇量級一些。我認爲微服務是 SOA 的一種輕量級實現,它的本質仍是 SOA。
  2. 所謂去中心化,其實是確保不由於中心而致使單點故障,若是能解決這個問題,有中心又如何呢?所以,我認爲不要一味地去中心化,要合理地去中心化纔是正道。

2、什麼場景下選擇微服務?

微服務架構我以爲比較適合新項目,若是用於已有項目那至關於要重構,或者逐步拆分作微服務架構?是否是這樣?仍是有什麼更好的方法?

  1. 對於業務流程較爲複雜,且業務會變得逐漸複雜的項目,能夠考慮使用微服務架構。
  2. 對於已有項目而言,可考慮逐步進行微服務化,也可考慮在新業務中使用微服務架構。

我想利用微服務實現系統的模塊化,便於公共模塊複用和水平擴展,但目前的系統規模其實都很小,這種狀況是否是不適合使用微服務?

我認爲微服務架構用於業務較複雜或目前業務簡單但未來有可能變得複雜的架構,建議視具體狀況來肯定合理的架構,不要爲了微服務而去微服務。

高併發低延遲的系統能使用微服務嗎?

我認爲高併發場景不太適合使用微服務,由於微服務會帶來一些調用鏈的開銷,高併發場景須要作到儘量地的延遲以及更高效的通信。

微服務與 SOA 到底有什麼區別,各自的應用場景是什麼?到底在什麼樣的狀況才適合使用微服務架構?

我認爲微服務是 SOA 的輕量級解決方案,微服務的本質仍是 SOA,只是更加容易落地而已。

我認爲在如下幾種狀況下,可考慮使用微服務架構:

  • 應用變得愈來愈大時
  • 項目存在多種開發語言時
  • 感受到經典架構模式過重時
  • 修改了一個 bug 須要平滑升級時
  • 想對系統進行細粒度監控時

固然還有其餘使用場景,但微服務不是萬靈丹,不能適用於全部場景。並且微服務對運維是有必定的要求的,尤爲是自動化運維。即使業務目前比較簡單,但未來會變得複雜,也建議使用微服務架構。

3、如何考量微服務的技術選型?

微服務的開源技術選型能介紹幾種嗎?Spring Cloud 如何解決跨語言的問題呢?

比較知名的微服務開源技術選型莫過於 Spring Cloud,它對 Netflix 提供的相關組件作了必定的封裝,讓開發者更容易上手。固然,我更加但願本書所先介紹的開源技術選型會被更多人接受與應用。

此次你的這本關於輕量級微服務,我有幾個問題,你的這本書裏關於微服務的技術選型是怎麼考量的?書中提到了 Spring Boot,你對於 Spring 的這個技術怎麼看?如今微信小程序比較流行,微服務會成爲小程序的技術首選嗎?

  1. 這本書中關於微服務的技術選型問題,我作了大量的思考並實踐,所選擇的方案均爲開源,且很是輕量級,目的是幫助你們可以快速搭建這款輕量級微服務架構。
  2. 雖然這本書講到的微服務開發框架是 Spring Boot,用過的人都知道它有明顯的優點,固然也有明顯的劣勢,畢竟底層仍是基於 Spring,而 Spring 從當初的輕量級彷佛變得愈來愈重,我但願有更好的輕量級框架能夠出現,因此當初寫了一款 Smart 框架以及《架構探險》第一本書,目的只是拋磚引玉,但願有更多的朋友都能投身到國內開源行業中,創造更優秀的開源項目。
  3. 我很是看好微信小程序的將來,但微服務是否成爲小程序的技術首選,我不太敢下次評論,我們一塊兒靜觀其變吧。

微服務框架是在 SOA 的基礎上提出的嗎?在技術選型要注意哪些點,用 Spring Cloud 仍是 Spring Boot?怎樣作到輕量級,有哪些參考?

  1. 我認爲微服務是傳統 SOA 的輕量級解決方案,它讓 SOA 更加容易落地。
  2. 在微服務技術選型方面,我建議竟可能地輕量級,作到「進可攻退可守」,至於 Spring Cloud 仍是其餘框架,徹底取決於咱們對技術自己的理解以及對業務的把控能力,技術也業務須要相互結合才能產生價值。
  3. 但願這本書中所設計的輕量級開源方案,會幫助您更快地搭建微服務架構。

4、實施微服務的開發成本有多高?

該在多大規模的項目中使用微服務比較合適?微服務會增長架構複雜度嗎?帶來的收益是否能夠抵消?

  1. 我認爲對於業務比較清晰的項目都可使用微服務架構,並不是須要具有多大規模。
  2. 微服務架構會帶來系統的複雜度(成本),但必然會帶來一些收益,至於成本和收益是否低效,這取決於咱們對微服務與業務的理解與把控能力。

實施微服務後,對於開發成本是否是更高了?

我認爲實施微服務並未提升開發成本,而是提升運維成本,一個好的微服務架構離不開運維方面的支持。本書下冊將針對運維方面將以描述,敬請期待。

微服務通常都要用到 Docker,這樣對研發人員和運維人員技術就要求更高了,如何快速有效實施微服務架構?

實施微服務必然會提升運維方面的成本,但我認爲這是有價值的,尤爲是自動化運維技術,也須要培養開發人員的運維思想。

微服務挺多人說玩不起,是否是相對來講實施成本挺高的?

玩不起包括兩層含義:一是認爲成本較高;二是擔憂有風險(怕玩掛了)。

5、微服務中的事務

如何簡單有效的實現事務?

可以使用消息隊列的方式,實現服務之間的事務控制。服務調用完畢,寫入消息隊列,經過消息驅動的方式調用其餘服務。

服務間是否是應該避免相互間調用, 由 API Gateway 來組織各個服務?

沒錯,應該避免服務間的調用,而使用服務網關做爲調用入口,但我不建議在服務網關處組織服務調用,而是經過一箇中間服務來編排,或使用消息驅動方式來完成。

服務與服務之間的事務怎麼作?

在微服務架構中,建議儘可能避免服務之間的調用,所以服務粒度的切分是相當重要的;服務間的調用會產生分佈式事務問題,建議採用「最終一致性」方法來確保分佈式事務,業界有兩種經常使用作法:CQRS 和 Event Sourcing。

目前,微服務的事務是你們最關心的,微服務的分佈式事務問題如何解決?請問,如今業界有沒有開源的解決微服務事務的項目。

微服務的事務控制比較複雜,咱們須要作到儘量避免服務之間的調用,這取決於咱們對微服務切分的粒度控制。

微服務分佈式事務通常藉助消息驅動與日誌追蹤的方式來解決,以達成事務的「最終一致性」,業界有 CQRS 與 Event Sourcing 來解決微服務的事務問題,但願對您有幫助。

如何使用事務補償模式解決分佈式事務問題?

事務補償機制說簡單點就是,在應用程序中經過代碼的方式作到數據的還原。通常狀況下,咱們需藉助消息隊列與日誌追蹤等方式來實現。

微服務在事務控制方面,容錯方面有什麼較好的實踐方式?

  1. 微服務的事務控制本質上是分佈式事務控制,建議使用「最終一致性」來確保。
  2. 在容錯方面,須要有基礎設施平臺的支撐,好比服務網關的熔斷機制。

6、微服務的業務該如何拆分?

微服務業務拆分有沒有什麼原則要點?

微服務業務拆分可按總體業務組件來拆分,也可按單一業務功能來切分。建議切分步驟從粗到細,逐步細化,不然開始就過細,致使依賴性過高,增長複雜度。

一個大服務怎麼拆最好,依據是什麼,微服務拆分如何控制合適的粒度?另外如今的微服務的教程好像都是針對 Java 的,好比 Spring Boot,其餘語言有沒有成熟的體系?

建議從整個業務流程來分析,首先抽象出公共服務,而後採用大粒度的方式來切分,最後逐步細化切分粒度,微服務切分粒度取決於咱們對業務的理解與把控能力。其餘開發語言也有相似於 Spring Boot 的微服務開發框架,好比 .NET 的 Nancy。

怎樣來控制微服務的粒度?就是有沒有什麼樣的原則和最佳實踐來判斷一個功能(接口)是應該屬於 A 服務仍是應該屬於 B 服務。

微服務的粒度控制取決於咱們對業務的理解與把控能力,一切所謂的原則都是不靠譜的。

微服務目前對於各個功能拆分是否是有些太細?

我認爲微服務的切分粒度沒有必要太細,適合業務發展並能提升開發效率的架構纔是好架構。

微服務拆分若是粒度太細,會不會致使維護成本增長?響應時間增長?事務控制如何實現?

  1. 微服務粒度問題取決於咱們對業務的理解與把控能力,無需太細。
  2. 可借用消息隊列和日誌追蹤進行事務控制,也可以使用 CQRS 或 Event Sourcing 解決方案。

如何控制粒度在方法級別的接口的調用權限?

此處所描述的「接口」是否理解爲服務的 API 接口呢?API 調用的權限控制可在微服務架構中的服務網關(Service Gateway)處加以控制。

單體架構拆分紅微服務後,每一個服務能獨立佈署,也便於橫向擴展,但也面臨以下的問題:

1. 微服務拆分粒度的原則是?2. 微服務的服務治理?

  1. 服務是根據業務功能來拆分的,拆分服務時需下降彼此之間的耦合性,儘量一個服務只作一件事情,即「單一職責原則」。
  2. 服務治理問題所涉及的問題較多,將在這本書下冊中加以描述,敬請期待,也歡迎進一步探討。

服務拆分以後就會出現,微服務調用微服務的狀況,致使效率很慢,接口的 QPS 很低,怎麼解決?

個人建議是,儘量避免服務之間的調用,不妨使用消息隊列的方式來下降服務之間的耦合,固然必要的直接調用可以使用 RPC 技術,它具有優秀的性能,可確保較高的 QPS。

7、使用微服務遇到的問題

我在公司實現分佈式的過程當中遇到了 3 個問題,如您有時間請您給些思路:

  1. 分佈式事務:當前採用消息隊列,隊列的消費者使用 Redis 作分佈式鎖來實現冪等消費,不知道這種方式存在什麼隱患?或者有沒有更好的方式?
  2. 日誌聚合:目前想要作一個日誌聚合功能,暫時考慮仍是使用消息隊列處理,不知道有什麼業界成熟的方式?
  3. 方法調用次數統計,暫時咱們想使用 AOP + 消息隊列 + strom 的方式來實現方法調用與耗時統計,不知道業界成熟的方式是什麼?
  1. 消息隊列可用於分佈式事務控制,這項技術已經在業界被證明是可用的。此外,還有 CQRS 與 Event Sourcing 技術也能夠嘗試一下。
  2. 日誌聚合可以使用業界流行的 ELK,即 Elasticsearch + Logstash + Kibana 來實現,L 用於收集日誌,E 用於存儲日誌,K 用於展示日誌。
  3. 方法調用次數統計,不建議放在服務內部經過 AOP 來控制,建議在微服務架構的服務網關(Service Gateway)加以控制。

我以爲接口調用次數統計,也能夠結合 flume + Mq + strom 作實時統計,這樣能夠根據日誌信息獲取調用次數額外的東西,如調用者所在的地區等。

看具體要求是怎樣的,若是隻是簡單記錄 API 調用次數,可在服務網關處增長此功能,將結果記錄到 MQ 中。

權限分訪問權限與資源權限。想請教下資源權限在微服務中怎麼作?好比我有個商品服務跟優惠服務,想要控制某個用戶只能查詢商品和建立優惠券,是每一個微服務都有獨自的權限功能,仍是有個權限服務統一下發和調配各個微服務的權限?或者貴公司在微服務中是怎麼作權限這塊的?

  1. 訪問權限建議在服務網關處加以控制。
  2. 資源權限建議抽象出一個單獨的中間件加以控制。

微服務下有不一樣的存儲介質,對於跨數據庫的分頁查詢有什麼好的辦法嗎?

使用微服務架構能夠作到:

  1. 一個服務使用一個數據庫(單庫)
  2. 一個服務使用多個數據庫(多庫)

對於「多庫」而言,可在服務內部聚合數據,也可以使用數據庫中間件來解決此問題。

SOA 與 MSA(微服務架構)區別在於系統一體化與服務組件分散化(「微化」)的區別。服務組件微化可讓關注點進一步縮小範圍,服務之間的規範或者實現的關聯性進一步下降(https://my.oschina.net/waylau/blog/617857)。但同時引入的一些問題:

  • 服務治理;
  • 服務的版本更新;
  • 服務之間的權限是如何來作控制的;
  • 服務如何來劃分顆粒度。

請教下,貴公司在實踐過程當中,有無遇到過上述問題,是如何解決的?

您說的很是好,這些問題可能都是每一位微服務實踐者所要面對的問題,考驗咱們的是,如何選擇合理的技術來解決此類問題。好比,服務治理可經過 Kubernetes、Mesos、Docker Swarm 等技術來實現,服務版本可經過 ZooKeeper、Etcd、Consul 等技術來控制,服務權限可自行實現權限中間件來解決,服務顆粒度劃分考驗咱們的是對業務的深度理解(這纔是最爲關鍵的)。總之,有具體技術能解決的可能都不是問題,多是問題的每每是咱們對自身業務的理解與把控能力。

1. 微服務對網絡、數據庫鏈接、緩存服務器等資源的影響;2. 微服務是否須要多版本服務共存?

  1. 微服務對網絡、數據庫、緩存方面較傳統架構而言,沒有太高的要求,但對運維方面要求較高。
  2. 微服務須要考慮服務多版本問題,尤爲是服務升級時,須要作到平滑,對總體系統沒有任何影響。

針對微服務的全局 ID 生成策略。不知道黃老師有沒有什麼好的建議?

  1. 看了不少的分佈式 ID 生成策略。提到不少 ID 趨勢遞增的策略,這個有什麼用?
  2. 爲何要讓 ID 具體有順序功能?如何保證順序?

不知道黃老師在實際項目中用了什麼策略,但願能分享一下。

實際上 ID 生成策略並不是是微服務架構所涵蓋的範疇。我認爲比較好的 ID 生成策略須要結合您所面臨的實際需求,通常應用場景下,可經過 Redis 來生成並管理 ID,它具有較高的併發能力,且能確保分佈式一致性。

有一個關於測試的問題想請教。是否是微服務更偏重敏捷模式呢?對於測試而言更容易開展工做?自動化測試覆蓋率更高?

  1. 我認爲微服務與敏捷沒有必然的關係,微服務講究的是將「化整爲零」,敏捷倡導的是「小步快跑」,但二者能夠有效地結合起來加以應用。
  2. 較傳統架構而言,微服務的測試複雜度和覆蓋面將更爲普遍,不只須要對每一個服務進行測試,並且須要對總體應用加以驗證。所以,咱們須要使用自動化測試技術來提升測試效率。

微服務是否就必定是進程級別的?在同一個進程內實現微服務可行嗎?若是一個服務就一個進程,這樣是否是會耗費大量系統資源?

  1. 微服務講究的是服務能夠獨立開發與部署,若是在進程內進行微服務,將帶來很高的複雜度,就像當年的 OSGi 那樣,理念很是好,但實踐起來卻困難重重。
  2. 一個服務一個進程,這樣讓服務的隔離性更加完全,配合 Docker 容器技術,能夠更加高效低利用服務器硬件與網絡資源。

微服務目前有什麼成熟的一整套開源方案嗎?包括測試、版本控制,發佈流程,代碼錯誤回滾?

業界也有其餘優秀的微服務開源方案,例如 Java 領域的 Netflix 與 Spring Cloud。固然,我更但願本書所提到的開源方案,能夠被更多人接受並應用。

微服務怎麼解決調用鏈過長致使的調試或異常追蹤過難的問題呢?

調用鏈追蹤是微服務落地的一個挑戰,咱們通常經過追蹤平臺來解決,推薦使用開源的 Zipkin。

微服務通常是 JSON 格式調用,與其餘調用方式有什麼區別麼?

我認爲 JSON 格式只是 REST API 返回值的一種,微服務並不是侷限於 REST API 通訊。

樓主推薦使用 Spring Cloud 構建微服務嗎?

Spring Cloud 對微服務架構提供了很好的技術封裝,建議對其充分了解的狀況下使用。

微服務都是經過 HTTP 方式對外提供?

微服務對外的接口不必定侷限於 HTTP 或 HTTPS,也能夠是 TCP,須要根據具體狀況而定。

使用 REST 通訊其實挺麻煩的,還須要封裝一層調用方法,不知道有沒有相似的問題?

REST API 是一個種輕量級通訊方式,也有助於跨平臺調用,咱們的作法每每是提供一個客戶端 SDK,目前已有大量的技術來快速實現 REST SDK,好比 Spring RestTemplate,或 Retrofit。

8、微服務與容器的結合會碰撞出怎樣的問題?

目前很火的容器技術和微服務如何結合?

因爲微服務架構是能夠作到服務的異構性的,也就是說,咱們可根據實際狀況,選擇最適合的開發語言來實現服務。容器技術具有隔離性,可將異構開發語言的服務進行統一封裝,並有助於自動化部署,以及持續交付。

Docker 容器技術的出現,爲微服務提供了更便利的條件,好比更小的部署單元,每一個服務能夠經過相似 Node.js 或 Spring Boot 的技術跑在本身的進程中。可能在幾十臺計算機中運行成千上萬個 Docker 容器,這麼多 Docker 容器怎麼來有效管理?出錯瞭如何排查呢?

實際上您提到的是服務治理問題,目前有大量的技術能夠作到,好比:Google Kubernetes、Apache Mesos、Docker Swarm 等。

據說使用 Docker 運行 Java 一點優點都沒有,微服務架構大量啓動 Docker 集羣,內存利用率很低,雖然 Java 運行效率很高。您怎麼看?

Java 應用經 Docker 化後,最明顯的問題是 Docker 鏡像體積較大,啓動 Docker 容器所佔用的系統資源較高。建議根據實際業務場景,選擇最爲合適的開發語言實現對應的微服務,而並不是侷限於 Java 應用之上。

若是不使用 Docker,會給微服務帶來哪些不便?

若是沒有 Docker 這類容器技術,可能會下降微服務的部署與交付能力。

Spring Boot 與 Docker 整合, 在大數據使用方面多很少?

Spring Boot 與 Docker 整合,在許多領域都有應用,固然不排除大數據方面。

有關微服務的相關問答內容至此結束。做爲開發者,多嘗試各類技術對於開闊本身的眼界和思路是十分有益的。並且遇到問題也能夠經過互聯網尋求解決的辦法,像開源中國的技術問答區上面就有不少活躍的技術大牛,歡迎你們在上面踊躍提問和回答。

相關文章
相關標籤/搜索