微服務自2014年3月由Martin Fowler首次提出以來,在Spring Cloud、Dubbo等各類微服務框架的幫助下,以燎原之勢席卷了整個IT技術界,成為了最主流的分散式應用解決方案。但仍然還有很多問題沒有得到根本性的解決,比如技術門檻高、多語言支持不足、代碼侵入性強等。如何應對這些挑戰成 ...
微服務自2014年3月由Martin Fowler首次提出以來,在Spring Cloud、Dubbo等各類微服務框架的幫助下,以燎原之勢席卷了整個IT技術界,成為了最主流的分散式應用解決方案。但仍然還有很多問題沒有得到根本性的解決,比如技術門檻高、多語言支持不足、代碼侵入性強等。如何應對這些挑戰成為了下一代微服務首要回答的問題。直到服務網格(Service Mesh)被提出,這一切都有了答案。
1 微服務之殤
時光回到2017年初,那時所有主流的微服務框架,不管是類庫性質的Finagle、Hystrix,還是框架性質的Spring Cloud、Dubbo,本質上都歸於應用內解決方案,都存在以下三個問題:
- 技術門檻高:隨著微服務實施水平的不斷深化,除了基礎的服務發現、配置中心和授權管理之外,團隊將不可避免的在服務治理層面面臨各類新的挑戰,包括但不限於分散式跟蹤、熔斷降級、灰度發佈、故障切換等,這對團隊提出了非常高的技術要求。
- 多語言支持不足:對於稍具規模的團隊,尤其在高速成長的互聯網創業公司,多語言的技術棧是常態,跨語言的服務調用也是常態,但目前開源社區上並沒有一套統一的、跨語言的微服務技術棧。
- 代碼侵入性強:主流的微服務框架(比如Spring Cloud、Dubbo)或多或少都對業務代碼有一定的侵入性,框架替換成本高,導致業務團隊配合意願低,微服務落地困難。
這些問題加起來導致的結果就是,在實施微服務的過程中,小團隊Hold不住,大公司推不動。
2 另闢蹊徑
如何解決上述三個問題呢?最容易想到的是代理模式,在LB層(比如Nginx、Apache HTTP Server)處理所有的服務調用,以及部分服務治理問題(比如分散式跟蹤、熔斷降級)。但這個方案有兩個顯著的缺點,第一,中心化架構,代理端自身的性能和可用性將是整個系統的瓶頸;第二,運維複雜度高,業務團隊笑了,運維團隊哭了。
難道這就是桃園嗎?
服務網格(Service Mesh)應運而生!自2016年9月Linkerd第一次公開使用之後,伴隨著Linkerd、Envoy、Istio、NGINX Application Platform、Conduit等新框架如雨後春筍般不斷涌現,在微服務之後,服務網格和它的邊車(Sidecar)模式引領了IT技術界2017一整年的走向。
3 服務框架選型
服務框架是一個比較成熟的領域,有太多可選項。 Spring Boot/Cloud 由於Spring社區的影響力和Netflix的背書,目前可以認為是構建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是谷歌近年新推的一套RPC框架,基於protobuf的強契約編程模型,能自動生成各種語言客戶端,且保證互操作。支持HTTP2是gRPC的一大亮點,通訊層性能比HTTP有很大改進。Protobuf是在社區具有悠久歷史和良好口碑的高性能序列化協議,加上Google公司的背書和社區影響力,目前gRPC也比較火,github上有超過13.4k星。目前看gRPC更適合內部服務相互調用場景,對外暴露HTTP RESTful介面可以實現,但是比較麻煩(需要gRPC Gateway配合),所以對於對外暴露API場景可能還需要引入第二套HTTP RESTful框架作為補充。總體上gRPC這個東西還比較新,社區對於HTTP2帶來的好處還未形成一致認同,建議謹慎投入,可以做一些試點。
4 服務網格
4.1 元定義
首先,我們來看一下服務網格的提出者William Morgan是如何描述它的。
A service mesh is a dedicated infrastructure layer for handling service-to-service communication. Consists of a control plane and data plane (service proxies act as “mesh”). - William Morgan, What’s a Service Mesh? And Why Do I Need One?
上面這段話非常清晰的指明瞭服務網格的職責,即處理服務間通訊,這正是服務治理的核心所在。而a dedicated infrastructure layer
這幾個單詞將服務網格和之前所有的微服務框架(framework)劃清了界限,也即服務網格獨立於具體的服務而存在,這從根本上解決了前文提到的老的微服務框架在多語言支持和代碼侵入方面存在的問題。並且,由於服務網格的獨立性,業務團隊不再需要操心服務治理相關的複雜度,全權交給服務網格處理即可。
那你可能會問,這不跟之前提到的代理模式差不多嗎?區別在於服務網格獨創的邊車模式。針對每一個服務實例,服務網格都會在同一主機上一對一併行部署一個邊車進程,接管該服務實例所有對外的網路通訊(參見下圖)。這樣就去除了代理模式下中心化架構的瓶頸。同時,藉助於良好的框架封裝,運維成本也可以得到有效的控制。
4.2 演化史
追本溯源,服務網格從無到有可分為三個演化階段(參見下圖)。第一個階段,每個服務各顯神通,自行處理對外通訊。第二個階段,所有服務使用統一的類庫進行通訊。第三個階段,服務不再關心通訊細節,統統交給邊車進程,就像在TCP/IP協議中,應用層只需把要傳輸的內容告訴TCP層,由TCP層負責將所有內容原封不動的送達目的端,整個過程中應用層並不需要關心實際傳輸過程中的任何細節。
4.3 時間線
最後,再來回看一下服務網格年輕的歷史。雖然服務網格的正式提出是在2016年9月,但其實早在2013年,Airbnb就提出了類似的想法——SmartStack,只不過SmartStack局限於服務發現,並沒有引起太多關註,類似的還有Netflix的Prana和唯品會的OSP Local Proxy。2016年服務網格提出之後,以Linkerd和Envoy為代表的框架開始嶄露頭角,並於2017年先後加入CNCF基金(Cloud Native Computing Foundation),最終促使了一代新貴Istio的誕生。2018年,Istio將發佈1.0版本,這也許意味著微服務開始進入2.0時代。
5 後臺服務選型
後臺服務主要包括消息系統,分散式緩存,分散式數據訪問層和任務調度系統。後臺服務是一個相對比較成熟的領域,很多開源產品基本可以開箱即用。
消息系統,對於日誌等可靠性要求不高的場景,則Apache頂級項目 Kafka 是社區標配。對於可靠性要求較高的業務場景,kafka其實也是可以勝任,但企業需要根據具體場景,對 Kafka的監控和治理能力進行適當定製完善,Allegro公司開源的 hermes 是一個可參考項目,它在Kafka基礎上封裝了適合業務場景的企業級治理能力。阿裡開源的 RocketMQ也是一個不錯選擇,具備更多適用於業務場景的特性,目前也是Apache頂級項目。 RabbitMQ是老牌經典的MQ,隊列特性和文檔都很豐富,性能和分散式能力稍弱,中小規模場景可選。
對於 緩存治理 ,如果傾向於採用客戶端直連模式(個人認為緩存直連更簡單輕量),則SohuTv開源的 cachecloud 是一款不錯的Redis緩存治理平臺,提供諸如監控統計,一鍵開啟,自動故障轉移,線上伸縮,自動化運維等生產級治理能力,另外其文檔也比較豐富。如果傾向採用中間層Proxy模式,則Twitter開源的 twemproxy和CodisLab開源的 codis是社區比較熱的選項。
對於 分散式數據訪問層 ,如果採用Java技術棧,則噹噹開源的 shardingjdbc是一個不錯的選項,分庫分表邏輯做在客戶端jdbc driver中,客戶端直連資料庫比較簡單輕量,建議中小規模場景採用。如果傾向採用資料庫訪問中間層proxy模式,則從阿裡Cobar演化出來的社區開源分庫分表中間件 MyCAT是一個不錯選擇 。proxy模式運維成本較高,建議中大規模場景,有一定框架自研和運維能力的團隊採用。
任務調度系統,個人推薦徐雪裡開源的 xxl-job,部署簡單輕量,大部分場景夠用。噹噹開源的 elastic-job也是一個不錯選擇,相比xxl-job功能更強一些也更複雜。
6 架構技術範圍
為解決單體架構下的各種問題,微服務架構應運而生。與其構建一個臃腫龐大、難以馴服的怪獸,還不如及早將服務拆分。微服務的核心思想便是服務拆分與解耦,降低複雜性。微服務強調將功能合理拆解,儘可能保證每個服務的功能單一,按照單一責任原則(Single Responsibility Principle)明確角色。 將各個服務做輕,從而做到靈活、可復用,亦可根據各個服務自身資源需求,單獨佈署,單獨作橫向擴展。
微服務技術是程式員繞不開的話題,在這裡給大家推薦一個交流學習群:650385180,裡面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分散式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,以下的課程體系圖也是在群里獲取。相信對於已經工作和遇到技術瓶頸的碼友,在這個群里會有你需要的內容。
7 小結
以上就是我對服務網格的一些簡單介紹,歡迎留言交流,和大家一起過過招。