因为运行上千个应用容器pod会消耗大量资源,实现更少的worker节点和资源占用成本高,所以在使用Kubernetes时,启动快和内存占用低是批判的。在Kubernetes平台上运行容器化微服务时,内存占用是比吞吐量更重要的考虑因素,因为:微服务更需要资源密集型(相对于CPU密集型),因为它们需要持续运行,开销成本成倍增加单体应用变成多个微服务(例如20个微服务占用大约20GB的存储空间)这些情况极大地影响了serverless功能和Java部署模型的演进。直到现在,许多企业开发人员选择Go、Python或Node.js替代方案来解决性能瓶颈,直到Quarkus(一种基于kubernetes的原生Java堆栈)的出现改变了这一点。本文介绍如何使用Quarkus执行性能优化以在kubernetes平台上运行无服务器函数。Container-first的设计理念因为Java生态系统中的传统框架必须对框架进行初始化,包括配置文件处理、类路径扫描、类加载、注解处理、元模型构建等,这些过程是必不可少的,所以相对来说比较耗费资源。如果使用几个不同的框架,消耗的资源也会成倍增加。Quarkus通过“左移”将所有资源密集型操作转移到构建阶段来解决这些Java性能问题。代码和框架分析、字节码转换和动态元模型生成都在构建阶段完成,而且只执行一次,结果:一个高度优化的运行时可执行文件,启动非常快,无需经过那些传统的启动过程,整个过程只执行一次在构建阶段一次。更重要的是,QuarkusBuild阶段:Quarkus支持构建原生可执行文件,与传统的云原生Java堆栈相比,Quarkus具有良好的性能,包括快速启动和极小的驻留集大小(RSS)内存占用,具有即时扩展能力和高密度内存利用率。QuarkusRSSandBootTimeMetrics此处有一个示例,展示了如何使用Quarkus将Java无服务器项目构建为本地可执行文件。1.使用Quarkus创建一个无服务器Maven项目下面的命令生成一个Quarkus项目(例如quarkus-serverless-native)来创建一个简单的函数:$mvnio.quarkus:quarkus-maven-plugin:1.13。4.Final:create\-DprojectGroupId=org.acme\-DprojectArtifactId=quarkus-serverless-native\-DclassName="org.acme.getting.started.GreetingResource"2.要构建本机可执行文件,您需要使用GraalVMforJava该程序构建本机可执行文件。您可以选择任何GraalVM发行版,例如OracleGraalVMCommunityEdition(CE)或Mandrel(OracleGraalVMCE的下游发行版)。Mandrel旨在支持在OpenJDK11上构建Quarkus原生可执行文件。打开pom.xml,您将找到原生设置。您将使用它来构建本机可执行文件。nativenative注意:你可以安装GraalVM或本地的Mandrel分布。您还可以下载Mandrel容器镜像来构建它(就像我所做的那样),因此您还需要一个在本地运行的容器引擎(例如Docker)。假设你已经开启容器运行时,你需要运行Maven命令:使用Docker作为容器引擎:$./mvnwpackage-Pnative\-Dquarkus.native.container-build=true\-Dquarkus.native.container-runtime=docker使用Podman作为容器引擎:$./mvnwpackage-Pnative\-Dquarkus.native.container-build=true\-Dquarkus.native.container-runtime=podman输出应该以BUILDSUCCESS结尾。NativeBuildLogs不使用JVM直接运行本地可执行文件:$target/quarkus-serverless-native-1.0.0-SNAPSHOT-runner输出信息类似:____________________________--/_??_\////_|/_\///_////__/-//_///_//__|/,_/,/_//\\--\___\_\____/_/|_/_/|_/_/|_|\____/___/INFO[io.quarkus](主要)quarkus-serverless-native1.0.0-SNAPSHOTnative(由Quarkusxx.xx.xx提供支持。)开始于0.019秒。收听:http://0.0.0.0:8080INFO[io.quarkus](main)Profileprodactivated.INFO[io.quarkus](main)Installedfeatures:[cdi,kubernetes,resteasy]太棒了!开机只用了19ms。您的运行时间可能略有不同。用linux的ps工具测试,结果内存占用还是很低。检测方法是:在应用程序运行时,打开另一个终端,运行以下命令:$ps-opid,rss,command-p$(pgrep-frunner)输出类似:PIDRSSCOMMAND1024611360target/quarkus-serverless-native-1.0.0-SNAPSHOT-runner进程只占用11MB内存。很小!注意:各种应用程序(包括Quarkus)的常驻集大小和内存占用量因环境而异,并随着应用程序加载而增加。您还可以使用RESTAPI访问此功能。输出应该是HelloRESTEasy:$curllocalhost:8080/helloHelloRESTEasy3.将函数部署到Knative服务。如果您尚未创建命名空间,请立即在OKD(OpenShiftKubernetes发行版)中创建命名空间(例如quarkus-serverless-native)并将此本机可执行文件部署为无服务器函数。然后添加quarkus-openshift扩展:$./mvnw-qquarkus:add-extension-Dextensions="openshift"在src/main/resources/application.properties文件中添加如下内容配置Knative与Kubernetes的相关资源:quarkus.container-image.group=quarkus-serverless-nativequarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000quarkus.native.container-build=truequarkus.kubernetes-client.trust-certs=truequarkus.kubernetes.deployment-target=knativequarkus.kubernetes.deploy=truequarkus.openshift.build-strategy=docker构建本地可执行文件,直接部署到OKD集群:$./mvnwcleanpackage-Pnative注意:使用oclogin命令提前确保您登录到正确的项目(例如quarkus-serverless-native)。输出应以BUILDSUCCESS结尾。构建本地二进制文件并将其部署为Knative服务需要几分钟时间。服务创建成功后,使用kubectl或oc命令工具查看Knative服务及版本信息:$kubectlgetksvcNAMEURL[...]quarkus-serverless-nativehttp://quarkus-serverless-native-[...].SUBDOMAINTrue$kubectlgetrevNAME配置名称K8S服务名称生成就绪原因quarkus-serverless-native-00001quarkus-serverless-nativequarkus-serverless-native-000011True4。访问本地可执行函数运行kubectl命令搜索具有serverless函数的节点:$kubectlgetrt/quarkus-serverless-native输出信息类似:NAMEURLREADYREASONquarkus-serverless-nativehttp://quarkus-serverless-restapi-quarkus-serverless-native.SUBDOMAINTrue使用curl命令访问上面信息中的URL字段:$curlhttp://quarkus-serverless-restapi-quarkus-serverless-native.SUBDOMAIN/hello之后就没有了超过1小时秒,在OKD集群访问Quark时会得到和本地操作一样的结果:HelloRESTEasy我们查看运行节点的日志,会发现本地可执行文件是作为Knative服务运行的。原生Quarkus日志接下来是什么?您可以使用GraalVM发行版优化您的Java无服务器函数,以使用Knative中的Kubernetes将它们部署为无服务器函数。Quarkus支持简单的配置以在常见的微服务中进行性能优化。本系列的下一篇文章将指导您在不更改代码的情况下跨多个无服务器平台实现可移植功能。(丹尼尔哦,CCBY-SA4.0)