從零開始搭建公司微服務架構技術棧,這套架構絕了---

近年,Spring Cloud 儼然已經成爲微服務開發的主流技術棧,在國內開發者社區非常火爆。我近年一直在一線互聯網公司(攜程,拍拍貸等)開展微服務架構實踐,根據我個人的一線實踐經驗和我平時對 Spring Cloud 的調研,我認爲 Spring Cloud 技術棧中的有些組件離生產級開發尚有一定距離。比方說 Spring Cloud Config 和 Spring Cloud Sleuth 都是 Pivotal 自研產品,尚未得到大規模企業級生產應用,很多企業級特性缺失(具體見我後文描述)。

另外 Spring Cloud 體系還缺失一些關鍵的微服務基礎組件,比如 Metrics 監控,健康檢查和告警等。所以我在參考 Spring Cloud 微服務技術棧的基礎上,結合自身的實戰落地經驗,也結合國內外一線互聯網公司(例如 Netflix,點評,攜程,Zalando 等)的開源實踐,綜合提出更貼近國內技術文化特色的輕量級的微服務參考技術棧。希望這個參考技術棧對一線的架構師(或者是初創公司)有一個好的指導,能夠少走彎路,快速落地微服務架構。

這個參考技術棧和總體架構如下圖所示:

主要包含 11 大核心組件,分別是:

核心支撐組件

  1. 服務網關 Zuul

  2. 服務註冊發現 Eureka+Ribbon

  3. 服務配置中心 Apollo

  4. 認證授權中心 Spring Security OAuth2

  5. 服務框架 Spring MVC/Boot

監控反饋組件

  1. 數據總線 Kafka

  2. 日誌監控 ELK

  3. 調用鏈監控 CAT

  4. Metrics 監控 KairosDB

  5. 健康檢查和告警 ZMon

  6. 限流熔斷和流聚合 Hystrix/Turbine

                                  核心支撐組件

服務網關 Zuul

2013 年左右,InfoQ 曾經對前 Netflix 架構總監 Adrian Cockcroft 有過一次專訪 [附錄 1],其中有問 Adrian:“Netflix 開源這麼多項目,你認爲哪一個是最不可或缺的 (MOST Indispensable)”,Adrian 回答說:“在 NetflixOSS 開源項目中,有一個容易被忽略,但是 Netflix 最強大的基礎服務之一,它就是 Zuul 網關服務。Zuul 網關主要用於智能路由,同時也支持認證,區域和內容感知路由,將多個底層服務聚合成統一的對外 API。Zuul 網關的一大亮點是動態可編程,配置可以秒級生效”。從 Adrian 的回答中,我們可以感受到 Zuul 網關對微服務基礎架構的重要性。

Zuul 在英文中是一種怪獸,星際爭霸中蟲族裏頭也有 Zuul,Netflix 爲網關起名 Zuul,寓意看門神獸。

Zuul 網關在 Netflix 經過生產級驗證,在納入 Spring Cloud 體系之後,在社區中也有衆多成功的應用。Zuul 網關在攜程(日流量超 50 億),拍拍貸等公司也有成功的落地實踐,是微服務基礎架構中網關一塊的首選。其它開源產品像 Kong 或者 Nginx 等也可以改造支持網關功能,但是較複雜門檻高一點。

Zuul 網關雖然不完全支持異步,但是同步模型反而使它簡單輕量,易於編程和擴展,當然同步模型需要做好限流熔斷(和限流熔斷組件 Hystrix 配合),否則可能造成資源耗盡甚至雪崩效應(cascading failure)。

服務註冊發現 Eureka + Ribbon

針對微服務註冊發現場景,社區裏頭的開源產品當中,經過生產級大流量驗證的,目前只有 Netflix Eureka 一個,它也已經納入 Spring Cloud 體系,在社區中有衆多成功應用,例如攜程 Apollo 配置中心也是使用 Eureka 做軟負載。其它產品如 Zookeeper/Etcd/Consul 等,都是比較通用的產品,還需要進一步封裝定製纔可生產級使用。Eureka 支持跨數據中心高可用,但它是 AP 最終一致系統,不是強一致性系統。

Ribbon 是可以和 Eureka 配套對接的客戶端軟負載庫,在 Eureka 的配合下能夠支持多種靈活的動態路由和負載均衡策略。內部微服務直連可以直接走 Ribbon 客戶端軟負載,網關上也可以部署 Ribbon,這時網關相當於一個具有路由和軟負載能力的超級客戶端。

