(非原創。轉載自:https://mp.weixin.qq.com/s/bsuveX-E6E2fKZ24mj03nQ)ios
1、前言git
2014 年能夠認爲是微服務 1.0 的元年,一晃三年過去,微服務技術生態又發生了巨大變化,容器,PaaS,Cloud Native(雲原生),gRPC(基於RPC, http 2.0),ServiceMesh(服務網格),Serverless(Serverless不表明不再須要服務器了,而是說:開發者不再用過多考慮服務器的問題,計算資源做爲服務而不是服務器的概念出現。Serverless是一種構建和管理基於微服務架構的完整流程,容許你在服務部署級別而不是服務器部署級別來管理你的應用部署,你甚至能夠管理某個具體功能或端口的部署,這就能讓開發者快速迭代,更快速地開發軟件) 等新技術新理念你方唱罷我登場,不知不覺咱們又來到了微服務 2.0 時代。github
(補充: 1: Spring cloud的微服務架構是基於HTTP的, 典型的RESTFUL; 而 dubbo是基於RPC的。算法
2、選型準則spring
對於技術選型,我我的有不少標準,其中下面三項是最重要的:數據庫
1. 生產級編程
生產級(Production Ready),可運維(Ops Ready),可治理,成熟穩定的技術纔是咱們的首選;緩存
2. 一線互聯網公司落地產品安全
咱們會盡可能採用在一線互聯網公司落地而且開源的,且在社區內造成良好口碑的產品,它們已經在這些公司通過流量衝擊,坑已經基本被填平,且被社區接受造成一個良好的社區生態(本文附錄部分會給出全部推薦使用或參考的開源項目的 GitHub 連接)。 服務器
3. 開源社區活躍度
GitHub 上的 stars 的數量是一個重要指標,同時會參考其代碼和文檔更新頻率(尤爲是近年),這些指標直接反應開源產品的社區活躍度或者說生命力。
另外,對於不一樣業務體量和團隊規模的公司,技術選型標準每每是不一樣的,創業公司的技術選型和 BAT 級別公司的技術選型標準可能徹底不一樣。本文主要針對日流量千萬以上,研發團隊規模很多於 50 人的公司,若是小於這個規模我建議認真評估是否真的須要採用微服務架構。考慮到 Java 語言在國內的流行度和我我的的背景經驗,本文主要針對採用 Java 技術棧的企業。本文也假定自建微服務基礎架構,有些產品其實有對應的雲服務能夠直接使用,自建和採用雲服務各有利弊,架構師須要根據場景上下文綜合權衡。
3、微服務基礎架構關鍵點
下面腦圖中芒果色標註的七個模塊,我認爲是構建微服務 2.0 技術棧的核心模塊,本文後面的選型會分別基於這些模塊展開。對於每一個模塊我也列出一些核心架構關注點,在選擇具體產品時,須要儘量覆蓋到這些關注點。
下圖是我近期工做總結和參考的一個微服務技術體系,我想同時分享給一線架構師或者工程師參考,其中粉紅色標註的模塊是和微服務關係最密切的模塊,你們在作技術選型時,能夠同時對照這個體系。
4、服務框架選型
服務框架是一個比較成熟的領域,有太多可選項。Spring Boot/Cloud 因爲 Spring 社區的影響力,目前能夠認爲是構建 Java 微服務的一個社區標準,Spring Boot 目前在 GitHub 上有超過 20k 星。基於 Spring 的框架本質上能夠認爲是一種 RESTful 框架(不是 RPC 框架),序列化協議主要採用基於文本的 JSON,通信協議通常基於 HTTP。RESTful 框架自然支持跨語言,任何語言只要有 HTTP 客戶端均可以接入調用,可是客戶端通常須要本身解析 payload。目前 Spring 框架也支持 Swagger 契約編程模型,可以基於契約生成各類語言的強類型客戶端,極大方便不一樣語言棧的應用接入,可是由於 RESTful 框架和 Swagger 規範的弱契約特性,生成的各類語言客戶端的互操做性仍是有很多坑的。
Dubbo是阿里多年構建生產級分佈式微服務的技術結晶,服務治理能力很是豐富,在國內技術社區具備很大影響力,目前 github 上有超過 16k 星。Dubbo 本質上是一套基於 Java 的 RPC 框架,噹噹 Dubbox 擴展了 Dubbo 支持 RESTful 接口暴露能力。
(補充: 微服務的服務治理: 服務註冊發現; 監控; 容錯; 認證; 負載均衡)
Dubbo 主要面向 Java 技術棧,跨語言支持不足是它的一個弱項,另外由於治理能力太豐富,以致於這個框架比較重,徹底用好這個框架的門檻比較高,可是若是你的企業基本上投資在 Java 技術棧上,選 Dubbo 可讓你在服務框架一塊站在較高的起點上,無論是性能仍是企業級的服務治理能力,Dubbo 都作的很出色。新浪微博開源的 Motan(GitHub 4k stars)也不錯,功能和 Dubbo 相似,能夠認爲是一個輕量裁剪版的 Dubbo。
gRPC[附錄 12.3] 是谷歌近年新推的一套 RPC 框架,基於 protobuf 的強契約編程模型,能自動生成各類語言客戶端,且保證互操做。支持 HTTP2 是 gRPC 的一大亮點,通信層性能比 HTTP 有很大改進。Protobuf 是在社區具備悠久歷史和良好口碑的高性能序列化協議,加上 Google 公司的背書和社區影響力,目前 gRPC 也比較火,GitHub 上有超過 13.4k 星。
目前看 gRPC 更適合內部服務相互調用場景,對外暴露 RESTful 接口能夠實現,可是比較麻煩(須要 gRPC Gateway 配合),因此對於對外暴露 API 場景可能還須要引入第二套 RESTful 框架做爲補充。整體上 gRPC 這個東西還比較新,社區對於 HTTP2 帶來的好處還未造成一致認同,建議謹慎投入,能夠作一些試點。
5、運行時支撐服務選型
運行時支撐服務主要包括服務註冊中心,服務路由網關和集中式配置中心三個產品。
服務註冊中心,若是採用 Spring Cloud 體系,則選擇 Eureka[附錄 12.4] 是最佳搭配,Eureka 在 Netflix 通過大規模生產驗證,支持跨數據中心,客戶端配合 Ribbon 能夠實現靈活的客戶端軟負載,Eureka 目前在 GitHub 上有超過 4.7k 星;Consul[附錄 12.5] 也是不錯選擇,自然支持跨數據中心,還支持 KV 模型存儲和靈活健康檢查能力,目前在 GitHub 上有超過 11k 星。
服務網關也是一個比較成熟的領域,有不少可選項。若是採用 Spring Cloud 體系,則選擇 Zuul[附錄 12.6] 是最佳搭配,Zuul 在 Netflix 通過大規模生產驗證,支持靈活的動態過濾器腳本機制,異步性能不足(基於 Netty 的異步 Zuul 遲遲未能推出正式版)。Zuul 網關目前在 github 上有超過 3.7k 星。基於 Nginx/OpenResty 的 API 網關 Kong[附錄 12.7] 目前在 github 上比較火,有超過 14.1k 星。由於採用 Nginx 內核,Kong 的異步性能較強,另外基於 lua 的插件機制比較靈活,社區插件也比較豐富,從安全到限流熔斷都有,還有很多開源的管理界面,可以集中管理 Kong 集羣。
配置中心,Spring Cloud 自帶 Spring Cloud Config[附錄 12.8](GitHub 0.75k stars),我的認爲算不上生產級,不少治理能力缺失,小規模場景能夠試用。我的比較推薦攜程的 Apollo[附錄 12.9] 配置中心,在攜程通過生產級驗證,具有高可用,配置實時生效(推拉結合),配置審計和版本化,多環境多集羣支持等生產級特性,建議中大規模須要對配置集中進行治理的企業採用。Apollo 目前在 github 上有超過 3.4k 星。
6、服務監控選型
主要包括日誌監控,調用鏈監控,Metrics 監控,健康檢查和告警通知等產品。
ELK 目前能夠認爲是日誌監控的標配,功能完善開箱即用,ElasticSearch[附錄 12.10] 目前在 GitHub 上有超過 28.4k 星。Elastalert[附錄 12.11] (GitHub 4k stars) 是 Yelp 開源的針對 ELK 的告警通知模塊。
調用鏈監控目前社區主流是點評 CAT[附錄 12.12](GitHub 4.3k stars),Twitter 以前開源如今由 OpenZipkin 社區維護的 Zipkin[附錄 12.13](GitHub 7.5k stars)和 Naver 開源的 Pinpoint[附錄 12.14](GitHub 5.3k stars)。我的比較推薦點評開源的 CAT,在點評和國內多家互聯網公司有落地案例,生產級特性和治理能力較完善,另外 CAT 自帶告警模塊。下面是我以前對三款產品的評估表,供參考。
Metrics 監控主要依賴於時間序列數據庫 (TSDB),目前較成熟的產品是 StumbleUpon 公司開源的基於 HBase 的 OpenTSDB[附錄 12.15](基於 Cassandra 的 KariosDB[附錄 12.16] 也是一個選擇,GitHub 1.1k stars,它基本上是 OpenTSDB 針對 Cassandra 的一個改造版),OpenTSDB 具備分佈式能力能夠橫向擴展,可是相對較重,適用於中大規模企業,OpenTSDB 目前在 GitHub 上有近 2.9k 星。
OpenTSDB 自己不提供告警模塊,Argus[附錄 12.17](GitHub 0.29k 星)是 Salesforce 開源的基於 OpenTSDB 的統一監控告警平臺,支持豐富的告警函數和靈活的告警配置,能夠做爲 OpenTSDB 的告警補充。近年也出現一些輕量級的 TSDB,如 InfluxDB[附錄 12.18](GitHub 12.4k stars)和 Prometheus[附錄 12.19](GitHub 14.3k stars),這些產品函數報表能力豐富,自帶告警模塊,可是分佈式能力不足,適用於中小規模企業。Grafana[附錄 12.20](GitHub 19.9k stars)是 Metrics 報表展現的社區標配。
社區還有一些通用的健康檢查和告警產品,例如 Sensu[附錄 12.21](GitHub 2.7k stars),可以對各類服務(例如 Spring Boot 暴露的健康檢查端點,時間序列數據庫中的 metrics,ELK 中的錯誤日誌等)定製靈活的健康檢查 (check),而後用戶能夠針對 check 結果設置靈活的告警通知策略。Sensu 在 Yelp 等公司有落地案例。其它相似產品還有 Esty 開源的 411[附錄 12.22](GitHub 0.74k 星)和 Zalando 的 ZMon[附錄 12.23] (GitHub 0.15k 星),它們是分別在 Esty 和 Zalando 落地的產品,可是定製 check 和告警配置的使用門檻比較高,社區不熱,建議有定製自研能力的團隊試用。ZMon 後臺採用 KairosDB 存儲,若是企業已經採用 KariosDB 做爲時間序列數據庫,則能夠考慮 ZMon 做爲告警通知模塊。
7、服務容錯選型
針對 Java 技術棧,Netflix 的 Hystrix[附錄 12.24](github 12.4k stars)把熔斷、隔離、限流和降級等能力封裝成組件,任何依賴調用(數據庫,服務,緩存)均可以封裝在 Hystrix Command 以內,封裝後自動具有容錯能力。Hystrix 起源於 Netflix 的彈性工程項目,通過 Netflix 大規模生產驗證,目前是容錯組件的社區標準,GitHub 上有超 12k 星。其它語言棧也有相似 Hystrix 的簡化版本組件。
Hystrix 通常須要在應用端或者框架內埋點,有必定的使用門檻。對於採用集中式反向代理(邊界和內部)作服務路由的公司,則能夠集中在反向代理上作熔斷限流,例如採用 Nginx[附錄 12.25](GitHub 5.1k stars)或者 Kong[附錄 12.7](GitHub 11.4k stars)這類反向代理,它們都插件支持靈活的限流容錯配置。Zuul 網關也能夠集成 Hystrix 實現網關層集中式限流容錯。集中式反向代理須要有必定的研發和運維能力,可是能夠對限流容錯進行集中治理,能夠簡化客戶端。
8、後臺服務選型
後臺服務主要包括消息系統,分佈式緩存,分佈式數據訪問層和任務調度系統。後臺服務是一個相對比較成熟的領域,不少開源產品基本能夠開箱即用。
消息系統,對於日誌等可靠性要求不高的場景,則 Apache 頂級項目 Kafka[附錄 12.26](GitHub 7.2k stars)是社區標配。對於可靠性要求較高的業務場景,Kafka 其實也是能夠勝任,但企業須要根據具體場景,對 Kafka 的監控和治理能力進行適當定製完善,Allegro 公司開源的 hermes[附錄 12.27](GitHub 0.3k stars)是一個可參考項目,它在 Kafka 基礎上封裝了適合業務場景的企業級治理能力。阿里開源的 RocketMQ[附錄 12.28](GitHub 3.5k 星)也是一個不錯選擇,具有更多適用於業務場景的特性,目前也是 Apache 頂級項目。RabbitMQ[附錄 12.29](GitHub 3.6k 星)是老牌經典的 MQ,隊列特性和文檔都很豐富,性能和分佈式能力稍弱,中小規模場景可選。
對於緩存治理,若是傾向於採用客戶端直連模式(我的認爲緩存直連更簡單輕量),則 SohuTv 開源的 cachecloud[附錄 12.30](GitHub 2.5k stars)是一款不錯的 Redis 緩存治理平臺,提供諸如監控統計,一鍵開啓,自動故障轉移,在線伸縮,自動化運維等生產級治理能力,另外其文檔也比較豐富。若是傾向採用中間層 Proxy 模式,則 Twitter 開源的 twemproxy[附錄 12.31](GitHub 7.5k stars)和 CodisLab 開源的 codis[附錄 12.32](GitHub 6.9k stars)是社區比較熱的選項。
對於分佈式數據訪問層,若是採用 Java 技術棧,則噹噹開源的 shardingjdbc[附錄 12.33](GitHub 3.5k stars)是一個不錯的選項,分庫分表邏輯作在客戶端 jdbc driver 中,客戶端直連數據庫比較簡單輕量,建議中小規模場景採用。若是傾向採用數據庫訪問中間層 proxy 模式,則從阿里 Cobar 演化出來的社區開源分庫分表中間件 MyCAT[附錄 12.34](GitHub 3.6k stars)是一個不錯選擇 。proxy 模式運維成本較高,建議中大規模場景,有必定框架自研和運維能力的團隊採用。
任務調度系統,我的推薦徐雪裏開源的 xxl-job[附錄 12.35](GitHub 3.4k stars),部署簡單輕量,大部分場景夠用。噹噹開源的 elastic-job[附錄 12.36](GitHub 3.2k stars)也是一個不錯選擇,相比 xxl-job 功能更強一些也更復雜。
9、服務安全選型
對於微服務安全認證受權機制一塊,目前業界雖然有 OAuth 和 OpenID connect 等標準協議,可是各傢俱體實現的作法都不太同樣,企業通常有不少特殊的定製需求,整個社區尚未造成通用生產級開箱即用的產品。有一些開源受權服務器產品,比較知名的如 Apereo CAS[附錄 12.37](GitHub 3.6k stars),JBoss 開源的 keycloak[附錄 12.38](GitHub 1.9 stars),spring cloud security[附錄 12.39] 等,大都是 opinionated(一家觀點和作法)的產品,同時因支持太多協議形成產品複雜,也缺少足夠靈活性。我的建議基於 OAuth 和 OpenID connect 標準,在參考一些開源產品的基礎上(例如 Mitre 開源的 OpenID-Connect-Java-Spring-Server[附錄 12.40],GitHub 0.62k stars),定製自研輕量級受權服務器。Wso2 提出了一種微服務安全的參考方案 [附錄 12.45],建議參考,該方案的關鍵步驟以下:使用支持 OAuth 2.0 和 OpenID Connect 標準協議的受權服務器(我的建議定製自研);
使用 API 網關做爲單一訪問入口,統一實現安全治理;
客戶在訪問微服務以前,先經過受權服務器登陸獲取 access token,而後將 access token 和請求一塊兒發送到網關;
網關獲取 access token,經過受權服務器校驗 token,同時作 token 轉換獲取 JWT token。
網關將 JWT Token 和請求一塊兒轉發到後臺微服務;
JWT 中能夠存儲用戶會話信息,該信息能夠傳遞給後臺的微服務,也能夠在微服務之間傳遞,用做認證受權等用途;
每一個微服務包含 JWT 客戶端,可以解密 JWT 並獲取其中的用戶會話信息。
整個方案中,access token 是一種 by reference token,不包含用戶信息能夠直接暴露在公網上;JWT token 是一種 by value token,能夠包含用戶信息但不暴露在公網上。
10、服務部署平臺選型
容器已經被社區接受爲交付微服務的一種理想手段,能夠實現不可變(immutable)發佈模式。一個輕量級的基於容器的服務部署平臺主要包括容器資源調度,發佈系統,鏡像治理,資源治理和 IAM 等模塊。
集羣資源調度系統:屏蔽容器細節,將整個集羣抽象成容器資源池,支持按需申請和釋放容器資源,物理機發生故障時可以實現自動故障遷移 (fail over)。目前 Google 開源的 Kubernetes[附錄 12.41],在 Google 背書和社區的強力推進下,基本已經造成市場領導者地位,GitHub 上有 31.8k 星,社區的活躍度已經遠遠超過了 mesos[附錄 12.42](GitHub 3.5k stars)和 swarm 等競爭產品,因此容器資源調度建議首選 K8s。固然若是你的團隊有足夠定製自研能力,想深度把控底層調度算法,也能夠基於 Mesos 作定製自研。
鏡像治理:基於 Docker Registry,封裝一些輕量級的治理功能。VMware 開源的 harbor[附錄 12.43] (GitHub 3.5k stars) 是目前社區比較成熟的企業級產品,在 Docker Registry 基礎上擴展了權限控制,審計,鏡像同步,管理界面等治理能力,能夠考慮採用。
資源治理:相似於 CMDB 思路,在容器雲環境中,企業仍然須要對應用 app,組織 org,容器配額和數量等相關信息進行輕量級的治理。目前這塊尚未生產級的開源產品,通常企業須要根據本身的場景定製自研。
發佈平臺:面向用戶的發佈管理控制檯,支持發佈流程編排。它和其它子系統對接交互,實現基本的應用發佈能力,也實現如藍綠,金絲雀和灰度等高級發佈機制。目前這塊生產級的開源產品不多,Netflix 開源的 spinnaker[附錄 12.44](github 4.2k stars)是一個,可是這個產品比較複雜重量(由於它既要支持適配對接各類 CI 系統,同時還要適配對接各類公有云和容器雲,使得整個系統異常複雜),通常企業建議根據本身的場景定製自研輕量級的解決方案。
IAM:是 identity & access management 的簡稱,對發佈平臺各個組件進行身份認證和安全訪問控制。社區有很多開源的 IAM 產品,比較知名的有 Apereo CAS(GitHub 3.6k stars),JBoss 開源的 keycloak(GitHub 1.9 stars)等。可是這些產品通常都比較複雜重量,不少企業考慮到內部各類系統靈活對接的需求,都會考慮定製自研輕量級的解決方案。
考慮到服務部署平臺目前尚未端到端生產級解決方案,企業通常須要定製集成,下面給出一個能夠參考的具有輕量級治理能力的發佈體系:
簡化發佈流程以下:
應用經過 CI 集成後生成鏡像,用戶將鏡像推到鏡像治理中心(一個倉庫);
用戶在資產治理中心申請發佈,填報應用,發佈和配額相關信息,而後等待審批經過;
發佈審批經過,開發人員經過發佈控制檯發佈應用;
發佈系統經過查詢資產治理中心獲取發佈規格信息;
發佈系統向容器雲發出啓動容器實例指令;
容器雲從鏡像治理中心拉取鏡像並啓動容器;
容器內服務啓動後自注冊到服務註冊中心,並保持按期心跳;
用戶經過發佈系統調用服務註冊中心調撥流量,實現藍綠,金絲雀或灰度發佈等機制;
網關和內部微服務客戶端按期同步服務註冊中心上的服務路由表,將流量按負載均衡策略分發到新的服務實例上。
另外,持續交付流水線(CD Pipeline)也是微服務發佈重要環節,這塊主要和研發流程相關,通常須要企業定製,下面是一個可供參考的流水線模型,在鏡像治理中心上封裝一些輕量級的治理流程,例如只有經過測試環境測試的鏡像才能升級發佈到 UAT 環境,只有經過 UAT 環境測試的鏡像才能升級發佈到生產環境,經過在流水線上設置一些質量門,保障應用高質量交付到生產。
11、寫在最後
注意,本文限於篇幅,對測試和 CI 等環節沒有涉及,但它們一樣是構建微服務架構的重要環節,也有衆多成熟的開源產品可選。
技術選型雖然重要,但還只是微服務建設的一小部分工做,選型後的產品要在企業內部真正落地,造成完整的微服務技術棧體系,則後續還有大量集成、定製、治理、運維和推廣等工做。
本文僅限我的經驗視角,選型思路僅供參考借鑑。每一個企業的具體上下文(業務場景,團隊組織,技術架構等)各不相同,每一個架構師的背景經驗也各不相同,你們要結合實際本身作出選型,沒有最好的技術棧,只有相對較合適的技術棧。另外,好的技術選型是相互借鑑甚至 PK 出來的,歡迎你們討論,給出本身的微服務 2.0 技術棧選型意見