精進雲原生 – Dubbo Kubernetes 最佳實踐

隨着雲原生的興起,越來越多的應用選擇基於 Kubernetes 進行部署,相關的 DevOps 等工具也應運而生。而 Dubbo 作爲微服務體系的主流解決方案,如何開發面向 Kubernetes 部署和運維的微服務應用是很多開發者與架構師要解決的問題。本文將從開發、部署、監控、運維等多維度視角分析,詳細的介紹如何基於 Dubbo 在Kubernetes 體系下構建高效、可靠的微服務應用。

 

上圖是今天演講會使用到的一個 Demo 工程。這個工程參考自 istio 的示例 book info 工程,總共部署四個應用。其中 Product Page 負責頁面的屬性整合,通過 http 接口對外暴露信息;Reviews、Details、Ratings 分別負責了評價、規則、評分等細分模塊信息。

01 使用 Dubbo Starter 初始化項目

 

對於很多開發來說,在 Java 體系下創建出新的應用,無外乎就是用 IDE 創建一個新的項目,或者用 maven 的 template,或者基於 Spring 的 Initializer。上圖使我們基於 Spring 的 Initializer 建立了我們自己的初始化項目的工程。我們點擊最上面的網址就能直接看到這個頁面了,你需要輸入對應的 group 和 artifact。然後選擇你希望用到的組件,比如 Nacos、Prometheus 的組件等等。

除此之外,我們在 IDE 裏提供了一個 Dubbo 的插件。這個插件可以通過上圖的方式進行安裝,或者如果你的倉庫裏已經用到了 Dubbo 的配置,它會提示你可以直接安裝。安裝完成後在右邊就會有一個對應的初始化的項目了。

上圖是一個示例,它在這裏建立了一個 Dubbo 的項目,然後你需要在這裏選中所需要的組件信息,最後點擊創建,之後它就會幫你在本地直接創建出一個全新的項目,然後你就可以在這個模版上開發了。

02 開發微服務之協議選型

 

初始化完應用以後,下一步就是開發服務,這裏我們選取一個和 Dubbo 關係較爲密切的環節——協議選型展開進行講解。

 

Dubbo 的 Triple 協議期望設計成一個易於瀏覽器訪問,且完全支持 gRPC 的協議。這就意味着,這樣的一個協議可以實現從端上到後端集羣之間的協議統一。

下面來看一下我們的項目,這是剛纔建立的一個項目,我現在把應用啓動起來,配置一些註冊中心的地址,這就是一個標準的 Spring 的啓動的流程。這裏定義了一個接口,這個接口返回了一個 “hello” 的內容信息。然後我用一個簡單的命令,就可以直接返回我的 hello world 的結果了。這樣對我們本身的測試來說有很大的幫助,也就是本地啓動之後,就可以直接測試接口。

03 基於 Kubernetes 快速初始化環境

 

對於微服務應用,如果需要在一個新的環境下部署,則必須前置部署包括但不限於註冊中心、配置中心、可觀測等組件。不管是從組件的數量上,還是單一組件的部署複雜度上來說,這都是一件耗時耗力的事情。爲了改變這一現狀,Dubbo 提供了一個快速拉起環境的工具,僅需 dubboctl manifest install 一鍵就可以在 Kubernetes 環境中部署起前面所說道的若干個組件,極大的降低整體部署的難度。

這裏有一個簡單的例子,環境拉起來之後,它會把所有的組件都會幫你拉起來。這裏埋一個點,這裏的 Prometheus 我們後面還會繼續使用。整個 Nacos 的地址,ZooKeeper 的地址都會直接提供給你。

 

這也是一個的例子。執行一個簡單的命令,然後本地會把 Kubernetes 的配置都準備好,它就會自動的幫你把組件都創建起來。也就是我們一鍵就可以獲取到所有 service 的部署。

04 快速部署應用到 Kubernetes 集羣中

 

爲了將應用正確地部署在 Kubernetes 中,主要有三個步驟需要完成,分別是應用容器化、無狀態部署和生命週期對齊。首先是應用容器化,顧名思義需要將應用運行在容器中。爲了實現容器化,通常我們需要準備一個 Dockerfile,然後通過一系列的腳本進行打包。但是其實我們可以把這一切通過一個 Maven 的插件來完成,今天要給大家介紹的是一個基於 Maven 的自動化構建插件,通過簡單的幾行配置就可以自動在 Maven 打包的過程中將編譯結果打包進容器中,實現快速構建。