Ribbon 是蝴蝶結的意思。

服務配置中心 Apollo

Spring Cloud 體系裏頭有個 Spring Cloud Config 產品,但是功能遠遠達不到生產級,只能小規模場景下用,中大規模企業級場景不建議採用。攜程框架研發部開源的 Apollo 是一款在攜程和其它衆多互聯網公司生產落地下來的產品,開源兩年多,目前在 github 上有超過 4k 星,非常成功,文檔齊全也是它的一大亮點,推薦作爲企業級的配置中心產品。

Apollo 支持完善的管理界面,支持多環境,配置變更實時生效,權限和配置審計等多種生產級功能。Apollo 既可以用於連接字符串等常規配置場景,也可用於發佈開關(Feature Flag)和業務配置等高級場景。在《2018 波波的微服務基礎架構和實踐》課程中,第二個模塊就配置中心相關主題,會深度剖析攜程 Apollo 的架構和實踐,預計 6 月份推出,歡迎大家關注學習。

阿波羅是希臘神話中太陽神的意思

認證授權中心 Spring Security OAuth2

目前開源社區還沒有特別成熟的微服務安全認證中心產品,之前我工作過的一些中大型互聯網公司,比如攜程,唯品會等,在這一塊基本都是定製自研的,但是對一般企業來說,定製自研還是有門檻的。OAuth2 是一種基於令牌 Token 的授權框架,已經得到衆多大廠(Google, Facebook, Twitter, Microsoft 等)的支持,可以認爲是事實上的微服務安全協議標準,適用於開放平臺聯合登錄,現代微服務安全(包括單頁瀏覽器 App/ 無線原生 App/ 服務器端 WebApp 接入微服務,以及微服務之間調用等場景),和企業內部應用認證授權 (IAM/SSO) 等多種場景。

Spring Security OAuth2 是 Spring Security 基礎上的一個擴展,支持四種主要的 OAuth2 Flows,基本可以作爲微服務認證授權中心的推薦產品。但是 Spring Security OAuth2 還只是一個框架,不是一個端到端的開箱即用的產品,企業級應用仍需在其上進行定製,例如提供 Web 端管理界面,對接企業內部的用戶認證登錄系統,使用 Cache 緩存令牌,和微服務網關對接等,才能作爲生產級使用。在《2018 波波的微服務基礎架構和實踐》課程中,第一個模塊就是微服務安全架構和實踐相關主題,會深度剖析 OAuth2 原理和 Spring Security OAuth2 實踐,歡迎大家關注學習。

Spring Security OAuth2 是 Spring Security 框架的一個擴展。

服務框架 Spring/Boot

Spring 可以說是史上最成功的 Web App/API 開發框架之一,它融入了 Java 社區中多年來沉澱下來的最佳實踐,雖然有將近 15 年曆史,但目前的社區活躍度仍呈上升趨勢。Spring Boot 在 Spring 的基礎上進一步打包封裝,提供更貼心的 Starter 工程,自啓動能力,自動依賴管理,基於代碼的配置等特性進一步降低接入門檻。另外 Spring Boot 也提供 actuator 這樣的生產級監控特性,支持 DevOps 研發模式,它是微服務開發框架的推薦首選。

REST 契約規範 Swagger 和 Spring 有比較好的集成,使得 Spring 也支持契約驅動開發 (Contract Driven Development) 模型。對於一些中大規模的企業,如果業務複雜團隊較多,考慮到互操作性和集成成本,建議採用契約驅動開發模型,也就是開發時先定義 Swagger 契約,然後再通過契約生成服務端接口和客戶端,再實現服務端業務邏輯,這種開發模型能夠標準化接口,降低系統間集成成本,對於多團隊協同並行開發非常重要。

監控反饋組件

數據總線 Kafka

最初由 Linkedin 研發並在其內部大規模成功應用,然後在 Apache 上開源的 Kafka,是業內數據總線 (Databus) 一塊的標配,幾乎每一家互聯網公司都可以看到 Kafka 的身影。Kafka 堪稱開源項目的一個經典成功案例,其創始人團隊從 Linkedin 離職後還專門成立了一家叫 confluent 的企業軟件服務公司,圍繞 Kafka 周邊提供配套和增值服務。在監控一塊,日誌和 Metrics 等數據可以通過 Kafka 做收集、存儲和轉發,相當於中間增加了一個大容量緩衝,能夠應對海量日誌數據的場景。除了日誌監控數據收集,Kafka 在業務大數據分析,IoT 等場景都有廣泛應用。如果對 Kafka 進行適當定製增強,還可以用於傳統消息中間件場景。

