2024年的雲原生架構需要哪些技術棧

crossoverJie發表於2024-04-11

背景

時間過得很快啊,一轉眼已經到了 2024 年,還記得 15 年剛工作那會掌握個 SSM/H(Spring/Struts2/Mybatis/Hibernate) 框架就能應付大部分面試了。

現在 CS 專業的新同學估計都沒聽說過 SSM😢

恰好從我剛開始工作時的移動網際網路熱潮到電商->共享經濟->toB 大熱->如今我都經歷了一遍,技術棧也有由最開始的單體應用+物理機發展到現在的 kubernetes 雲原生架構。

當然中途也經歷了幾個大的階段:
SOA服務化-> 微服務-> 雲原生-> 服務網格-> 無服務等幾個階段。

最近一份工作又主要是在做基礎架構,我認為了解的還算是比較全面的,所以本文我就以我的視角分享下我們在 2024 年應當使用哪些雲原生技術棧,因為涉及到的技術元件比較多,就不過多討論細節了。

但可以保證的是提到的技術棧都是我所用過的,優缺點都會提到,主打一個真實體驗。

作業系統

首先是作業系統,這裡有別於以往我們傳統的作業系統(Linux/Windows Server/MacOS),主要指的是雲原生的作業系統,沒有太多可以選擇的餘地,那就是 kubernetes

不過怎麼維護好 kubernetes 是一個難點問題,還記得去年下半年滴滴出過一次事故,網傳就是 kubernetes 升級出現的問題。

根據我們的經驗來看,對於小團隊更建議直接託管給雲廠商,維護 kubernetes 是一個非常複雜的工作,小團隊通常都是一職多能,自己維護更容易出問題。

當然大團隊有專人維護最好,即便是出問題也能快速響應,前提是自己能 cover 住這個風險。

因為我們是小團隊,所以考慮到成本和穩定性,我們也只使用了雲廠商的 kubernetes 能力,其餘的部分可控元件由我們自己維護(具體的後文會講到)

多雲的優勢與好處

既然都用了雲廠商的容器服務,那也要考慮到雲廠商故障可能帶來的問題;比如去年的阿里雲故障。

所以現在一些中大廠也會選擇多雲方案,將同一份程式碼部署再多個雲服務商,一旦其中一個出現問題可以快速切換。

但具體的實施過程中也有許多挑戰,比如最棘手也是最關鍵的資料一致性如何保證?

當然我們可以採用一些支援分散式部署的資料庫或中介軟體,他們本身是支援資料同步的;比如訊息佇列中的 Pulsar,它就可以跨級群部署以及訊息同步。

同時多雲部署對應的成本也會提升,在這個“降本增效”的大背景下也得慎重考慮;所以對此還有一個折中方案:

我們的技術架構需要具備快速遷移到其他雲服務的能力,比如我們內部有一些工具可以定期備份資源,比如 MySQL 的 binlog,一些中介軟體的後設資料,同時可以基於這些後設資料快速恢復業務。

一般遇到需要切換雲服務時都是一些極端情況,所以允許部分執行時的資料丟失也是能接受的,我們只要保證最核心的資料不會丟失從而不影響業務即可。

這個說起來簡單,但也需要我們花時間進行模擬演練;具體是否實施就得看公司是否接受雲服務當機帶來的損失以及演練所花的成本了。

我們是具備恢復後設資料能力的,但會丟失部分執行時的資料。

DevOps

既然我們已經選擇 kubernetes 作為我們雲原生的作業系統,那我們的持續整合與釋出也得圍繞著 kubernetes 來做。

上圖是一張使用 Git 配合 gitlab+ArgoCD 的流程圖,我們使用 gitlab 來管理原始碼,同時也可以利用他的 Pipline 幫我們做持續整合,最終使用 Argo 幫我們打通 kubernetes 的流程。

也就是我們常說的 GitOps

同時我們的回滾歷史版本,擴縮容都由 kubernetes 提供能力,我們的 DevOps 平臺只需要呼叫 kubernetes 的 API 即可。

