在Kubernetes中最佳化Java無伺服器 - Danie

banq發表於2021-06-10

在 Kubernetes 上實現更快的啟動、更小的記憶體佔用執行無伺服器函式。
由於執行數千個應用程式 pod 的費用以及使用更少的工作節點和其他資源來節省成本,在Kubernetes 中更快的啟動和更小的記憶體佔用總是很重要的。在 Kubernetes 上的容器化微服務上,記憶體比吞吐量更重要,因為:
  • 由於永久性(與 CPU 週期不同),它更昂貴
  • 微服務成倍增加開銷成本
  • 一個單體應用變成N 個微服務(例如,20 個微服務 ≈ 20GB)

這會顯著影響無伺服器功能開發和 Java 部署模型。這是因為許多企業開發人員選擇了 Go、Python 和 Nodejs 等替代方案來克服效能瓶頸——直到現在,多虧了Quarkus,一個新的 Kubernetes 原生 Java 堆疊。本文介紹瞭如何最佳化 Java 效能以使用 Quarkus 在 Kubernetes 上執行無伺服器功能。
 

容器優先設計
Java 生態系統中的傳統框架在初始化這些框架所需的記憶體和啟動時間方面是有代價的,包括配置處理、類路徑掃描、類載入、註釋處理以及構建世界的元模型,框架需要這些操作。對於不同的框架,這一次又一次地成倍增加。Quarkus 透過將幾乎所有開銷“左移”到構建階段來幫助解決這些 Java 效能問題。透過在構建時只進行一次程式碼和框架分析、位元組碼轉換和動態元模型生成,您最終會得到一個高度最佳化的執行時可執行檔案,它啟動速度超快,並且不需要傳統啟動的所有記憶體,因為工作在構建階段完成一次。
更重要的是,Quarkus 允許您構建具有效能優勢的本機可執行檔案,包括驚人的快速啟動時間和非常小的駐留集大小 (RSS) 記憶體,與傳統雲相比,可實現即時擴充套件和高密度記憶體利用率——本機 Java 堆疊。
 
下面是一個快速示例,說明如何使用 Quarkus透過Java 無伺服器專案構建本機可執行檔案。

1. 建立 Quarkus 無伺服器 Maven 專案
此命令生成一個 Quarkus 專案(例如,quarkus-serverless-native)來建立一個簡單的函式:

$ mvn io.quarkus:quarkus-maven-plugin:1.13.4.Final:create \
       -DprojectGroupId =org.acme \
       -DprojectArtifactId =quarkus-serverless-native \
       -DclassName = "org.acme.getting.started.GreetingResource"


2. 構建原生可執行檔案
您需要一個 GraalVM 來為 Java 應用程式構建本機可執行檔案。您可以選擇任何 GraalVM 發行版,例如Oracle GraalVM 社群版 (CE)Mandrel(Oracle GraalVM CE 的下游發行版)。Mandrel 旨在支援在 OpenJDK 11 上構建 Quarkus 原生可執行檔案。
開啟pom.xml,您將找到此native配置檔案。您將使用它來構建本機可執行檔案:

<profiles >
    <profile >
        <id > native </id >
        <properties >
            <quarkus.package.type > native </quarkus.package.type >
        </properties >
    </profile >
</profiles >


假設您已經啟動了容器執行時,請執行以下 Maven 命令之一。
對於Docker

$ ./mvnw package -Pnative \
-Dquarkus.native.container-build=true \
-Dquarkus.native.container-runtime=docker

對於 Podman::

$ ./mvnw package -Pnative \
-Dquarkus.native.container-build=true \
-Dquarkus.native.container-runtime=podman


在沒有 Java 虛擬機器 (JVM) 的情況下直接執行本機可執行檔案:
$ target/quarkus-serverless-native-1.0.0-SNAPSHOT-runner
超音速!19 毫秒啟動。時間可能因您的環境而異。

正如 Linuxps實用程式報告的那樣,它還具有極低的記憶體使用率。在應用程式執行時,在另一個終端中執行此命令:
$ ps -o pid,rss,command -p $(pgrep -f runner)
 

 將函式部署到 Knative 服務
請在OKD(OpenShift Kubernetes 分發版)上建立一個名稱空間(例如,)以將此本機可執行檔案部署為無伺服器功能。然後為 Knative 服務部署新增一個擴充套件:quarkus-serverless-nativequarkus-openshift
$ ./mvnw -q quarkus:add-extension -Dextensions="openshift"
新增以下變數src/main/resources/application.properties以配置 Knative 和 Kubernetes 資源:

quarkus.container-image.group=quarkus-serverless-native
quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000
quarkus.native.container-build=true
quarkus.kubernetes-client.trust -certs=true
quarkus.kubernetes.deployment-target=knative
quarkus.kubernetes.deploy=true
quarkus.openshift.build-strategy=docker

構建原生可執行檔案,然後直接部署到OKD叢集:
$ ./mvnw clean package -Pnative

輸出應以BUILD SUCCESS. 完成原生二進位制構建並部署新的 Knative 服務需要幾分鐘時間。成功建立服務後,您應該使用kubectl或oc命令工具看到 Knative 服務 (KSVC) 和修訂版 (REV) :

$ kubectl get ksvc
NAME URL   [ ... ]
quarkus-serverless-native http: // quarkus-serverless-native- [ ... ] .SUBDOMAIN True

$ kubectl get rev
NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON
quarkus-serverless -native-00001 quarkus-serverless-native quarkus-serverless-native-00001   1            

 

訪問原生可執行函式
透過執行以下kubectl命令檢索無伺服器函式的端點 :
$ kubectl get rt/quarkus-serverless-native

訪問路由URL與curl命令:
$ curl http://quarkus-serverless-restapi-quarkus-serverless-native.SUBDOMAIN/hello

當您訪問 OKD 叢集中 Quarkus 執行 pod 的日誌時,您將看到本機可執行檔案正在作為 Knative 服務執行。

相關文章