可以看到,我只需要把我的 pom 裏添加一個對應的配置項依賴,通過一鍵 maven 的編譯模式,它就可以在 maven 打包的過程中幫你構建完鏡像,然後直接推送到遠端倉庫。這一切都只需要這一個命令就可以完成,而且一次性配置之後,未來你所有的鏡像更新都可以自動化的去做,不需要再去寫繁瑣的 dockerfile。

 

在應用實現容器化以後,下一步通過 Kubernetes 的資源配置將鏡像運行在 Kubernetes 容器中,右邊這個模板是 Kubernetes 中一個非常簡單的無狀態 Deployment 部署的模版。

這是一個簡單的例子,把 deployment 配置完之後,指定了剛纔的鏡像。同時我聲明瞭一個 service,這個 service 非常重要,它後面會作爲 frontend 應用入口的配置,但它是一個 Ingress 網關。可以看到 apply 鏡像之後,我們就可以在 K8s 體系上把這個環境 run 起來了。這裏做一個簡單的測試,我引入一個 curl 的容器,同樣我們可以用剛纔 curl 的命令訪問我新部署好的容器節點,可以看到它返回了 hello world 的數據信息。綜上,我們通過 deployment 的部署,可以在 K8s 上把容器 run 起來,同時它還可以對外提供服務,對外提供的服務我可以通過下面 curl 的命令進行調用。

 

最後是將應用部署到 Kubernetes 集羣中以後,由於 Kubernetes 是基於 POD 的生命週期進行調度的,在執行分批輪轉的過程中會基於 POD 的健康狀態進行調度,如果沒有配置對應的健康狀態,會導致實際上前一批應用還沒啓動成功就把後一批的應用給發佈了的情況。而爲了解決這個問題,Dubbo 提供了幾個 QoS 命令可以供 Kubernetes 調用查詢應用狀態。

上圖是一個例子。在整個應用啓動的時候,這裏 sleep 了 20 秒,然後配置了對應的 probe 信息。我們簡單推測一下,我在前面設置了等待 20 秒,那麼我的應用肯定要超過 20 秒才能起來。因爲修改了代碼,所以這裏需要重新編譯一下,用一鍵 maven 的編譯模式直接推上去。接下來要把 deployment apply 進去,進去之後 Pod 的狀態全都是 not ready 的,都是零的狀態。因爲前面 sleep 了 20 秒的時候,Dubbo 還沒啓動完,所以都是 not ready 的狀態。我們等 sleep 的階段過了,它就會變成 ready 的狀態,然後再進行分批這就是生命週期對齊的過程。所以 Kubernetes 知道應用什麼時候啓動成功了,什麼時候啓動失敗了,才能進行更好的調度。

05 雲原生微服務可觀測最佳實踐

 

可觀測體系整體來說分爲 Metrics、Tracing 和 Loggin 幾個模塊。首先對於 Metrics 我們主要關心幾個核心指標,比如延遲、流量、異常情況等等。對應到 Dubbo 的有包括 QPS、RT 等等的指標。

 

爲了更好地觀測這些指標,Dubbo 最新版本默認集成了 Metrics 收集能力,如果你部署的集羣中已經有了 Prometheus,僅需要簡單的配置幾個參數,即可實現 Metrics 的自動採集。

上面是一個演示的例子。我們在前面的 deployment 的例子上加上 Metrics 的採集信息,然後把它 apply 進去之後,我們就可以用整個 Grafana 導出過來。跑了一段時間之後,就會有對應的流量信息,比如 QPS 信息、RT 信息、成功率等等。得到這些指標後,我們還可以做一個告警。比如 QPS 從 100 突然跌到了 0,或者成功率突然跌了很多,這種情況我們需要做一個警示,讓大家知道當前發生的問題。我們可以基於 Prometheus 採集,做一個主動的推送,這就是告警的過程。

 

除了 Metrics 之外,Tracing 也是一個很重要的可觀測組成部分。目前業界主流爲了實現 Tracing 能力有兩種解決方案,一種是通過 SDK 依賴的方式引入 Tracing 相關組件,靜態化部署;另外一種是通過 Agent 的模式自動注入到代碼中動態部署。

大家可以看到,在這裏你只需要依賴 dependency 裏面加上 Dubbo 的 starter,配置項裏把 Tracing 能力打開,開啓一個指標的上報,9411 是我們 Zipkin 的一個後端。

 

