Redian新闻
>
优化 Kubernetes 中的 Java 无服务器函数 | Linux 中国

优化 Kubernetes 中的 Java 无服务器函数 | Linux 中国

科技
 
导读:在 Kubernetes 中运行无服务器函数时,实现更快的启动速度和更小的内存占用。           
本文字数:5814,阅读时长大约:7分钟

由于运行上千个应用程序容器荚(Pod)所耗费的资源多,令它实现较少工作节点和资源占用所需成本也较高,所以在使用 Kubernetes🔗 opensource.com 时,快速启动和较少的内存占用是至关重要的。在 Kubernetes 平台运行容器化微服务时,内存占用是比吞吐量更重要的考量因素,这是因为:

◈ 由于需要持续运行,所以耗费资源更多(不同于 CPU 占用)
◈ 微服务令开销成本成倍增加
◈ 一个单体应用程序变为若干个微服务的情况(例如 20 个微服务占用的存储空间约有 20GB)

这些情况极大影响了无服务器函数的发展和 Java 部署模型。到目前为止,许多企业开发人员选择 Go、Python 或 Node.js 这些替代方案来解决性能瓶颈,直到出现了 Quarkus🔗 quarkus.io 这种基于 kubernetes 的原生 Java 堆栈,才有所改观。本文介绍如何在使用了 Quarkus 的 kubernetes 平台上进行性能优化,以便运行无服务器函数。

容器优先的设计理念

由于 Java 生态系统中传统的框架都要进行框架的初始化,包括配置文件的处理、classpath 的扫描、类加载、注解的处理以及构建元模型,这些过程都是必不可少的,所以它们都比较耗费资源。如果使用了几种不同的框架,所耗费的资源也是成倍增加。

Quarkus 通过“左移(shifting left)”,把所有的资源开销大的操作都转移到构建阶段,解决了这些 Java 性能问题。在构建阶段进行代码和框架分析、字节码转换和动态元模型生成,而且只有一次,结果是:运行时可执行文件经过高度优化,启动非常快,不需要经过那些传统的启动过程,全过程只在构建阶段执行一次。

Quarkus Build phase

更重要的是:Quarkus 支持构建原生可执行文件,它具有良好性能,包括快速启动和极小的驻留集大小(resident set size)(RSS)内存占用,跟传统的云原生 Java 栈相比,具备即时扩展的能力和高密度的内存利用。

Quarkus RSS and Boot Time Metrics

这里有个例子,展示如何使用 Quarkus 将一个 Java 无服务器🔗 opensource.com 项目构建为本地可执行文件。

1、使用 Quarkus 创建无服务器 Maven 项目

以下命令生成一个 Quarkus 项目,(例如 quarkus-serverless-native)以此创建一个简单的函数:

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

2、构建一个本地可执行文件

你需要使用 GraalVM 为 Java 程序构建一个本地可执行文件。你可以选择 GraalVM 的任何发行版,例如 Oracle GraalVM Community Edition (CE)🔗 www.graalvm.org 或 Mandrel🔗 github.com(Oracle GraalVM CE 的下游发行版)。Mandrel 是为支持 OpenJDK 11 上的 Quarkus-native 可执行文件的构建而设计的。

打开 pom.xml,你将发现其中的 native 设置。你将使用它来构建本地可执行文件。

  1. <profiles>
  2.     <profile>
  3.         <id>native</id>
  4.         <properties>
  5.             <quarkus.package.type>native</quarkus.package.type>
  6.         </properties>
  7.     </profile>
  8. </profiles>

注意: 你可以在本地安装 GraalVM 或 Mandrel 发行版。你也可以下载 Mandrel 容器映像来构建它(像我那样),因此你还需要在本地运行一个容器引擎(例如 Docker)。

假设你已经打开了容器运行时,此时需要运行一下 Maven 命令:

使用 Docker🔗 www.docker.com 作为容器引擎:

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

