随着云部署的兴起,IT 部门使用的物理服务器减少,用电量也相应降低,结果是通过减少碳排放帮助缓解了气候变化。云架构有助于实现这一点,因为它们不需要维护竖井式的计算资源,而是在需要保持业务服务运行时,高效共享所在云上的可用资源。

然而短期内,云迁移的这些好处对于二氧化碳的排放并没有产生显著的影响。这是因为采用云的速度比转向无碳基础设施的速度要快得多。例如,谷歌云目前已实现碳中和,但他们正在努力成为无碳、可持续的云计算系统。

与此同时,开发人员和架构师仍然在尽可能地优化应用程序的性能,缩小容器镜像,缩短启动和响应时间以及减少内存占用。他们相信,这最终能够减少应用层的计算消耗。

Java 不是为这个时代设计的

Java 诞生于 27 年前,用于运行业务服务。它有诸多优点,如较高的网络吞吐量、长期运行的进程和面向可变系统的动态行为。几十年前,这些都是很棒的特性,开发人员可以编写灵活、丰富的互联网应用,然后在多台应用服务器上运行。这些服务器位于由物理服务器和虚拟机组成的基础设施上。

然而,自从 Kubernetes 和 Linux 容器面世以来,事情发生了变化。它为我们提供了一种新的模式,让我们可以重构现有应用。在云上,我们应该将这些应用 当作牛而非猫 。新应用的主要特性是可移植、不可变及可快速扩展。

遗憾的是,Java 的动态特性在这个新时代并无多大优势。尽管如此,企业仍然维护着大量基于 Java 技术栈构建的关键业务应用程序,这可能成为将工作负载迁移到云平台的障碍。这也使企业失去了减少二氧化碳排放的机会,因为他们需要花不少钱来维持传统基础设施上的单体应用。

颇具讽刺意味的是,根据 TIOBE排行榜 ,Java 仍然是第三大最受欢迎的编程语言。顺应这一趋势,出现了许多开源项目和工具,如 Shenandoah GC 。它们试图从吞吐量管理方面优化 Java 的性能,通过扩展、临时状态及减少不可变系统的内存占用。遗憾的是,这些努力不足以说服开发人员将 Java 应用程序留在 Kubernetes 集群中,而不是采用 JavaScript 和 Python 等替代方案。

无服务器 Java

作为减少云计算资源的无尽努力的一部分,通过定期监控应用程序工作负载和资源使用情况,许多企业已经意识到,所有业务服务都不需要一直运行(例如 24 x 7 x 365)。

举例来说,某些服务(如订单服务)只有不足 10%的时间被最终用户和第三方访问。在这种情况下,当应用程序在某段时间内(如 5 分钟或 30 秒)没有网络通信时,无服务器架构让你能够自动将应用程序缩减为零。

事实上,无服务器行为不仅可以应用于基于 HTTP 的微服务,还可以应用于来自物联网(IoT)边缘设备和 Kafka 消息服务器的分布式流服务。

作为一名 Java 开发人员,你会问:“Java 如何处理无服务器架构?”更大的问题是:“ Java 适合开发无服务器应用程序吗? ”根据 NewRelic的调查 ,由于重量级的程序包和动态行为,开发人员通常不会在 AWS Lambda 上运行 Java 应用程序,如图 1 所示。

图 1:无服务器之爱

这就是为什么越来越多的开发人员希望将 Node.Js 和 Python 应用程序引入无服务器平台和函数即服务(Function as a Service,FaaS),而不是演进现有 Java 应用程序的原因。不要放弃你的 Java 技能!下一节将介绍如何使 Java 应用程序更适合于无服务器架构。

生而原生的 Java

构建一个原生可执行的 Java 应用程序不仅有巨大的好处,如启动和响应时间缩短、内存占用变小,而且还解决了传统 Java 技术栈中存在的上述挑战。让我们深入了解一下原生可执行文件的工作原理吧!原生可执行文件是使用预编译器(AOT)构建的。该编译器会生成一个独立的原生镜像,其中包含应用程序类、依赖库和运行时。你可以理解为和 Linux 容器镜像类似,包含了在任何容器运行时和 Kubernetes 上运行应用程序所需的所有东西。

有了原生可执行文件,就不再需要 Java 虚拟机(JVM)来运行 Java 应用程序了。相反,原生镜像可以运行在 Substrate VM 上,它是 GraalVM 中的运行时组件(如垃圾收集器、线程调度)。