當然還有現在流行 FinOps,我的理解主要是做雲成本的管理和最佳化,對應到我的工作就是回收一些不用的資源,在不影響業務的情況下適當的降低一些配置😳。

Service Mesh

接下來便是我認為最重要的 Service Mesh 環節了,這個的背景故事就多了,本質上我覺得這都是由 RPC(Remote Process Call) 引起的也是分散式所帶來的。

由最開始的單機的本地函式呼叫開始:

local+------>remote +------> micro-service+----->service-mesh
               +                  |                    +
               v                  v                    v
           +---+----+       +-----+------+        +----+----+
           | motan  |       | SpringCloud|        | Istio   |
           | dubbo  |       | Dubbo3.0   |        | Linkerd |
           | gRPC   |       | SOFA       |        |         |
           +--------+       +------------+        +---------+

主要經歷了以上三個重要的階段,分別是 RPC 框架到微服務再到現在的服務網格。

  • RPC 框架主要幫我們簡化了分散式通訊,只專注於業務本身
  • 微服務框架的出現可以更好的幫我們治理大批次的服務,比如一些限流、路由、降級等功能,讓我們分散式應用更加健壯。
  • 而如今的服務網格讓我們的應用程式更加適配雲原生,專注於業務研發而不再需要去維護微服務框架;將這些基礎功能全部下沉到我們的基礎層,同時也帶來了不弱於微服務框架的功能性。

但使用 Istio 也有著不低的技術門檻,我覺得如果滿足以下條件更推薦使用 Istio:

  • 應用已經接入 kubernetes 平臺
  • 應用之間採用的是 gRPC 通訊框架
  • API 閘道器也遷移到 Istio Gateway
  • 公司至少預備一個專人維護 Istio(這裡的維護不一定是對程式碼的瞭解,但一定要對 Istio 本身的功能和文件足夠了解)

除此之外使用 SpringCloudDubbokratosgo-zero之類的微服務框架也未嘗不可。

我之前有寫過兩篇關於 Istio 的 文章,也可以用做參考:

  • 在 kubernetes 環境中實現 gRPC 負載均衡
  • 服務網格實戰-入門Istio

可觀測性


現如今可觀測系統也變得越來越重要,個人覺得評價一個技術團隊重要指標就是他們的可觀測系統做的如何。

一個優秀的可觀測系統可以清晰得知系統的執行狀態、高效的排查問題、還有及時的故障告警。

要實現上述標準就需要我們可觀測系統的三個核心指標了:

  • Metrics,藉助它我們可以在 Grafana 中繪製出各種直觀的皮膚,可以更加全面的瞭解我們系統的執行狀態

  • Trace則是可以幫助我們構建出系統呼叫的全貌,透過一個 trace 就可以知道一個請求經歷了哪些系統,在哪個環節出了問題。
  • Logs 就比較好理解了,就是我們自己在應用裡列印的一些日誌;只是和以往的開發模式略有不同的是:在雲原生體系中更推薦直接輸出到標準輸出和標準錯誤流中,一些第三方採集元件可以更方便的進行採集。

我們自己的可觀測系統經歷過一次迭代,以往的技術棧是:

  • Metrics 使用 VictoriaMetrics:這是一個完全相容 Prometheus 的時序資料庫,但相對 Prometheus 來說更加的節省資源。
  • Trace 選擇的是 SkyWalking,這也是 Java trace 領域比較流行的技術方案。
  • Logs:使用 filebeat 採集日誌然後輸出到 ElasticSearch 中,這也是比較經典的方案。

去年底我們做了一次比較大的改造,主要就是將 SkyWalking 換為了 OpenTelemetry,這是一個更加開放的社群,也逐漸成為雲原生可觀測的標準了。

使用它我們的靈活性更高,不用與某些具體的技術棧進行繫結;目前 logs 還沒有切換,社群也還在 beta 測試中,後續成熟後也可以直接用 OpenTelemetry 來收集日誌。

我也寫的有一篇 SW 遷移到 OpenTelemetry 的文章,感興趣的朋友可以參考:

  • 實戰:如何優雅的從 SkyWalking 切換到 OpenTelemetry

