1、前言ios
2014年能夠認爲是微服務 1.0的元年,當年有幾個標誌性事件,一是 Martin Fowler在其博客上發表了」Microservices」一文,正式提出微服務架構風格;二是Netflix微服務架構通過多年大規模生產驗證,最終抽象落地造成一整套開源的微服務基礎組件,統稱 NetflixOSS,Netflix的成功經驗開始被業界承認並推崇;三是 Pivotal將 NetflixOSS開源微服務組件集成到其Spring體系,推出 Spring Cloud微服務開發技術棧。git
一晃三年過去,微服務技術生態又發生了巨大變化,容器,PaaS,Cloud Native,gRPC,ServiceMesh,Serverless等新技術新理念你方唱罷我登場,不知不覺咱們又來到了微服務 2.0時代。github
基於近年在微服務基礎架構方面的實戰經驗和平時的學習積累,我想總結並提出一些構建微服務 2.0技術棧的選型思路,供各位在一線實戰的架構師、工程師參考借鑑。對於一些暫時尚未成熟開源產品的微服務支撐模塊,我也會給出一些定製自研的設計思路。算法
2、選型準則spring
對於技術選型,我我的有不少標準,其中下面三項是最重要的:數據庫
1.生產級編程
咱們選擇的技術棧是要解決實際業務問題和上生產抗流量的(選擇不慎可能形成生產級事故),而不是簡單作個 POC或者 Demo展現,因此生產級(Production Ready),可運維(Ops Ready),可治理,成熟穩定的技術纔是咱們的首選;緩存
2.一線互聯網公司落地產品安全
咱們會盡可能採用在一線互聯網公司落地而且開源的,且在社區內造成良好口碑的產品,它們已經在這些公司通過流量衝擊,坑已經基本被填平,且被社區接受造成一個良好的社區生態(本文附錄部分會給出全部推薦使用或參考的開源項目的GitHub連接)。服務器
3.開源社區活躍度
GitHub上的stars的數量是一個重要指標,同時會參考其代碼和文檔更新頻率(尤爲是近年),這些指標直接反應開源產品的社區活躍度或者說生命力。
另外,對於不一樣業務體量和團隊規模的公司,技術選型標準每每是不一樣的,創業公司的技術選型和BAT級別公司的技術選型標準可能徹底不一樣。本文主要針對日流量千萬以上,研發團隊規模很多於 50人的公司,若是小於這個規模我建議認真評估是否真的須要採用微服務架構。考慮到 Java語言在國內的流行度和我我的的背景經驗,本文主要針對採用 Java技術棧的企業。本文也假定自建微服務基礎架構,有些產品其實有對應的雲服務能夠直接使用,自建和採用雲服務各有利弊,架構師須要根據場景上下文綜合權衡。
這裏編輯強力推薦楊波在『極客時間App』上的微服務架構視頻白板課程,他用一張圖,6分鐘時間,深刻淺出解釋微服務架構中的關鍵概念。目前是第一季,後面還有第二季。感興趣的用戶還請點擊文末閱讀原文連接瞭解詳情。
3、微服務基礎架構關鍵點
下面腦圖中芒果色標註的七個模塊,我認爲是構建微服務 2.0技術棧的核心模塊,本文後面的選型會分別基於這些模塊展開。對於每一個模塊我也列出一些核心架構關注點,在選擇具體產品時,須要儘量覆蓋到這些關注點。
下圖是我近期工做總結和參考的一個微服務技術體系,我想同時分享給一線架構師或者工程師參考,其中粉紅色標註的模塊是和微服務關係最密切的模塊,你們在作技術選型時,能夠同時對照這個體系。
4、服務框架選型
服務框架是一個比較成熟的領域,有太多可選項。Spring Boot/Cloud[附錄 12.1]因爲 Spring社區的影響力和 Netflix的背書,目前能夠認爲是構建 Java微服務的一個社區標準,Spring Boot目前在 GitHub上有超過 20k星。
基於 Spring的框架本質上能夠認爲是一種 RESTful框架(不是 RPC框架),序列化協議主要採用基於文本的 JSON,通信協議通常基於 HTTP。RESTful框架自然支持跨語言,任何語言只要有 HTTP客戶端均可以接入調用,可是客戶端通常須要本身解析 payload。目前 Spring框架也支持 Swagger契約編程模型,可以基於契約生成各類語言的強類型客戶端,極大方便不一樣語言棧的應用接入,可是由於 RESTful框架和 Swagger規範的弱契約特性,生成的各類語言客戶端的互操做性仍是有很多坑的。
Dubbo[附錄 12.2]是阿里多年構建生產級分佈式微服務的技術結晶,服務治理能力很是豐富,在國內技術社區具備很大影響力,目前 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(GitHub1.9stars)等。可是這些產品通常都比較複雜重量,不少企業考慮到內部各類系統靈活對接的需求,都會考慮定製自研輕量級的解決方案。
考慮到服務部署平臺目前尚未端到端生產級解決方案,企業通常須要定製集成,下面給出一個能夠參考的具有輕量級治理能力的發佈體系:
簡化發佈流程以下:
應用經過 CI集成後生成鏡像,用戶將鏡像推到鏡像治理中心;
用戶在資產治理中心申請發佈,填報應用,發佈和配額相關信息,而後等待審批經過;
發佈審批經過,開發人員經過發佈控制檯發佈應用;
發佈系統經過查詢資產治理中心獲取發佈規格信息;
發佈系統向容器雲發出啓動容器實例指令;
容器雲從鏡像治理中心拉取鏡像並啓動容器;
容器內服務啓動後自注冊到服務註冊中心,並保持按期心跳;
用戶經過發佈系統調用服務註冊中心調撥流量,實現藍綠,金絲雀或灰度發佈等機制;
網關和內部微服務客戶端按期同步服務註冊中心上的服務路由表,將流量按負載均衡策略分發到新的服務實例上。
另外,持續交付流水線(CD Pipeline)也是微服務發佈重要環節,這塊主要和研發流程相關,通常須要企業定製,下面是一個可供參考的流水線模型,在鏡像治理中心上封裝一些輕量級的治理流程,例如只有經過測試環境測試的鏡像才能升級發佈到 UAT環境,只有經過 UAT環境測試的鏡像才能升級發佈到生產環境,經過在流水線上設置一些質量門,保障應用高質量交付到生產。
11、寫在最後
注意,本文限於篇幅,對測試和 CI等環節沒有涉及,但它們一樣是構建微服務架構的重要環節,也有衆多成熟的開源產品可選。
技術選型雖然重要,但還只是微服務建設的一小部分工做,選型後的產品要在企業內部真正落地,造成完整的微服務技術棧體系,則後續還有大量集成、定製、治理、運維和推廣等工做。
本文僅限我的經驗視角,選型思路僅供參考借鑑。每一個企業的具體上下文(業務場景,團隊組織,技術架構等)各不相同,每一個架構師的背景經驗也各不相同,你們要結合實際本身作出選型,沒有最好的技術棧,只有相對較合適的技術棧。另外,好的技術選型是相互借鑑甚至 PK出來的,歡迎你們討論,給出本身的微服務 2.0技術棧選型意見。
12、附錄連接
Spring Boot
AlibabaDubbo
Google gRPC
NetflixOSSEureka
Hashicorp Consul
NetflixOSSZuul
Kong
Spring Cloud Config
CTrip Apollo
ElasticSearch
YelpElastalert
Dianping CAT
Zipkin
Naver Pinpoint
OpenTSDB
KairosDB
Argus
InfluxDB
Prometheus
Grafana
Sensu
Esty 411
Zalando ZMon
NetflixOSS Hystrix
Nginx
ApacheKafka
Allegro Hermes
Apache Rocketmq
Rabbitmq
Sohutv CacheCloud
Twittertwemproxy
CodisLab codis
Dangdang Sharding-jdbc
MyCAT
Xxl-job
Dangdang elastic-job
Apereo CAS
JBoss keycloak
Spring cloud security
OpenID-Connect-Java-Spring-Server
GoogleKubernetes
Apache Mesos
VmwareHarbor
NetflixSpinnaker
Microservices in Practice – Key Architecture Concepts of an MSA