专家分享选择开源和自研道路上的考量以及具体的业务案例,点击查看 了解详情
写点什么

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

  • 2022 年 6 月 24 日
  • 本文字数:4684 字

    阅读完需:约 15 分钟

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

随着云部署的兴起,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 集群上运行,从而获得以下好处:



下面是一份快速入门指南,介绍如何利用 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-http
applying codestarts... java maven quarkus config-properties dockerfiles maven-wrapper funqy-http-codestarts
-----------
复制代码


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


--> /Users/USERNAME/quarkus-serverless-example-----------
复制代码

探究新创建的函数

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


@Funqpublic 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] ✅ Extension io.quarkus:quarkus-openshift has been installed


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


quarkus.container-image.group=YOUR_NAMESPACEquarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000quarkus.kubernetes-client.trust-certs=truequarkus.kubernetes.deployment-target=knativequarkus.kubernetes.deploy=truequarkus.openshift.build-strategy=dockerquarkus.openshift.expose=true
复制代码


也可以使用容器运行时(如 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
复制代码


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


$ curl --header "Content-Type: application/json" \  --request POST \  --data '{"name":"Daniel"}' \ YOUR_ROUTE_URL/fun 
复制代码


输入类似下面这样: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 团队阐述新兴技术。


原文链接:

Reduce Carbon Dioxide Emissions with Serverless and Kubernetes Native Java

2022 年 6 月 24 日 09:001

评论

发布
暂无评论
发现更多内容

安卓11重磅上线,快来看看,是不是熟悉的配方,大专生面试阿里P7居然过了

android 程序员 移动开发

对标小程序 _ _快应用_开发入门指南,移动应用开发课程设计

android 程序员 移动开发

巧用Android网络通信技术,在网络上直接传输对象(2),android开发入门基础教程

android 程序员 移动开发

字节跳动技术整理:Android-Camera内存问题剖析,为什么Flutter能最好地改变移动开发

android 程序员 移动开发

学习不系统学过的Android知识全忘记了?思维导图+手写笔记

android 程序员 移动开发

安卓指纹对称加密及登录功能的实现(1),技术实现

android 程序员 移动开发

巧用Android网络通信技术,在网络上直接传输对象(1),讲的真详细

android 程序员 移动开发

字节跳动+京东+360,字节跳动+京东+美团+腾讯面试总结

android 程序员 移动开发

字节面试官:看了3000多份简历,面试1000场后,androidjni开发书籍

android 程序员 移动开发

学习 View 事件分发,就像外地人上了黑车!,真的已经讲烂了

android 程序员 移动开发

巧用Android网络通信技术,在网络上直接传输对象 (1),安卓面试题宝典app

android 程序员 移动开发

学习 View 事件分发,就像外地人上了黑车!(1),kotlin安卓开发书籍

android 程序员 移动开发

孽缘啊,同套面试题中午我把你挂了,晚上你把我挂了,农民工看完都会了

android 程序员 移动开发

字节跳动最新开源!超实用的UI轮子库,我只是个轮子搬运工

android 程序员 移动开发

学会这些Android开发热门前沿知识,2020年你就不用愁了!

android 程序员 移动开发

安卓指纹对称加密及登录功能的实现,阿里P8大牛从零开始教Android开源框架

android 程序员 移动开发

巧用Android网络通信技术,在网络上直接传输对象,android设计模式总结

android 程序员 移动开发

字节三面:ButterKnife为什么执行效率为什么比其他注入框架高?它的原理是什么

android 程序员 移动开发

字节跳动厂内部超高质量Flutter+Kotlin笔记!技术与实战篇

android 程序员 移动开发

小厂开发五年,成功入职腾讯,这是我的复盘和总结,阿里P8Android架构师谈

android 程序员 移动开发

屌丝的眼泪,因为错过的初恋,才搞清楚PNG图片压缩原理(1)

android 程序员 移动开发

字节码插桩--你也可以轻松掌握(1),收割快手,字节,百度,美团的Offer之旅

程序员 移动开发

字节码插桩--你也可以轻松掌握,2021年Android工作或许更难找

android 程序员 移动开发

工作出现瓶颈,学习效率下降?通学这份Android进阶知识体系

android 程序员 移动开发

完美!腾讯技术官发布Android零基础就业宝典,不用再怀疑人生了

android 程序员 移动开发

屌丝的眼泪,因为错过的初恋,才搞清楚PNG图片压缩原理

android 程序员 移动开发

字节跳动正式启动2021届秋季校招!这份字节跳动历年校招Android面试真题解析,你确定不收藏

android 程序员 移动开发

字节跳动面试,第三面挂了,这原因我服了,快速上手

android 程序员 移动开发

实现Flutter离线验证码组件,跳槽面试大厂被拒

android 程序员 移动开发

字节跳动+京东+360(1),Android工程师必备知识

android 程序员 移动开发

字节跳动1面Too simple2面怀疑人生,宅家修炼“65天,flutter开源项目集合

android 程序员 移动开发

面向体验的视频云-火山引擎增长沙龙

面向体验的视频云-火山引擎增长沙龙

低碳环保:无服务器和Kubernetes原生Java部署实践_语言 & 开发_Daniel Oh_InfoQ精选文章