另外,Java 原生编译使开发人员在无服务器工作负载中也继续坚持使用 Java 应用程序,因为原生可执行文件可以缩短冷启动的启动时间,而这原本是许多企业想要采用无服务器架构时面临的最大挑战之一。

下面是一份简单的教程,介绍如何安装必要的 C 语言库和依赖项,然后在你的操作系统上将 Java 应用程序编译成一个原生可执行的镜像。

安装 C 语言库

为了支持 C 语言原生编译,需要使用以下命令安装 GCC 和相关库:

  • Fedora:

$ sudo dnf install gcc glibc-devel zlib-devel libstdc++-static

  • Debian:

$ sudo apt-get install build-essential libz-dev zlib1g-dev

  • macOS

$ xcode-select --install

要了解更多关于如何安装 GraalVM 的信息,请访问 这个网站 。

配置 GraalVM

设置环境变量 GRAALVM_HOME:

  • Linux

$ export GRAALVM_HOME=$HOME/Development/graalvm/

  • macOS

$ export GRAALVM_HOME=$HOME/Development/graalvm/Contents/Home/

安装原生镜像工具:

${GRAALVM_HOME}/bin/gu install native-image

如果还没设置的话,请使用以下命令设置环境变量 JAVA_HOME:

$ export JAVA_HOME=${GRAALVM_HOME}

不过,生成原生镜像需要预先提供很多关于应用程序的信息。只有当一个类或方法被明确注册后,反射才会起作用。这就要求 Java 开发者在构建原生可执行镜像之前,对当前所有的应用程序进行转换,以便注册反射。

Kubernetes 原生 Java 入门:Quarkus

如果可以继续开发云原生微服务,而且不需要花太多时间处理反射,那么你是否只需要在部署到 Kubernetes 集群之前构建一个原生可执行镜像?我很确定,这对 Java 开发者来说是很好的。

Quarkus 是一个开源项目,旨在提供一个标准的 Java 技术栈,使 Java 开发者不仅可以在 OpenJDK 上构建容器优先的应用程序,还可以编译生成原生可执行文件,在 Kubernetes 集群上运行,从而获得以下好处:

  • 将尽可能多的工作转移到构建阶段

  • 最大限度地减少运行时依赖

  • 最大限度地消除死代码

  • 引入清晰的元数据契约

  • 增强开发人员的体验(如 DEV UI 、 开发服务 、 命令行 )。Quarkus 还提供了一个扩展,即 Funqy ,其目的是针对 OpenShift无服务器 、 Knative 、 AWS Lambda 、 Azure Functions 和 谷歌云平台 等无服务器平台编写可移植的无服务器函数。

下面是一份快速入门指南,介绍如何利用 Quarkus 新建一个使用了原生可执行编译的无服务器函数。

新建一个无服务器 Java 项目

搭建一个 Quarkus 项目,并使用 Quarkus命令行工具 创建一个函数:

$ quarkus create quarkus-serverless-example -x funqy-http

这个命令会帮你下载 Funqy 扩展,并启用 Quarkus Funqy 功能,其输出如下所示:

Creating an app (default project type, see --help).
-----------
selected extensions:
- io.quarkus:quarkus-funqy-httpapplying codestarts...javamavenquarkusconfig-propertiesdockerfilesmaven-wrapperfunqy-http-codestarts-----------

Quarkus 项目成功创建到下面的目录里:

--> /Users/USERNAME/quarkus-serverless-example
-----------

探究新创建的函数

进入项目的根目录,打开 src/main/java/org/acme 目录下的 MyFunctions.java 文件。其中默认生成了一个简单的函数方法 fun ,可以返回问候信息。 @Funq 注解使一般方法成为可以通过 RESTful API 访问的函数。

@Funq
public String fun(FunInput input) {return String.format("Hello %s!", input != null ? input.name : "Funqy");
}

可以新增一个函数或在现有的函数中添加业务逻辑。这里,我们暂时保留默认代码。

构建并将原生可执行文件部署到 Kubernetes

Quarkus 提供了一个 OpenShift 扩展,用于构建应用程序并将其部署到 Kubernetes 集群上。执行以下 Quarkus 命令行来添加扩展:

$ cd quarkus-serverless-example
$ quarkus ext add openshift

输出如下所示:

