十幾年前就有一些公司開始踐行服務拆分以及SOA,六年前有了微服務的概念,因而你們開始思考SOA和微服務的關係和區別。最近三年Spring Cloud的大火把微服務的實踐推到了高潮,而近兩年K8S在容器編排的地位肯定以後你們又開始實踐起以K8S爲核心的雲原生思想和微服務的結合如何去落地,2018年又多出一個ServiceMesh服務網格的概念,你們又在思考如何引入落地ServiceMesh,ServiceMesh和K8S以及Spring Cloud的關係如何等等。程序員
確實有點亂了,這一波又一波的熱潮,幾乎每兩年都會來一波有關微服務架構理念和平臺,許多公司還沒完成微服務的改造就又提出了服務+容器道路,又有一些公司打算從微服務直接升級成ServiceMesh。本文嘗試總結一下我見過的或實踐過的一些微服務落地方式,而且提出一些本身的觀點,但願拋磚引玉,你們能夠暢談一下本身公司的微服務落地方式。數據庫
其實在2006年在使用.NET Remoting作服務拆分的時候(其實當時咱們沒有意識到這叫服務拆分,這是打算把一些邏輯使用獨立的進程來承載,以Windows服務形式安裝在不一樣服務器上分散壓力),咱們使用了F5來作服務的負載均衡。沒有所謂的服務發現,針對每個服務,咱們直接在程序配置文件中寫死F5的IP地址和端口,使用Excel來記錄全部服務在F5的端口地址以及服務實際部署的IP:端口,而後在F5進行配置。F5在這裏作了負載均衡、簡單的路由策略(相同的客戶端老是優先路由到相同的後端)以及簡單的白名單策略等等。後端
雖然個人標題說這是古典玩法,可是能夠說不少公司若是沒有上RPC,沒有上Spring Cloud,也沒有上K8S的話極可能就是這樣的玩法。不管是v0.2仍是v0.1,本質上服務是固定在虛擬機或實體機部署的,若是須要擴容,須要遷移,那麼確定須要修改反向代理或負載均衡器的配置。少數狀況下,若是調整了反向代理或負載均衡器的IP地址,那麼還可能會須要修改客戶端的配置。緩存
貌似互聯網公司這樣玩的很少,傳統企業或是遊戲服務端是比較適合服務總線這種架構的,若是服務和服務之間的協議不統一的話,要在客戶端作協議轉換的工做比較痛苦,若是能夠由統一的中間層接入全部協議統一進行轉換的話,客戶端會比較輕量,可是這種架構的很大問題在於服務總線的擴容和可靠性。安全
其實RPC框架我我的喜歡JSON over HTTP,雖然咱們知道HTTP和JSON序列化性能確定不如一些精簡的二進制序列化+TCP,可是優勢是良好的可讀性、測試方便、客戶端開發方便,並且我不認爲15000的QPS和20000的QPS對於通常應用有什麼區別。服務器
總的來講,咱們會有一個集羣化的分佈式配置中心來充當服務註冊的存儲,好比ZK、Consul、Eureka或etcd。咱們的服務框架會有客戶端和服務端部分,客戶端部分會提供服務的發現、軟負載、路由、安全、策略控制等功能(可能也會經過插件形式包含Metrics、Logging、Tracing、Resilience等功能),服務端部分對於RPC框架會作服務的調用也會輔助作一些安全、策略控制,對於RESTful的話就服務端通常除了監控沒有額外的功能。架構
好比使用Spring Cloud來玩,那麼:併發
在以前《朱曄和你聊Spring系列S1E8:湊活着用的Spring Cloud(含一個實際業務貫穿全部組件的完整例子)》一文中,我有一個完整的例子介紹過Spring Cloud的這套玩法,能夠說的確Spring Cloud給了咱們構建一套微服務體系最基本的東西,咱們只須要進行一些簡單的擴展和補充,好比灰度功能,好比更好的配置服務,就徹底能夠用於生產。 這種模式和以前0.x的很大區別是,服務的註冊有一個獨立的組件,註冊中心完成,經過配合客戶端類庫的服務發現,至少服務的擴容很輕鬆,擴容後也不須要手動維護負載均衡器的配置,至關於服務端從死到活的一個重大轉變。並且在1.0的時代,咱們更多看到了服務治理的部分,開始意識到成百上千的服務,若是沒有Metrics、Logging、Tracing、Resilience等功能來輔助的話,微服務就是一個災難。負載均衡
Spring Cloud已經出了G版了,表示Netflix那套已經進入了維護模式,許多程序員表示表示扶我起來還能學。我認爲Spring Cloud這個方向實際上是挺對的,先有開源的東西來填補空白,慢慢再用本身的東西來替換,可是開發比較苦,特別是一些公司基於Spring Cloud辛苦二次開發的框架圍繞了Netflix那套東西來作的會比較痛苦。總的來講,雖然Spring Cloud給人的感受很亂,變化很大,大到E到G版的升級不亞於在換框架,並且組件質量層次不齊,可是它確實是一無全部的創業公司可以起步微服務的很少的選擇之一。若是沒有現成的框架(不是說RPC框架,RPC框架雖是微服務功能的80%重點,但倒是代碼量20%的部分,工做量最大的是治理和整合那套),基於Spring Cloud起步微服務,至少你能夠當天起步,1個月完成適合本身公司的二次開發改造。框架
若是說1.0時代你們糾結過Dubbo仍是Spring Cloud,2.0時代我相信也有一些公司上過Mesos的「賊船」,咱們不是先知很難預測什麼框架什麼技術會在最後存活下來,可是這倒是也給技術帶來了很多痛苦,相信仍是有很多公司在幹Mesos轉K8S的事情。
若是引入了K8S,那麼服務發現能夠由K8S來作,不必定須要Eureka。咱們能夠爲Pod建立Service,經過Cluster虛擬IP的方式(如上圖所示,經過IP tables)路由到Pod IP來作服務的路由(除了Cluster IP方式也有的人對於內部鏈接會採用Ingress方式去作,路由方面會更強大,不過這是否是又相似v0.2了呢?)。固然,咱們還能夠更進一步引入內部DNS,使用內部域名解析成Cluster IP,客戶端在調用服務的時候直接使用域名(域名能夠經過配置服務來配置,也能夠直接讀取環境變量)便可。若是這麼幹的話其實就沒有Eureka啥事了,有的公司沒有選擇這種純K8S服務路由的方式仍是使用了註冊中心,若是這樣的話其實服務註冊到註冊中心的就是Pod IP,仍是由微服務客戶端作服務發現的工做。我更喜歡這種方式,我以爲K8S的服務發現仍是弱了一點,並且IP tables的方式讓人沒有安全感(IPVS應該是更好的選擇),與其說是服務發現,我更願意讓K8S只作容器調度的工做以及Pod發現的工做。
雖然K8S能夠作一部分服務發現的工做,咱們仍是須要在客戶端中去實現更多的一些彈力方面的功能,所以我認爲2.0時代只是說是微服務框架結合容器、容器調度,而不能是脫離微服務框架自己徹底依靠K8S實現微服務。2.0和1.0的本質區別或者說加強仍是很明顯,那就是咱們能夠全局來統籌解決咱們的微服務部署和可靠性問題,在沒有容器和容器調度這層抽象以前,有的公司經過實現自動化虛擬機分配拉起,加上自動化初始腳原本實現自動的微服務調度擴容,有相似的意思,可是很是花時間並且速度慢。K8S真正讓OPS成爲了DEV而不是執行者,讓OPS站在整體架構的層面經過DEV(咱不能說開發DSL文件不算開發吧)資源和資源之間的關係來統籌整個集羣。在只有十幾個微服務若干臺服務器的小公司可能沒法發揮2.0容器雲的威力,可是服務器和服務一多,純手工的命令式配置容易出錯且難以管理,K8S真的釋放了幾十個運維人力。
因而ServiceMesh服務網格的概念騰空而出,巧妙解決了這幾個問題:
說了這麼多ServiceMesh的優點,咱們來看一下這種模式的性能問題。想一下各類模式下客戶端要請求服務端整個HTTP請求(跳)次數:
總的來講,3跳並非ServiceMesh的瓶頸所在,而更多的可能性是Istio的倔強的架構理念。Istio認爲策略和遙測不該該耦合在Sidecar Proxy應該放到Mixer,那麼至關於在調用服務的時候還須要額外增長Mixer的同步請求(來得到策略方面的放行)。Istio也在一直優化這方面,好比爲Mixer的策略在Proxy作本地緩存,爲遙測數據作批量上報等等。雖然通過層層優化,可是Istio目前的TPS不足2000,仍是和通常的RPC能達到的20000+有着十倍的差距,說不定未來Istio會有架構上的妥協,把Mixer變爲非直接依賴,策略方面仍是採用相似Pilot統一管理配置下發的方式,遙測方面仍是由Sidecar直接上報數據到Mixer。
我我的認爲,ServiceMesh是一個很是正確的道路,並且ServiceMesh和K8S結合會更好,理由在於:
可是,能夠看到目前ServiceMesh還不算很是成熟,Istio在不斷優化中,Linkerd 2.x也想再和Istio拼一下,到底誰會勝出還難以知曉,通過以前Dubbo vs Spring Cloud的折騰,Mesos vs K8S的折騰,VM vs Docker的折騰,是否還能經得起折騰Istio vs Linkerd 2呢?我建議仍是再看一看,再等一等。
做爲應用服務自己而言,只須要和本地代理作通信調用外部服務、緩存、數據庫、消息隊列,不須要關心服務和資源所在何地,以及背後的實際服務的組件形態。固然,這只是一個暢想了,對於有狀態的資源,Mesh的難度很大,對於相似DB這樣的資源由於調用層次並不複雜,也不太會存在異構場景,Mesh的意義不大,綜合起來看Everything Mesh的投入產出比相比Service Mesh仍是小不少。
若是搞Java微服務的話,Spring Boot是離不開的,可是是否要用Spring Cloud呢?個人觀點是,在目前階段若是沒有什麼更好的選擇,仍是應該先用。Spring Cloud和K8S首先並非矛盾的東西,K8S是偏運維的,主要作資源整合和管理,若是完全沒有服務治理框架純靠K8S的話會很累,並且功能不完整。開發和架構能夠在Spring Cloud方面深耕,運維能夠在容器和K8S方面發力,兩套體系能夠協做造成目前來講比較好的微服務基石。至於K8S的推行,這必定是一個正確的方向,並且和軟件架構方面的改進工做一點不矛盾,畢竟K8S是脫離於具體語言和平臺的。
至於Service Mesh,它作的事情和Spring Cloud是有不少重複的,在未來Istio若是發展的更好的狀況下,應該能夠替代Spring Cloud,開發人員只須要用Spring Boot開發微服務便可,客戶端方面也能夠很瘦,不須要過多關心服務如何通信和路由,服務的安全、通信、治理、控制都由Service Mesh進行(可是,是否有了Sidecar,客戶端真的徹底不須要SDK了呢?我認爲可能仍是須要的,對於Tracing,若是沒有客戶端部分顯然是不完整的,雖然Sidecar是localhost可是仍是跨進程了)。
Spring Cloud目前雖然針對K8S和Istio作了一些整合,可是並沒看到一套針對ServiceMesh的最佳實踐出來,是否未來Spring Cloud會在微服務這方面作退化給ServiceMesh讓步還不得而知。總的來講,長期我看好Spring Boot + K8S + Istio的組合,短時間我認爲仍是Spring Boot + K8S + Spring Cloud這麼用着。
本文總結了各類微服務落地的形態,因爲技術多樣,各類理念層出不窮,形成了微服務的落地方式真的很難找到兩家相同的公司,本文中咱們介紹了:
固然,可能還會有更多的方式:
也可能不少公司在混用各類方式,具備N套服務註冊中心,正在作容器化遷移,想一想就頭痛,微服務的理念層出不窮伴隨着巨頭之間的技術戰役,苦的仍是架構和開發,固然,運維可能也苦,2019新年快樂,Enjoy微服務!