2014年能夠認爲是微服務1.0的元年,當年有幾個標誌性事件,一是Martin Fowler在其博客上發表了「Microservices」一文,正式提出微服務架構風格;二是Netflix微服務架構通過多年大規模生產驗證,最終抽象落地造成一整套開源的微服務基礎組件,統稱NetflixOSS,Netflix的成功經驗開始被業界承認並推崇;三是Pivotal將NetflixOSS開源微服務組件集成到其Spring體系,推出Spring Cloud微服務開發技術棧。ios
一晃三年過去,微服務技術生態又發生了巨大變化,容器,PaaS,Cloud Native,gRPC,ServiceMesh,Serverless等新技術新理念你方唱罷我登場,不知不覺咱們又來到了微服務2.0時代。基於近年在微服務基礎架構方面的實戰經驗和平時的學習積累,我想總結並提出一些構建微服務2.0技術棧的選型思路,供各位在一線實戰的架構師、工程師參考借鑑。對於一些暫時尚未成熟開源產品的微服務支撐模塊,我也會給出一些定製自研的設計思路。nginx
對於技術選型,我我的有不少標準,其中下面三項是最重要的:git
咱們選擇的技術棧是要解決實際業務問題和上生產抗流量的(選擇不慎可能形成生產級事故),而不是簡單作個POC或者Demo展現,因此生產級(Production Ready),可運維(Ops Ready),可治理,成熟穩定的技術纔是咱們的首選;github
咱們會盡可能採用在一線互聯網公司落地而且開源的,且在社區內造成良好口碑的產品,它們已經在這些公司通過流量衝擊,坑已經基本被填平,且被社區接受造成一個良好的社區生態(本文附錄部分會給出全部推薦使用或參考的開源項目的github連接。)。算法
Github上的stars的數量是一個重要指標,同時會參考其代碼和文檔更新頻率(尤爲是近年),這些指標直接反應開源產品的社區活躍度或者說生命力。spring
另外,對於不一樣業務體量和團隊規模的公司,技術選型標準每每是不一樣的,創業公司的技術選型和BAT級別公司的技術選型標準可能徹底不一樣。本文主要針對日流量千萬以上,研發團隊規模很多於50人的公司,若是小於這個規模我建議認真評估是否真的須要採用微服務架構。考慮到Java語言在國內的流行度和我我的的背景經驗,本文主要針對採用Java技術棧的企業。本文也假定自建微服務基礎架構,有些產品其實有對應的雲服務能夠直接使用,自建和採用雲服務各有利弊,架構師須要根據場景上下文綜合權衡。docker
下面腦圖中芒果色標註的七個模塊,我認爲是構建微服務2.0技術棧的核心模塊,本文後面的選型會分別基於這些模塊展開。對於每一個模塊我也列出一些核心架構關注點,在選擇具體產品時,須要儘量覆蓋到這些關注點。數據庫
下圖是在參考過華爲技術專家王磊的《微服務的設計與生態系統》[附錄12.46]的基礎上,結合做者自身的實踐調整而來,我想同時分享給一線架構師或者工程師參考,其中粉紅色標註的模塊是和微服務關係最密切的模塊,你們在作技術選型時,能夠同時對照這個體系。apache
服務框架是一個比較成熟的領域,有太多可選項。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更適合內部服務相互調用場景,對外暴露HTTP RESTful接口能夠實現,可是比較麻煩(須要gRPC Gateway配合),因此對於對外暴露API場景可能還須要引入第二套HTTP RESTful框架做爲補充。整體上gRPC這個東西還比較新,社區對於HTTP2帶來的好處還未造成一致認同,建議謹慎投入,能夠作一些試點。
運行時支撐服務主要包括服務註冊中心,服務路由網關和集中式配置中心三個產品。
服務註冊中心,若是採用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星。
主要包括日誌監控,調用鏈監控,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做爲告警通知模塊。
針對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實現網關層集中式限流容錯。集中式反向代理須要有必定的研發和運維能力,可是能夠對限流容錯進行集中治理,能夠簡化客戶端。
後臺服務主要包括消息系統,分佈式緩存,分佈式數據訪問層和任務調度系統。後臺服務是一個相對比較成熟的領域,不少開源產品基本能夠開箱即用。
消息系統,對於日誌等可靠性要求不高的場景,則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功能更強一些也更復雜。
對於微服務安全認證受權機制一塊,目前業界雖然有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,能夠包含用戶信息但不暴露在公網上。
容器已經被社區接受爲交付微服務的一種理想手段,能夠實現不可變(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環境測試的鏡像才能升級發佈到生產環境,經過在流水線上設置一些質量門,保障應用高質量交付到生產。
注意,本文限於篇幅,對測試和CI等環節沒有涉及,但它們一樣是構建微服務架構的重要環節,也有衆多成熟的開源成熟產品可選。
技術選型雖然重要,但還只是微服務建設的一小部分工做,選型後的產品要在企業內部真正落地,造成完整的微服務技術棧體系,則後續還有大量集成、定製、治理、運維和推廣等工做。
本文僅限我的經驗視角,選型思路僅供參考借鑑。每一個企業的具體上下文(業務場景,團隊組織,技術架構等)各不相同,每一個架構師的背景經驗也各不相同,你們要結合實際本身作出選型,沒有最好的技術棧,只有相對較合適的技術棧。另外,好的技術選型是相互借鑑甚至PK出來的,歡迎你們討論,給出本身的微服務2.0技術棧選型意見。
Spring Boot
https://github.com/spring-projects/spring-boot
Alibaba Dubbo
https://github.com/alibaba/dubbo
Google gRPC
https://github.com/grpc/grpc
NetflixOSS Eureka
https://github.com/Netflix/eureka
Hashicorp Consul
https://github.com/hashicorp/consul
NetflixOSS Zuul
https://github.com/Netflix/zuul
Kong
https://github.com/Kong/kong
Spring Cloud Config
https://github.com/spring-cloud/spring-cloud-config
CTrip Apollo
https://github.com/ctripcorp/apollo
ElasticSearch
https://github.com/elastic/elasticsearch
Yelp Elastalert
https://github.com/Yelp/elastalert
Dianping CAT
https://github.com/dianping/cat
Zipkin
https://github.com/openzipkin/zipkin
Naver Pinpoint
https://github.com/naver/pinpoint
OpenTSDB
https://github.com/OpenTSDB/opentsdb
KairosDB
https://github.com/kairosdb/kairosdb
Argus
https://github.com/salesforce/Argus
InfluxDB
https://github.com/influxdata/influxdb
Prometheus
https://github.com/prometheus/prometheus
Grafana
https://github.com/grafana/grafana
Sensu
https://github.com/sensu/sensu
Esty 411
https://github.com/etsy/411
Zalando ZMon
https://github.com/zalando/zmon
NetflixOSS Hystrix
https://github.com/Netflix/Hystrix
Nginx
https://github.com/nginx/nginx
Apache Kafka
https://github.com/apache/kafka
Allegro Hermes
https://github.com/allegro/hermes
Apache Rocketmq
https://github.com/apache/rocketmq
Rabbitmq
https://github.com/rabbitmq/rabbitmq-server
Sohutv CacheCloud
https://github.com/sohutv/cachecloud
Twitter twemproxy
https://github.com/twitter/twemproxy
CodisLab codis
https://github.com/CodisLabs/codis
Dangdang Sharding-jdbc
https://github.com/shardingjdbc/sharding-jdbc
MyCAT
https://github.com/MyCATApache/Mycat-Server
Xxl-job
https://github.com/xuxueli/xxl-job
Dangdang elastic-job
https://github.com/elasticjob/elastic-job-lite
Apereo CAS
https://github.com/apereo/cas
JBoss keycloak
https://github.com/keycloak/keycloak
Spring cloud security
https://github.com/spring-cloud/spring-cloud-security
OpenID-Connect-Java-Spring-Server
https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server
Google Kubernetes
https://github.com/kubernetes/kubernetes
Apache Mesos
https://github.com/apache/mesos
Vmware Harbor
https://github.com/vmware/harbor
Netflix Spinnaker
https://github.com/spinnaker/spinnaker
Microservices in Practice – Key Architecture Concepts of an MSA
https://wso2.com/whitepapers/microservices-in-practice-key-architectural-concepts-of-an-msa/
微服務的設計與生態系統
http://servicecomb.incubator.apache.org/assets/slides/20170619/MSAPrinciple&EcoSystem.pdf