Looking for the newly published extensions in registry.quarkus.io

[SUCCESS] :white_check_mark: Extension io.quarkus:quarkus-openshift has been installed

src/main/resources 目录中的 application.properties 文件中添加以下用于 Kubernetes 部署的配置。需要将 YOUR_NAMESPACE 替换为实际部署该功能的命名空间(例如 doh-dev )。

 Looking for the newly published extensions in registry.quarkus.io[SUCCESS] :white_check_mark: Extension io.quarkus:quarkus-openshift has been installed

也可以使用容器运行时(如 Docker 或 Podman)构建一个原生可执行镜像,只要添加以下配置: quarkus.native.container-build=true

请注意, 这里 有解决方案库。

为了部署该函数,你可以使用自己的 Kubernetes 集群(例如 minikube ),但我建议使用 红帽OpenShift开发者沙盒 。你只要注册一个免费账户,它会提供一个共享 Kubernetes 集群。该沙盒使你能够在 10 分钟内启动一个新的 Kubernetes 集群,无需在本地文件系统上进行任何安装或配置。

执行以下 Quarkus 命令行,构建并部署函数到 Kubernetes 集群:

$ quarkus build --native --no-tests

输出应该以 BUILD SUCCESS 消息结束。

进入 OpenShift 开发控制台的 Topology 视图,可以看到 Java 函数( quarkus-serverless-example-00001 )已经部署完毕。该函数可能会被缩减为零,因为 Knative 服务的默认设置为 30 秒,如果在这段时间内没有网络流量到达该函数的 pod,函数就会停掉,如图 2 所示。

图 2:Topology 视图中的函数

请注意,可以给 REV 和 KSVC 添加一个新标签,将 pod 显示为 Quarkus 函数,让你在查看 Topology 视图时可以轻松区分各 pod。使用 oc 命令行,如下所示:

  • 向 REV 添加一个 Quarkus 标签:
oc label rev/quarkus-serverless-example-00001 app.openshift.io/runtime=quarkus --overwrite
  • 向 KSVC 添加一个 Function 标签:
oc label ksvc/quarkus-serverless-example boson.dev/function=true --overwrite

复制 Route URL,然后粘贴到以下 CURL 命令行中来访问该函数。例如,该 URL 看起来可能是这样: https://quarkus-serverless-example-doh-dev.apps.sandbox.x8i5.p1.openshiftapps.com 。

$ curl --header "Content-Type: application/json" \

输入类似下面这样: Hello Daniel!

回到 Topology 视图,你会看到函数 pod 在一秒钟内自动启动,如图 3 所示。

图 3:向上扩展函数

查看 pod 日志,你会发现 Java 无服务器函数是作为一个 native 镜像运行的。它的启动时间是 17 毫秒,如图 4 所示。

图 4:原生可执行文件的启动时间

啊,一个超音速的亚原子应用!从现在开始,这些新的 Java 无服务器函数将使你能够在 Kubernetes 上优化资源使用,减少二氧化碳排放。

小结

本文介绍了 Java 无服务器应用程序。在容器平台上(如 Kubernetes),它提供了比其他任何编程语言都高的资源密度,可以帮助组织减少二氧化碳排放,如图 5 所示。

图 5:容器平台上多个应用程序的资源密度

要构建 Java 应用程序原生镜像,开发人员还可以选择三个 GraalVM 发行版中的一个:Oracle GraalVM 社区版(CE)、Oracle GraalVM 企业版(EE)和 Mandrel。从 这里 可以进一步了解 GraalVM 和 Mandel 之间的区别。如果要继续 Kubernative 原生 Java 之旅,可以访问这个 网站 。

作者简介:

Daniel Oh是红帽公司高级首席技术营销经理,负责向开发者介绍如何使用云原生运行时(即 Quarkus、Spring Boot、Node.js)和 OpenShift/Kubernetes 构建云原生微服务和无服务器函数。作为 CNCF 大使,Daniel 将继续为各种云开源项目和生态系统做出贡献,以加速 DevOps 在企业中的应用。他在许多技术研讨会、工作坊和聚会上发言,为企业开发人员和 DevOps 团队阐述新兴技术。