使用 Podman🔗 podman.io 作为容器引擎:

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

输出信息结尾应当是 BUILD SUCCESS

Native Build Logs

不借助 JVM 直接运行本地可执行文件:

  1. $ target/quarkus-serverless-native-1.0.0-SNAPSHOT-runner

输出信息类似于:

  1. __ ____ __ _____ ___ __ ____ ______
  2. --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
  3. -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
  4. --\___\_\____/_/ |_/_/|_/_/|_|\____/___/
  5. INFO [io.quarkus] (main) quarkus-serverless-native 1.0.0-SNAPSHOT native
  6. (powered by Quarkus xx.xx.xx.) Started in 0.019s. Listening on: http://0.0.0.0:8080
  7. INFO [io.quarkus] (main) Profile prod activated.
  8. INFO [io.quarkus] (main) Installed features: [cdi, kubernetes, resteasy]

简直是超音速!启动只花了 19 毫秒。你的运行时间可能稍有不同。

使用 Linux 的 ps 工具检测一下,结果内存占用还是很低。检测的方法是:在应用程序运行期间,另外打开一个终端,运行如下命令:

  1. $ ps -o pid,rss,command -p $(pgrep -f runner)

输出结果类似于:

  1.   PID    RSS COMMAND
  2. 10246  11360 target/quarkus-serverless-native-1.0.0-SNAPSHOT-runner

该进程只占 11MB 内存。非常小!

注意: 各种应用程序(包括 Quarkus)的驻留集大小和内存占用,都因运行环境而异,并随着应用程序载入而上升。

你也可以使用 REST API 访问这个函数。输出结果应该是 Hello RESTEasy:

  1. $ curl localhost:8080/hello
  2. Hello RESTEasy

3、把函数部署到 Knative 服务

如果你还没有创建命名空间,现在就在 OKD🔗 docs.okd.io(OpenShift Kubernetes 发行版)创建一个命名空间🔗 docs.okd.io(例如 quarkus-serverless-native),进而把这个本地可执行文件部署为无服务器函数。然后添加 quarkus-openshift 扩展:

  1. $ ./mvnw -q quarkus:add-extension -Dextensions="openshift"

向 src/main/resources/application.properties 文件中添加以下内容,配置 Knative 和 Kubernetes 的相关资源:

  1. quarkus.container-image.group=quarkus-serverless-native
  2. quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000
  3. quarkus.native.container-build=true
  4. quarkus.kubernetes-client.trust-certs=true
  5. quarkus.kubernetes.deployment-target=knative
  6. quarkus.kubernetes.deploy=true
  7. quarkus.openshift.build-strategy=docker

构建本地可执行文件,并把它直接部署到 OKD 集群:

  1. $ ./mvnw clean package -Pnative

注意: 提前使用 oc login 命令,确保登录的是正确的项目(例如 quarkus-serverless-native)。

输出信息结尾应当是 BUILD SUCCESS。完成一个本地二进制文件的构建并部署为 Knative 服务需要花费几分钟。成功创建服务后,使用 kubectl 或 oc 命令工具,可以查看 Knative 服务和版本信息:

  1. $ kubectl get ksvc
  2. NAME URL [...]
  3. quarkus-serverless-native http://quarkus-serverless-native-[...].SUBDOMAIN True
  4. $ kubectl get rev
  5. NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON
  6. quarkus-serverless-native-00001 quarkus-serverless-native quarkus-serverless-native-00001 1 True

4、访问本地可执行函数

运行 kubectl 命令,搜索无服务器函数的节点:

  1. $ kubectl get rt/quarkus-serverless-native

输出信息类似于:

  1. NAME URL READY REASON
  2. quarkus-serverless-native http://quarkus-serverless-restapi-quarkus-serverless-native.SUBDOMAIN True

用 curl 命令访问上述信息中的 URL 字段:

  1. $ curl http://quarkus-serverless-restapi-quarkus-serverless-native.SUBDOMAIN/hello

