微服務架構被認爲是構建大型複雜系統的最佳理論指導,其採用了分而治之、單一職責、關注點分離等方法論來設計系統架構。微服務的實現方式和思路有很多種,本文簡述基於kubernetes的微服務平臺建設思路及技術選型。

應用架構發展歷史

要了解微服務架構提出的背景,首先我們來看一下應用架構的發展歷程,如下圖所示:

  • 單體應用:傳統應用的開發技術爲.NET、J2EE等技術,開發完成後部署在websphere、weblogic這樣的商業容器中(或者開源的tomcat)。應用間的交互一般通過CORBA、DCOM這樣RPC風格的組件進行,此時並沒有服務化的概念。部署的環境一般爲小型機、服務器。
  • SOA架構:業界在意識到了系統集成標準化的重要性後,提出了SOA的理念。SOA強調的是服務化、標準化,通過制定統一的應用接口標準,所有的應用都可以方便的提供服務,並且也可以快速調用其他應用提供的服務,通過一個集中化的服務中間件,系統集成的效率大大提高。經典的落地場景就是ESB企業服務總線。交互協議多用基於SOAP的web service。在這個時期,出現了虛擬化技術,應用可以部署在vmware虛擬機中,大大提高了資源的利用效率。
  • 微服務:其實在martin fowler寫那篇經典的微服務論述文章前,業界很多公司早就在實踐微服務了。國外的有netflix oss技術棧,國內的有大名鼎鼎的dubbo框架。esb在落地過程中碰到了很多問題,集中化的中心節點很容易造成性能瓶頸,並可能產生單點故障,在互聯網公司的實踐中上千甚至上萬的服務,已經不可能通過esb去承載。微服務與傳統的esb區別就是去中心化,去掉了中心esb節點,取而代之的是一個分佈式的服務化框架,提供服務註冊、服務發現、限流熔斷、配置管理等一系列高級功能。由於互聯網的流行,此時的交互協議多爲輕量級的RESTful風格協議。這個時期,是雲計算真正落地的時期,以aws爲代表的Iaas技術大行其道,從根本上改變了應用部署的方式。(事實上,netflix就是基於亞馬遜的EC2彈性節點來動態的增加、減少微服務實例的,應用架構的靈活性大大增加)
  • 雲原生:雲原生其實就是微服務的一種落地,但我認爲,雲原生已經可以看作是下一代的應用架構了。它從平臺層面重新審視整個微服務實施中的關注點,並且以宏觀視角給出了完整的解決方案,強調與devops的整合,整體抽象層次最高,且做到了語言無關,這是上一代微服務所做不到的。需要注意的是,在雲原生時代,應用和基礎架構需要進行深度集成,換句話說,只有你在kubernetes這樣的雲基礎設施上部署的應用,纔可以算成是“雲原生”應用。應用充分利用了基礎架構的能力(微服務能力),這纔是“雲原生”的真諦(天生被設計需要跑在雲上的應用)。

雲原生概念的提出可謂是業界對軟件工程長期發展的一個高度總結和最佳實踐集合,以下是紅帽公司對於雲原生概念的解釋,個人是比較認可的

微服務解決方案

提到微服務,就不得不提到Spring Cloud和Kubernetes(太早的dubbo就忽略了),這兩者社區都非常活躍,都有完整的微服務解決方案,有大量的落地案例。但他們解決問題的思路和方式完全不同,這也決定了兩者未來的發展方向。這邊進行一個全方位的對比,對比完之後你就知道,爲什麼kubernentes被稱之爲下一代的基礎應用架構。

微服務公共關注點

首先我們來看下,紅帽公司總結的所謂的微服務公共關注點。可以說,不管你用哪種方式、哪個平臺去實現微服務,這些內容都是你必須要去關注並實現的。

可以看到,裏面差不多一半關注點是和運維相關的。這麼看來,似乎拿spring cloud和kubernetes比較有點不公平,spring cloud只是一個開發框架,對於應用如何部署和調度是無能爲力的,而kubernetes是一個運維平臺。也許用spring cloud+cloud foundry去和kubernetes比較才更加合理,但需要注意的是,即使加入了cloud foundry的paas能力,spring cloud仍然是“侵入式”的且語言相關,而kubernetes是“非侵入式”的且語言無關。

Spring Cloud 與 Kubernetes 功能對比

先來看下這張圖 可以說,spring cloud關注的功能是kubernetes的一個子集,下面來詳細對比一下:

關注點 Spring Cloud Kubernetes
自愈和自動伸縮 kube-controller-manager
調度和發佈 kube-scheduler+Deployment
配置管理 Spring Cloud Config/Nacos ConfigMap
服務發現和LB Eureka/Nacos Service+CoreDNS/Istio
彈性和容錯 Hystrix/Resillience4j Istio
API網關 Zuul/Spring Cloud Gateway Ingress/Istio Gateway
服務安全 Spring Cloud Security Istio
調用鏈監控 Spring Cloud Sleuth+ZipKin Istio+Jaeger/ZipKin
Metrics監控 actuator+Spring Boot Admin Istio+Prometheus
日誌收集 Spring Cloud Sleuth+ELK fluentd/Istio

