從字節跳動到火山引擎(三):替換 Spring Cloud,使用基於 Cloud Native 的服務治理

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本文中,火山引擎高級研發工程師夏巖將介紹 Spring Cloud 技術體系和雲原生技術體系的區別與聯繫,以及技術團隊關於如何藉助雲原生能力構建微服務系統的一些實踐。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Spring Cloud 技術體系簡介","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們通過時間線展開整個項目背景:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在我剛開始工作的時候(2010 年以前),可能還沒有云原生社區,當時 Java 體系是企業級開發的首選","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2010 年, Netflix 推出了 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Move to Cloud","attrs":{}},{"type":"text","text":" 計劃,將絕大部分的服務遷到了 AWS 上","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2012 年,Netflix 推出了 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Open Source Software Center","attrs":{}},{"type":"text","text":"(開源軟件中心倉庫),類似於 Apache Maven,提供了一些在上雲過程中沉澱下來的開源項目","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2014 年,Martin Fowler 發表了一篇博客:","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"Microservices","attrs":{}},{"type":"text","text":"[1],把當時一些公司的架構風格稱爲“微服務”。文章指出微服務架構有以下一些特點:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"高可維護性和可測試性","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務之間松耦合","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務可獨立部署","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務圍繞業務組織","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"被一些小團隊使用","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2015 年,Spring 社區圍繞之前 Netflix 沉澱的一些組件以及 Martin 提出的微服務理念,推出了 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Spring Cloud v1.0.0","attrs":{}},{"type":"text","text":",直到現在 Spring Cloud 還被廣泛使用。Spring Cloud v1.0.0 包含的組件較少,只有服務發現、配置管理等幾個核心組件","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以微服務架構的發展歷程並不是從論文走向產業化,而是從工程師的實踐中抽象出特點,最後形成完整的生態。到今天,Spring Cloud 組件已經比較的完善了,包含配置、服務解耦、服務發現、熔斷、路由、消息傳遞、API 網關、tracing、CI 管道和測試等。這些構成了整個 Spring Cloud 的生態","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Spring Cloud 是基於 Java 構建的微服務體系,在 Spring 和 Java 社區不停迭代的過程中,出現了一股全新的力量。2014 年 6 月 7 日,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Kubernetes 首次發佈","attrs":{}},{"type":"text","text":",當時還有 Docker Swarm、Mesos 這些調度平臺互相競爭","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從時間線可以看出來,Kubernetes 和 Spring Cloud 的發展是同時期的。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a2/a28e99885b0cb035678c7714161ec8c4.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"微服務的一些關鍵組件包括配置管理、服務發現、Load Balance、API 網關、中心化日誌、Metrics 等,Spring Cloud 這套體系和 Kubernetes 體系還是有一些交疊的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉例來說,Spring Cloud 有 Config Server(類似的有阿里開源的 Nacos、攜程開源的 Apollo),Kubernetes 則有 ConfigMap、Secret 等,它本身也有配置能力,但是比較弱。Kubernetes 的優勢在於它的組件和整個系統之間的交融度比較高,但在 Spring Cloud 裏可能是所有組件都要去兼容 Spring Cloud,以 Java 社區爲主,和其他語言的交互比較少。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d6/d6bede5a8cd2f6880813d7dc1175d0a6.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上圖展示了軟件的各種能力。可以看到 Kubernetes 包含的能力範圍比 Spring Cloud 更大。比較突出的有 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Auto Scaling","attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"DevOps","attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"進程隔離","attrs":{}},{"type":"text","text":",這些是 Spring Cloud 不能管轄到的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在當時,一些新興客戶會面臨一個問題:","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"對於基於 Java 的業務應用,開發的時候選擇哪種模式更好","attrs":{}},{"type":"text","text":"?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對此,現在我們更推薦使用 Kubernetes,因爲 Kubernetes 是一個語言無關的平臺。Spring Cloud 雖然是 JVM 體系,但是離開了 JVM 很多事情都做不了,因此不得不逼迫客戶隨着一起做變動,這個體驗其實不太好。所以我們後面也說服了同公司的一些團隊一起參與到 CNCF 雲原生技術架構的建設。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Spring Cloud 基礎能力替換","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"配置中心","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Spring Cloud 的 Config Server 具有較多能力:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Git 作爲配置倉庫","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"JDBC 和 Redis 提供了統一的配置抽象層","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但不太好用。一些個性化的需求比如配置中心的權限管理和熱加載,Spring Cloud Config Server 本身不支持,需要做二次開發。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於 Kubernetes,可以通過 ConfigMap 或者 Secret 按照更加原生的方式以環境變量、文件或啓動參數的方式注入到應用中去,就像敲 Linux 命令一樣方便。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們會發現 Spring Cloud Config Server 更像是一個獨立的軟件,Kubernetes 的 ConfigMap 更像是軟件內的功能,這就是兩者之間的區別。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"配置管理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes 的配置管理比較簡單,只需要在最終的啓動聲明裏增加 Environment,或者是將 ConfigMap 以 Volume 的方式加載進去就可以了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有時候會有同事問,Sping Cloud 雖然原生沒有熱加載能力,但是基於 SpringEventBus,甚至用一些第三方廠商的開源工具,也可以實現所謂的熱加載。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes 可以做到嗎?其實 Kubernetes 也是可以做到的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"環境變量當然是 immutable 掛進去,但是我們可以將一些可變的屬性以文件的方式掛載到宿主機容器化應用程序的 YMAL 文件裏去。隨着 ConfigMap 的變動,YMAL 也會同時變動,這時只需要讓應用能 watch 配置文件的變化,進行自動從加載就可以了。而熱加載本來就應該由應用自身實現。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes 本身也有 reload 能力,尤其是在擴展到其他語言的時候。字節內部使用 Go 語言比較多,大家只要能夠 reload 某一個文件或遠程地址,應用就可以將自己的行爲進行變化。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"服務發現","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Spring Cloud 和 Kubernetes 最大的不同在於","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"服務發現","attrs":{}},{"type":"text","text":"。我們絕大部分的功能都需要基於服務發現去做二次擴展,這時就會面臨服務發現的選擇問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Spring Cloud 的服務發現是基於 Eureka 的(後期也可以基於 Consul 進行),提供了自上報的機制和客戶端負載均衡,是一個 AP 系統。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes 則更像傳統的雲廠商,可幫助用戶創建機器/容器。平臺自然知道應用在哪裏,就可以通過 DNS 以及服務端負載均衡幫助導流。這樣的體驗是截然不同的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Spring Cloud 這套體系如果是 Eureka Client,永遠是要嵌入業務內部的,因爲在啓動的那一刻才知道應用在哪裏,通過 Utils 組件去獲取當前的 IP 地址。而 Kubernetes 並不需要由應用進行感知,這是非常大的區別。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接入 Kubernetes 的服務發現也是比較簡單的。只要創建一個 service 的資源(resource),定義其對應的 Label 即可。我認爲服務發現是 Kubernetes 的一個很大的優點。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Auto Scaling & Self Healing","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Auto Scaling 和 Self Healing 是 Spring Cloud 不具備的。在 Spring Cloud 裏,Eureka 會做一些健康檢查。其邏輯比較簡單:Eureka 不停地發請求,看心跳有沒有定時上報上來。但 Spring Cloud 只能知道服務是否健康,無法阻止訪問不健康的服務。如果要擴容或自恢復不健康的服務,需要在 Spring Cloud 裏做很多擴展。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f7/f7edf723a0c221dfc790e43a84cae39d.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes 這方面做得好一點。它本身提供 readless 的檢測,檢測完之後,如果調用失敗了,平臺就會幫助進行自動擴展和調度。要實現這樣的功能也很簡單,只要在應用或容器內開通一個端口,能夠檢測服務當前是否運行正常,可以比如說有延遲的參數,或者是間隔週期,在恰當時候進行一次請求,就可以知道應用是否就緒/健康。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5f/5fa0b2e05febbd9278682b27c13bed0b.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣會更符合所謂的微服務原子要素,因爲我們不光要能檢測系統是否健康,更希望能夠自動擴展。Kubernetes 社區還在做 HPA,甚至可以監測某些指標,隨着指標變化進行自動擴縮容。這些在 Spring Cloud 裏面都是非常難實現的。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Spring Cloud 流量治理能力替換","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"API Gateway","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"絕大部分用戶都會面臨一個很重要的問題:已經基於 Spring Cloud 做了很多流量治理工作,這個工作如何遷移到雲上?比如 API gateway,Spring Cloud Gateway 提供了很多能力,允許通過 filter 做很多開發,以完成自己的業務邏輯。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes 是怎麼實現的呢?它選擇了更大的一個場景,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"把整個生態開源出來了","attrs":{}},{"type":"text","text":"。這個開源生態下有很多工具, 比如 API Gateway 就有 Kong、Tyk、Gloo 等工具。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/89/89056cc492fe847cb394918c60197a92.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉一個現在比較火的產品 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Ambassador Edge","attrs":{}},{"type":"text","text":"。它原生提供了身份驗證、分佈式追蹤、多協議、rate limit 等功能。但在 Spring Cloud 體系裏實現這些功能就要做很多事情。Spring Cloud Gateway 的成本相對 Ambassador 等開源的網關成本要更高一些。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d7/d709e99979807a963878d00a7417a39c.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏舉一個例子,比如要用 Ambassador 構建一個 Keyclock 的鑑權體系。只要聲明幾個 YMAL 文件,就可以快速把整個流程走通。對比起來使用 Spring Cloud Gateway 構建時,要花很多時間去研究 Keyclock 有沒有 API 接口,Spring Cloud 要如何接入等。類似這種很通用的功能,可以考慮使用開源產品來直接替換。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Service Mesh","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Service Mesh 是另外一個更激動人心的話題,也是現在大家都在研究的前沿方向。傳統應用之間的通訊一直是很複雜的問題。比如 Spring Cloud Ribbon 做了很多安全、分流的工作,而這些工作其實跟業務本身相關度非常低。那麼這些能力可以提取出來嗎?社區給出了一個全新的答卷:","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Service Mesh","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Service Mesh 所做的事情是在節點之間通過一個 Proxy 代理層截獲所有流量,節點之間通過特定的網關進行轉發。因爲所有流量都被劫持了,可以做很多工作,包括 load balance、根據 label 做灰度發佈等。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/45/458e430d1c213e04a444d56c45f49108.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Spring Cloud 原生的默認設置無法實現全鏈路灰度,需要改 load balance 策略,這樣會導致同源數據裏的開發工作量增加。但是在雲原生體系裏,Istio 直接配一個 virtualservice 就能完成。雖然 Istio 有一些功能還在開發過程中,但使用 Istio 會更加容易,因爲它把跟業務不相關的屬性全部剝離出去,不再跟應用綁得那麼緊密了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"雙向 TLS","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉例來說,如果要提供雙向 TLS,傳統做法如果是應用自己來解決這個問題,就要先發個郵件通知要升級雙向 TLS 了,然後每個人都得配一下自己的證書,這個過程非常痛苦。現在有了 Service Mesh,只要通過一行聲明式就可以在不同的 Proxy 之間強制打開雙向驗證,保證整個網絡安全,至於服務跟 Proxy 之間的安全則由隔離性來保證。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5e/5e9bc8f1e14848c5d5d3cb3c24606418.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"熔斷","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於 Spring 社區主打的熔斷器功能,也可以直接使用 Istio 提供的 destinationRule 的能力,只需要簡單配置一些參數即可,比如訪問的最大可連接數、錯誤多少次之後會被拒絕、進行 Half-Open 重試的間隔等。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/70/7027f9e4f4bf0f5d65e0c728625c0e51.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Centralized Metrics","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Metrics 可以通過 sidecar 獲取,無需像傳統架構由應用獲取。如果應用本身還暴露出來一些業務的 Metrics,通過 Prometheus 的定製抓取可獲得這些數據。但如果只是想知道一些網絡吞吐 Metrics,現在應用本身也不需要直接提供,這樣又減少了應用業務的負擔。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/99/993de00942a1416a35656ff564a9f4ef.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結與展望","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Service Mesh 的出現提出了一個全新的思考方向:我們真的要將那麼多中間件功能放在應用本身嗎?恰好社區也在思考這個問題。CNCF 社區最近有一些新的博文,提出了一個叫做多運行時的架構體系(Multi-Runtime Microservices Architecture),這是一種全新的理念,認爲圍繞業務我們需要提供四種能力:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"生命週期管理","attrs":{}},{"type":"text","text":":管理應用什麼時候啓動,什麼時候關閉等。包含打包、健康檢查、部署、擴展、配置等功能","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"網絡管理","attrs":{}},{"type":"text","text":":包括服務發現、A/B test、灰度發佈、熔斷、點對點通訊、pub-sub 等","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"狀態管理","attrs":{}},{"type":"text","text":":包括 workflow 管理、緩存、應用狀態等","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"綁定","attrs":{}},{"type":"text","text":":包含數據傳輸,協議轉換等","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有了這些能力,開發人員只需關注業務邏輯,研發效率將會極大提高。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這些能力基於雲原生體系也可以做到。比如生命週期可以基於 Kubernetes 去做,網絡可以基於 Istio 去做,狀態管理可以基於 Cloud State 去做,綁定可以基於 Camel 去做。將這些東西組合在一起,業務單元就無需再關注這些事情。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而 Spring Cloud 爲了解決複雜的依賴問題,需要 maven 依賴,要依賴很多組件。當然這些事情慢慢都可以去掉,我們只要關心業務單元最核心的部分——","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"業務邏輯","attrs":{}},{"type":"text","text":",因爲只有這個部分纔是真正動態的邏輯。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/63/63d2c664ff69e76c911a5f107bc47b3f.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有了多運行時架構,會發現一個很大的變化:一旦業務單元變得足夠小,我們只需要去寫業務本身,進行數據的讀取和存儲就可以了。這時如果想獲得額外的服務發現、熔斷、配置管理等服務,只需要在外圍添加這些能力即可。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家可能會問,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"多運行時跟 FaaS 有什麼關係","attrs":{}},{"type":"text","text":"?可以看一下這張圖:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/bd/bdd6ba12ed74c8e507c7f20d8b417420.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單體架構的複雜度和規模化正相關,規模越大複雜度越高,中間件越複雜。FaaS 在複雜度提升的過程中,提高了拓展度但是複雜度卻背道而馳,Mecha 的設計是希望隨着規模化,可以將複雜度控制在一個較低的水平之內。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後展望得有點長遠,其實現在 Istio 還在開發的過程中。Istio v1.9 之後一直在提速,要一切爲了生產。整個社區在積極推動 sidecar 模式,要將很多非業務單元的東西移出來,比如負載均衡、服務發現、彈性伸縮。至於未來我們是否能走到多運行時路線上來,也是我們的展望,希望大家能夠跟我們一起來探討整個雲原生架構的未來。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Q&A","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Q1:Istio 有好用的控制器嗎?目前還沒有看到成熟的控制器,使用 Istio 的難度比較大。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"A:Istio 確實沒有好用的控制器,因爲現在看起來還是一個比較前沿的方向。已知的像 solo.io,他們做了一些產品,是直接基於 Envoy,沒有基於 Istio。但是我覺得社區是不斷髮展的,產品也會不斷推陳出新,可能要交給後面的人來解決這個問題。當前的確是沒有好用的控制器。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Q2:新的雲原生平臺和微服務能力是否是語言無關?有關的話選的是哪些?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"A:整個 CNCF 社區比 Spring Cloud 社區能打的原因就是因爲語言無關。如果將語言綁定,很多平臺可以自己自洽,就比較簡單。但是我們要接受現實:現在的互聯網體系,或者整個軟件體系,異構已經成爲了必然的趨勢。我們不可能要求所有人只會一門語言,這個時候可以用不同的語言去實現不同的事情,不同生態會有不同的構成。Kubernetes 以及 CNCF 社區就在做這件事情。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Q3:kube-proxy 能否完全替代 Spring Cloud Zuul 或 Gateway?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"A:這個問題其實還蠻有意思。kube-proxy 現在還是基於 iptables 和 IPVS 做轉發的工作,當然像 Cilium 基於 kube-proxy 的 eBPF 做了很多的工作。至於未來會不會完全取代,從我的經驗上來看,Service Mesh 融入了很多業務屬性,可能並不是 kube-proxy 想要去支撐的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Q4:Kubernetes 環境下,開發人員如何比較方便地調試本地代碼?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"A:現在還有一些單機版的 Kubernetes,比如 minikube 或者一些雲廠商,都會提供比較合理的本地直接訪問雲端服務的特性。個人更建議開發者嘗試一下 minikube/K3s, 就在本地運行,進行一些調試是非常方便的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[1]Microservices:","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"https://martinfowler.com/articles/microservices.html","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章