Kafka 的特性是大容量,高吞吐,高可用,數據可重複消費,可水平擴展,支持消費者組等。Kafka 尤其適用於不嚴格要求實時和不丟數據的大數據日誌場景。

Kafka 創始人三人組,離開 Linkedin 後,創立了基於 Kafka 的創業公司 Confluent。

日誌監控 ELK

<![endif]-->

ELK(ElasticSearch/Logstash/Kibana)是日誌監控一塊的標配技術棧,幾乎每一家互聯網公司都可以看到 ELK 的身影,據稱攜程是國內 ELK 的最大用戶,每日增量日誌數據量達到 80~90TB。ELK 已經非常成熟,基本上是開箱即用,後續主要的工作在運維、治理和調優。

ELK 一般和 Kafka 配套使用,因爲日誌分詞操作還是比較耗時的,Kafka 主要作爲前置緩衝,起到流量消峯作用,抵消日誌流量高峯和消費(分詞建索引)的不匹配問題。一旦反向索引建立,日誌檢索是非常快的,所以日誌檢索快和靈活是 ElasticSearch 的最大亮點。另外 ELK 還有大容量,高吞吐,高可用,可水平擴容等企業級特性。

創業公司起步期,考慮到資源時間限制,調用鏈監控和 Metrics 監控可以不是第一優先級,但是 ELK 是必須搭一套的,應用日誌數據一定要收集並建立索引,基本能夠覆蓋大部分 Trouble Shooting 場景(業務,性能,程序 bug 等)。

另外用好 ELK 的關鍵是治理,需要制定一些規則(比如只收集 Warn 級別以上日誌),對應用的日誌數據量做好監控,否則開發人員會濫用,什麼垃圾數據都往 ELK 裏頭丟,造成大量空間被浪費,嚴重的還可能造成性能可用性問題。

ELK + Kafka 參考部署架構

調用鏈監控 CAT

Spring Cloud 支持基於 Zipkin 的調用鏈監控,我個人基於實踐經驗認爲 Zipkin 還不能算一款企業級調用鏈監控產品,充其量只能算是一個半成品,很多重要的企業級特性缺失。Zipkin 最早是由 Twitter 在消化 Google Dapper 論文的基礎上研發,在 Twitter 內部有較成功應用,但是在開源出來的時候把不少重要的統計報表功能給閹割了(因爲依賴於一些比較重的大數據分析平臺),只是開源了一個半成品,能簡單查詢和呈現可視化調用鏈,但是細粒度的調用性能數據報表沒有開源。

Google 大致在 2007 年左右開始研發稱爲 Dapper 的調用鏈監控系統,但在遠遠早於這個時間(大致在 2002 左右),eBay 就已經有了自己的調用鏈監控系統 CAL(Centralized Application Logging),Google 和 eBay 的設計思路大致相同,但是也有一些差別。CAL 在 eBay 有大規模成功應用,被稱爲是 eBay 的四大神器之一(另外三個是 DAL,Messaging 和 SOA)。

開源調用鏈監控系統 CAT 的作者吳其敏(我曾經和他同事,習慣叫他老吳),曾經在 eBay 工作近十年,期間深入消化吸收了 CAL 的設計。2011 年後老吳離開 eBay 去了點評,用三年時間在點評再造了一款調用鏈監控產品 CAT(Centralized Application Tracking),CAT 具有 CAL 的基因和影子,同時也融入了老吳在點評的探索實踐和創新。

CAT 是一款更完整的企業級調用鏈監控產品,甚至已經接近一個 APM(Application Performance Management)產品的範疇,它不僅支持調用鏈的查詢和可視化,還支持細粒度的調用性能數據統計報表,這塊是 CAT 和市面上其它開源調用鏈監控產品最本質的差異點,實際上開發人員大部分時間用 CAT 是看性能統計報表(主要是 CAT 的 Transaction 和 Problem 報表),這些報表相當於給了開發人員一把尺子,可以自助測量並持續改進應用性能。另外 CAT 還支持應用報錯大盤,自助告警等功能,也是企業級監控非常實用的功能。

CAT 在點評,攜程,陸金所,拍拍貸等公司有成功落地案例,因爲是國產調用鏈監控產品,界面展示和功能等更契合國內文化,更易於在國內公司落地。個人推薦 CAT 作爲微服務調用鏈監控的首選。