低碳环保:无服务器和 Kubernetes 原生 Java 部署实践相关推荐

  1. Quarkus:一个Kubernetes原生Java框架

    Red Hat发布了Quarkus,这是一个为GraalVM和OpenJDK HotSpot量身定制的Kubernetes原生Java框架.Quarkus的目标是使Java成为Kubernetes和无 ...

  2. Kubernetes原生api部署微服务5-监听Pod

    我们使用Client-go中的informer来监听用户微服务与文章微服务的Pod. Informer代替Controller去访问k8s-apiserver,而Controller的所有操作(如:查 ...

  3. 高可用 kubernetes 集群部署实践

    前言 Kubernetes(k8s) 凭借着其优良的架构,灵活的扩展能力,丰富的应用编排模型,成为了容器编排领域的事实标准.越来越多的企业拥抱这一趋势,选择 k8s 作为容器化应用的基础设施,逐渐将自 ...

  4. 何时该用无服务器,何时该用Kubernetes?

    什么时候该用无服务器,什么时候该用Kubernetes构建云原生应用程序? 一个好的无服务器应用场景应该是在夜间没有太多或者完全没有流量.由于无服务器平台仅在代码运行期间收费,因此可以显著降低成本.较 ...

  5. web服务器中启用作业储存_如何在Kubernetes中启用无服务器计算

    web服务器中启用作业储存 在本系列的前两篇文章中,介绍了在开放源代码平台上使用无服务器平台的过程,我介绍了如何开始使用无服务器平台,以及如何使用流行的语言编写函数以及如何在Apache OpenWh ...

  6. JAVA服务器没回应_Java如何面对无服务器的挑战?

    这是来自jaxcenter组织的一个讨论,谈论了Java在无服务器浪潮冲击下面临的机会和挑战.下面摘录主要部分: Spring推动者Pivotal有一个名为 Riff的函数即服务平台,它是一个开源的. ...

  7. 会比Kubernetes和无服务器更有前途的是Istio

    导 读 谷歌强烈看好Istio,你觉得呢? 随着现代数字计算基础设施的不断发展,新的自动化层可以实现越来越快速的变化和适应.一旦容器化使得在几秒钟内部署新功能成为可能,那么Kubernetes和类似工 ...

  8. WebAssembly可以解决无服务器的问题吗?

    对无服务器计算用例的需求持续增长,对于那些希望创建和运行应用程序的组织来说,所涉及的基础设施管理相对较少.这对于寻求提供软件应用程序.服务或两者兼而有之的初创公司来说是一个好消息--不必对本地服务器进 ...

  9. aws lambda_AWS Lambda –无服务器编程

    aws lambda AWS Lambda is serverless programming. Serverless programming help to ease out the deploym ...

最新文章

  1. iframe 内嵌第三方网站 cookie 失效,解决办法
  2. SAP MM 分期付款场景下的付款方式
  3. LeetCode - Longest Common Prefix
  4. Zoj 3201 Tree of Tree
  5. linux内核驱动模块开发步骤及实例入门介绍
  6. ZooKeeper相关资料集锦
  7. 单片机拼字程序怎么做_家装行业做小程序怎么样?
  8. Laravel核心解读--观察者模式
  9. php cms 选择哪个好?
  10. lxml库的一些注意事项
  11. Android ImageView 正确使用姿势
  12. xlsx.js导出表格设置批注框根据内容自动全部显示的解决办法
  13. 用devc++表白_表白墙第42期|别人深夜买醉,我只想买你的心
  14. OUC2022秋软件工程第14小组作业
  15. Docker的基本操作命令
  16. 微信小程序 评论input 弹出框
  17. c语言ascii码字符集共有多少个编码,标准ascii码字符集共有多少个编码
  18. Scriptable Build Pipeline - 2018.2 入门指南
  19. JVM运行时内存结构学习
  20. iframe中由一个页面跳转到另一个页面

热门文章

  1. 计算机视觉期刊会议记录
  2. 每日题解:LeetCode 174. 地下城游戏
  3. 计算机会显示错误的是,电脑提示蓝屏错误WHEA UNCORRECTABLE ERROR的解决方法
  4. 一、统计EXCEL里面有多少列
  5. 初识C++中的构造函数和析构函数
  6. 敖丙思维导图-网络基础
  7. 数学/线性代数 {行列式, 行列式变换,行列式操作,行列式计算}
  8. 狼羽:3种简单方法培养客户忠诚度
  9. 用InputStreamReader读取从键盘输入的数据
  10. 51nod P2500 后面第一个大于【单调栈】