訊息佇列

這裡單獨把訊息佇列拎出來是因為我目前主要是在維護公司內部的訊息佇列,同時業務體量大了之後訊息佇列變得非常重要了,通常會充當各個業務線對接的橋樑,或者是資料庫同步 MySQL 的渠道,總之用處非常廣泛。

這裡還是推薦更貼合雲原生的訊息佇列 Pulsar,由於它存算分離的架構特性,配合kubernetes 的特性可以實現快速的擴縮容,相比 kafka 來說更易維護;同時社群活躍度也非常高,在 Bug 修復和支援新特性方面比較積極。

Pulsar官方支援的客戶端也比較全面:

Language Documentation Release note Code repo
Java User doc
API doc
Standalone Bundled
C++ User doc
API doc
Standalone Standalone
Python User doc
API doc
Standalone Standalone
Go client User doc
API doc
Standalone Standalone
Node.js User doc
API doc
Standalone Standalone
C#/DotPulsar User doc Standalone Standalone

還有一個問題是:如何部署我們的 Pulsar 叢集,是私有化部署還是購買雲服務(目前 Pulsar的商業公司 streamnative 和國內的騰訊雲都有類似的服務)

我們之前有諮詢過價格,相對來說還是自己部署價效比最高;和前文講的一樣,只使用雲廠商的 kubernetes 服務,在這基礎上部署我們的自己的服務。

因為得益於 Pulsar 社群的活躍,即便是自己維護出現問題也可以及時得到反饋;同時自己平時踩的坑也可以反哺社群。

之前也寫過一些關於 Pulsar 的系列文章,感興趣的可以查閱:

  • 在 kubernetes 環境下如何優雅擴縮容 Pulsar
  • Pulsar3.0新功能介紹
  • Pulsar負載均衡原理及最佳化
  • 白話 Pulsar Bookkeeper 的儲存模型
  • Pulsar壓測及最佳化

業務框架

最後是業務框架的選擇,決定這個的前提是我們先要確定選擇哪個語言作為主力業務語言。

雖然這點對於 kubernetes 來說無關緊要,下面以我比較熟悉的 Java 和 Golang 進行介紹。

Java

Java 可選的技術方案就比較多了,如果我們只是上了 kubernetes 但沒有使用服務網格;那完全可以只使用 springboot 開發 http 介面,就和開發一個單體應用一樣簡單。

只是這樣會缺少一些服務治理的能力,更適用於中小型團隊。

如果團隊人員較多,也沒使用服務網格時;那就推薦使用前文介紹的微服務框架:比如 Dubbo、SpringCloud 等。

當有專門的雲原生團隊時,則更推薦使用服務網格的方案,這樣我們就能綜合以上兩種方案的優點:

  • 程式碼簡潔,只是需要將 http 換為 gRPC。
  • 同時利用 Istio 也包含了微服務框架的能力。

Golang

Golang 其實也與 Java 類似,中小團隊時我們完全可以只使用 Gin 這類 http 框架進行開發。

而中大型團隊在 Golang 生態中也有對標 DubboSpringCloud 的框架,比如 kratosgo-zero 等。

得益於 Golang 的簡潔特性,我覺得比使用 Java 開發業務更加簡單和“無腦”。

同樣的後續也可以切換到服務網格,直接採用 gRPC 和 Golang 也非常適配,此時團隊應該也比較成熟了,完全可以自己基於 gRPC 做一個開發腳手架,或者也可以使用 Kratos 或者是 go-zero 去掉他們的服務呼叫模組即可。

總結

以上就是個人對目前流行的技術方案的理解,也分別對不同團隊規模進行了推薦;確實沒有完美的技術方案,只有最合適的,也不要跟風選擇一些自己不能把控的技術棧,最終吃虧的可能就是自己。

參考連結:

  • https://levelup.gitconnected.com/gitops-in-kubernetes-with-gitlab-ci-and-argocd-9e20b5d3b55b
  • https://grpc.io/

相關文章