至於社區裏頭有人提到 CAT 的侵入性問題,我覺得是要一分爲二看,有利有弊,有耦合性但是性能更好,一般企業中基礎架構團隊會使用 CAT 統一爲基礎組件埋點,開發人員一般不用自己埋點;另外企業用了一款調用鏈監控產品以後,一般是不會換的,開發人員用習慣就好了,侵入不是大問題。

CAT 的 Transaction 報表

Metrics 監控 KariosDB

除了日誌和調用鏈,Metrics 也是應用監控的重要關注點。互聯網應用提倡度量驅動開發(Metrics Driven Development),也就是說開發人員不僅要關注功能實現,做好單元測試(TDD),還要做好業務層(例如註冊,登錄和下單數等)和應用層(例如調用數,調用延遲等)的監控埋點,這個也是 DevOps(開發即運維)理念的體現,DevOps 要求開發人員必須關注運維需求,監控埋點是一種生產級運維需求。

Metrics 監控產品底層依賴於時間序列數據庫(TSDB),最近比較熱的開源產品有 Prometheus 和 InfluxDB,社區用戶數量和反饋都不錯,可以採納。但是這些產品分佈式能力比較弱,定製擴展門檻比較高,一般建議剛起步量不大的公司採用。

如果企業業務和團隊規模發展到一定階段,建議考慮支持分佈式能力的時間序列監控產品,例如 KairosDB 或者 OpenTSDB,我本人對這兩款產品都有一些實踐經驗,KariosDB 基於 Cassandra,相對更輕量一點,建議中大規模公司採用,如果你們公司已經採用 Hadoop/HBase,則 OpenTSDB 也是不錯選擇。

KairosDB 一般也和 Kafka 配套使用,Kafka 作爲前置緩衝。另外注意使用 KariosDB 打點的話 tag 的值不能太離散,否則會有查詢性能問題,這個和 KariosDB 底層存儲結構有關係。Grafana 是 Metrics 展示標配,可以和 KariosDB 無縫集成。

Grafana 是 Metrics 展示標配,和主流時間序列數據庫都可以集成

健康檢查和告警 ZMon

除了上述監控手段,我們仍需要健康檢查和告警系統作爲配套的監控手段。ZMon 是德國電商公司 Zalando 開源的一款健康檢查和告警平臺,具備強大靈活的監控告警能力。ZMon 本質上可以認爲是一套分佈式監控任務調度平臺,它提供衆多的 Check 腳本(也可以自己再定製擴展),能夠對各種硬件資源或者目標服務(例如 HTTP 端口,Spring 的 Actuator 端點,KariosDB 中的 Metrics,ELK 中的錯誤日誌等等)進行定期的健康檢查和告警,它的告警邏輯和策略採用 Python 腳本實現,開發人員可以實現自助式告警。ZMon 同時適用於系統,應用,業務,甚至端用戶體驗層的監控和告警。

ZMon 分佈式監控告警系統架構,底層基於 KairosDB 時間序列數據庫

限流熔斷和流聚合 Hystrix+Turbine

2010 年左右,Netflix 也飽受分佈式微服務系統中雪崩效應(Cascading Failure)的困擾,於是專門啓動了一個叫做彈性工程的項目來解決這個問題,Hystrix 就是彈性工程最終落地下來的一個產品。Hystrix 在 Netflix 微服務系統中大規模推廣應用後,雪崩效應問題基本得到解決,整個體統更具彈性。

之後 Netflix 把 Hystrix 開源貢獻給了社區,短期獲得社區的大量正面反饋,目前 Hystrix 在 github 上有超過 1.3 萬顆星,據說支持奧巴馬總統選舉的系統也曾使用 Hystrix 進行限流熔斷保護 [參考附錄 2],可見限流熔斷是分佈式系統穩定性的強需求,Netflix 很好的抓住了這個需求並給出了經過生產級驗證的解決方案。Hystrix 已經被納入 Spring Cloud 體系,它是 Java 社區中限流熔斷組件的首選(目前還看不到第二個更好的產品)。

Turbine 是和 Hystrix 配套的一個流聚合服務,能夠對 Hystrix 監控數據流進行聚合,聚合以後可以在 Hystrix Dashboard 上看到集羣的流量和性能情況。

Hystrix 在英文中是豪豬獸的意思,豪豬獸通過身上的刺保護自己,Netflix 爲限流熔斷組件起名 Hystrix,寓意 Hystrix 能夠保護微服務調用。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/MaT4u7285833Fz9Qd1_m1g