过了不超过一秒钟,你也会得到跟本地操作一样的结果:

  1. Hello RESTEasy

当你在 OKD 群集中访问 Quarkus 运行中的节点的日志,你会发现本地可执行文件正在以 Knative 服务的形式运行。

Native Quarkus Log

下一步呢?

你可以借助 GraalVM 发行版优化 Java 无服务器函数,从而在 Knative 中使用 Kubernetes 将它们部署为无服务器函数。Quarkus 支持在普通的微服务中使用简易配置进行性能优化。

本系列的下一篇文章将指导你在不更改代码的情况下跨多个无服务器平台实现可移植函数。

(Daniel Oh, CC BY-SA 4.0🔗 creativecommons.org)


via: https://opensource.com/article/21/6/java-serverless-functions-kubernetes

作者:Daniel Oh 选题:lujun9972 译者:cool-summer-021 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出


LCTT 译者 :cool-summer-021
🌟🌟
翻译: 4.0 篇
|
贡献: 33 天
2022-09-22
2022-10-24
https://linux.cn/lctt/cool-summer-021
欢迎遵照 CC-BY-SA 协议规定转载,
如需转载,请在文章下留言 “转载:公众号名称”,
我们将为您添加白名单,授权“转载文章时可以修改”。

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
边干边学,自建工具房杂物棚 - 2(动工)Kubernetes 能否帮助解决自动化挑战? | Linux 中国The Chinese Online Slang That Took Over the Internet in 2022如何在 Linux 中更改 GRUB 主题 | Linux 中国Kubernetes上千规模Pod最佳实践如何用 Kubeadm 在 Debian 11 上安装 Kubernetes 集群 | Linux 中国面向 OLTP 场景,火山引擎跑在 Kubernetes 上的数据库有何不同?| Q推荐在 Linux 中使用 Etcher 创建可启动 USB – 下载和使用指南 | Linux 中国Kubernetes是如何实现数据持久化存储的?小城生活,贫富悬差不大在 Linux 中使用 “Converter” GUI 工具转换和操作图像 | Linux 中国Kubernetes 1.24发布,支持网络策略状态、上下文日志记录和子资源如何在 Ubuntu Linux 上更新谷歌 Chrome | Linux 中国准备好在 Debian Linux 上获得 Ubuntu MATE 的体验吧! | Linux 中国真正的 汉服那年火车上的故事 (上集)(十三)心太软[梅玺阁菜话]阁主瞎烧烧之十七 麻辣番茄牛肚(视频)Java 无服务器函数入门 | Linux 中国字节跳动开源 kube-apiserver 高可用方案 KubeGatewayTuxedo 已对所有用户开放基于 Ubuntu 的 TUXEDO OS | Linux 中国Rhino Linux:滚动发布但也很稳定的 Ubuntu | Linux 中国管理Kubernetes资源要注意的5件事!Kubernetes 集群的关闭与重启后Kubernetes时代的未来?Wasmer 3.0 发布,可在浏览器外运行 WebAssemblyKubernetes入门之Pod健康状态监测机制3 个可在 Linux 上玩旧 NES 游戏的 NES 模拟器 | Linux 中国Kubernetes 1.26 版本正式发布:改进 Windows 支持,加强网络安全和管理功能16 张图硬核讲解 Kubernetes 网络Kubernetes 即将支持机密计算 | Linux 中国没有银弹,只有取舍 - Serverless Kubernetes 的思考与征程(一)Kubernetes 缺少的多租户功能,你可以通过这些方式实现使用 PowerFlex 在 Kubernetes 平台上部署 Microsoft SQL Server 大数据集群如何提高 Ubuntu 和其他 Linux 系统中的扬声器音量 | Linux 中国如何在 Ubuntu 和其他相关 Linux 中安装 Python 3.10 | Linux 中国re:Invent全球大会全回顾:硬件创新、全面无服务器、云原生数据战略
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。