可以看出,兩邊的解決方案都是比較完整的。kubernetes這邊,在Istio還沒出來以前,其實只能提供最基礎的服務註冊、服務發現能力(service只是一個4層的轉發代理),istio出來以後,具有了相對完整的微服務能力。而spring cloud這邊,除了發佈、調度、自愈這些運維平臺的功能,其他的功能也支持的比較全面。相對而言,雲廠商會更喜歡kubernetes的方案,原因就是三個字:非侵入。平臺能力與應用層的解耦,使得雲廠商可以非常方便的升級、維護基礎設施而不需要去關心應用的情況,這也是我比較看好service mesh這類技術前景的原因。

談談Istio

關於Istio,其實已經討論的比較多了。作爲近兩年微服務領域最熱門的話題,這裏我不準備展開Istio的技術細節,感興趣的可以登陸 servicemesher技術社區 或者 Istio官方網站 查閱資料,這裏只談談我個人的看法。根據官方網站的描述,Istio主要被設計用來 連接、保護、控制、觀測 服務,下面分別來講一下:

連接

主要是定義路由規則,配合virtual service和destination rule實現各種高級路由功能,能夠非常細粒度的實現灰度、金絲雀、多版本路由等能力,這塊是istio的最大亮點,spring cloud這部分能力完全缺失,沒得比。

保護

主要是端到端的mTLS加密、服務間認證授權、終端用戶認證授權,這部分Spring Cloud提供了Spring Cloud Security可以實現最終用戶認證功能,但Spring Security本質上來講是在單體應用的背景下設計出來的,運用在分佈式系統上有諸多不便(例如Session同步),端到端加密和服務間認證也是沒有的。

控制

主要是策略(policy),例如黑白名單、限速等各類控制能力,通過適配器(Adapter)實現,並且可以自定義適配器擴展各類個性化的控制能力。這部分由於需要通過mixer來實現,歷來爭議很大(Istio最新版本policy功能都是默認關閉的)。Spring Cloud可以通過Hystrix/Resillience4j來實現限速、熔斷等方面的功能,理論上說istio的設計是更好的,因爲適配器是可以靈活擴展的。可惜mixer的設計問題,現在處於比較尷尬的地位,mixer v2計劃把policy做到sidecar裏面,大方向是對的,可以期待一下。

觀測

主要是遙測(telemetry)。一般我們說的可觀測性(Observability),包含 Logging、Tracing、Metrics 這三部分,istio也都有解決方案。Logging和Metrics不說了,都是通過envoy收集好以後上報給基礎設施後端(也是通過mixer,不過這個是異步的,稍微好一點)。Tracing比較有意思,istio官方原來的宣傳是完全不需要修改代碼,即可實現分佈式跟蹤,但其實還是需要修改一點代碼的(雖然不多)。經過我們張超盟大哥的反饋,istio官方修改了措辭,變成了只需要修改一點代碼。大家可以看下官方的介紹頁面 https://istio.io/docs/tasks/telemetry/distributed-tracing/overview/,可以看到bookinfo這個示例裏面,應用是做了header的上下文傳遞的工作的。這部分來說,雖然spring cloud也需要引入sleuth的jar包,但因爲spring cloud本來就是一個侵入式框架,這部分反而感覺侵入性沒istio那麼大(sleuth會自動注入到RestTemplate裏面去埋點,業務代碼不需要改動)。當然如果追求真正的無侵入(spring cloud sleuth使用的基礎是你的應用要基於spring cloud框架進行開發),那麼需要使用pinpoint或者skywalking這樣的基於字節碼注入的tracing框架。

結論

上面我詳細分析了目前主流的微服務框架spring cloud與kubernetes,並對各自的優劣進行了對比。在目前這個時間節點,對於中小型的技術團隊來說,我推薦的組合就如文章標題所說:使用spring boot+kubernetes來實現微服務架構,這是一個比較清爽的搭配。如果是沒有歷史包袱的,且底層基礎設施準備上k8s的技術團隊來說,個人認爲現在來說已經沒有必要使用spring cloud了。畢竟kubernetes已經提供了比較完整的微服務解決方案,何苦再自己搞一套服務註冊、服務發現、配置管理的輪子呢(況且還是語言綁定)?

當然選擇kubernetes,代價就是限流、容錯、安全、路由等能力的缺失,所以說究竟怎麼選擇,還是取決於團隊與公司自身的實際需求。而對於istio來說,目前我不推薦上生產。service mesh總體來說還是處於一個非常早期的階段,但可以保持高度關注。由於service mesh自身無侵入的特性,未來在kubernetes上升級sidecar也是完全透明的,可以期待一下mixer v2出來以後的service mesh的技術走向。

基於spring boot+kubernetes的微服務架構技術選型如下:(僅代表個人觀點)

  • 服務註冊與服務發現:kube-proxy+coredns
  • 配置管理:ConfigMap
  • api網關:Ingress(外部網關,位於集羣入口,https加密,證書管理,域名管理,限速等)+zuul(內部網關,用於服務轉發,並可以開發比較靈活的各類定製化適配器)
  • metrics監控:prometheus+spring actuator
  • 調用鏈監控:skywalking
  • 日誌收集:EFK

參考資料

https://developers.redhat.com/blog/2016/12/09/spring-cloud-for-microservices-compared-to-kubernetes/

相關文章