這也是一個例子,我只需要配置這些配置,它的數據就會報到 Zipkin 上去,這裏的 dependency 直接加上。同樣的,用剛纔的命令進行打包,把鏡像推送上去,然後我們等待一下。推送的過程中可以看一下 Zipkin 這個組件,它也是在最前面我們在 K8s 初始化環境的時候一起拉起的,所以這一切你只需要在前面一次性部署的時候就可以擁有了。然後我們簡單的執行一個 curl 命令,因爲我需要讓我的環境有流量。部署完之後,用 curl 命令還是執行一下我們的獲取,這個其實已經把後端開發完了,它返回了真實的結果。接下來我們去 Zipkin 上看看能不能找到這條 Tracing。首先把 9411 映射過來,我們可以看到 curry 一下,這裏就會有對應的指標信息。整個全鏈路的調用信息這裏都可以看到,這就是全鏈路的接入的流程。相當於你只需要把前面的 dependency 加上,把上報的配置加上,之後的一切我都會幫你在後面完成以及上報。你看到對應的結果,就可以知道全鏈路上發生了什麼事情。

 

除此之外也可以基於 Agent 的模式進行部署,這個示例是基於 Skywaling 的配置默認。通過修改 deployment 的配置,可以實現自動掛在 javaagent 到應用中。

 

對於整個可觀測來說,我們可以通過 Metrics 看到 QPS、RT 等信息,通過 Tracing 看到全鏈路的訪問信息。這裏提供給我們一個很好的方案,就是我們要先去做服務的觀測,基於服務的觀測更好的排查整體的問題,第一時間知道應用掛沒掛。比如半夜兩點,它的可用率跌到零了。這個時候可以通過一系列的自動化機制告訴你應用出了問題,快速的進行恢復。這裏的快速恢復可以使用回滾,將流量隔離的方案他都可以快速的執行。基於這樣快速的從觀測到排查,再到快速恢復的鏈條,可以構建整個生產環境下的安全穩定的體系。所以我們觀測完之後的目標就是保證整個應用的穩定。

06 在 Kubernetes 中管理微服務應用

 

K8s 給我們帶來的收益包括快速擴縮容,即我可以很快的基於 K8s 從一個 Pod 變成多個 Pod。因爲 K8s 是基於整個 Image 的部署的流程,當鏡像打包出來後,你的環境就是固定的,只需要去橫向的擴容即可。橫向的快速擴容也會涉及到幾個瓶頸的點,如果我需要讓我的應用能夠快速擴容,比如我的應用提起來就要幾十分鐘,這種情況即使快速擴容了,等擴容完之後你的業務峯值也過去了,這裏就會引入到 Native Image。基於 Native Image,我們可以很好的實現整個 Serverless 的橫向的擴容。如果可以實現毫秒級的啓動,我可以在流量來的波峯,直接讓我的 Pod 橫向擴容好幾倍,當它的流量下去的時候就直接下掉,這樣就實現了成本的壓縮。另外還有一個問題是怎麼知道什麼時候要擴容?這就需要基於 Metrics 的觀測,基於一些歷史數據的分析,知道在某個時間點會有多少的流量,然後提前擴容,或者做一個自動化的擴容。

 

這裏我舉一個簡單的例子,比如我的 rating 上出了一些問題,我需要把它的故障摘除掉,返回一個 Mock 的結果。

 

這個時候你只需要在上面去配置一個上圖的規則,它就會返回。這就是 Admin 的使用流程,這裏就不再展開了,還有剛剛提到的我們在做 Go 版本的重構能力,後面也都會有更好的建設。

 

除此之外,基於 istio 的 Service Mesh 治理,我們前面協議選型的時候選了 Triple 協議,它完全是 based on HTTP 標準的。因此我們使用 istio 的整個體系之後,你只需要掛上 sidecar 它就會幫你去做流量治理。這一切的前提是你的協議一定是 istio 可見的。

比如你原來用是 Dubbo 2 的 Dubbo 的協議,它是一個私有的 tcp 協議,對於 istio 來說它很難分辨你的協議內容。如果你用了 Triple 協議,我們可以基於 HTTP 標準,你就可以知道你的 header 裏有什麼東西,可以去做一個流量的轉發。所以它完全擁抱 Mesh 的體系,可以支持我們所有 istio 的治理能力。

本文通過 Bookinfo 示例,介紹瞭如何基於新版 Starter 快速初始化一個項目、通過一系列雲原生工具實現應用快速部署、使用 Dubbo 原生可觀測能力進行線上診斷分析等,實現了從項目初始化到線上部署的全流程覆蓋,爲期望在 Kubernetes 下開發微服務的用戶提供了可以複製且大規模部署的樣板。

作者:江河清,阿里雲研發工程師、Apache Dubbo PMC

點擊立即免費試用雲產品 開啓雲上實踐之旅!

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章