写点什么

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

  • 2022-06-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-06-24 09:007161

评论 1 条评论

发布
用户头像
节能减排?

2022-10-18 16:11 · 上海
回复
没有更多了
发现更多内容

竞猜商城系统软件制作

v16629866266

定制开发小程序

luluhulian

前端学习总结,经验分享,项目经验分享过程

我是哪吒

学习 程序员 Vue 大前端 2月春节不断更

对DevOps的九大误解,是时候纠正了!

禅道项目管理

开源 DevOps 敏捷 自动化 持续交付

CoralCache:一个提高微服务可用性的中间件

华为云开发者联盟

数据库 微服务 中间件 内存 CoralCache

Kafka.01 - 简介

insight

kafka 2月春节不断更

了解操作系统的那些事儿,从这篇文章开始

飞天小牛肉

Java 程序员 面试 操作系统 2月春节不断更

android开发工程师需要学什么?360°深入了解Flutter,这原因我服了

欢喜学安卓

android 程序员 面试 移动开发

我在春晚现场护航直播

阿里云CloudImagine

阿里云 运维 直播 运维工程师 春晚

拥抱云原生,Fluid 结合 JindoFS:阿里云 OSS 加速利器

阿里巴巴云原生

容器 云原生 k8s 分布式计算 调度

15. Python 程序运行速度如何提高十倍?第一遍滚雪球学 Python 收工

梦想橡皮擦

Python 2月春节不断更

Hive HMS Canary 时间较长异常分析

kwang

大数据 hadoop hive

架构师week12作业

Geek_xq

DIY一款4路USB转TTL串口调试模块

不脱发的程序猿

DIY 电路设计 硬件设计 USB电路 USB转TTL

翻译:《实用的Python编程》01_07_Functions

codists

Python 人工智能 后端 数据结构与算法 函数

【STM32】ST-LINK下载器下载后需复位,程序才运行的问题

AXYZdong

硬件 stm32 2月春节不断更

技术秘籍 | 如何简单优雅的适配textview行间距?

百度开发者中心

大前端 TextView

【LeetCode】最大连续1的个数三Java题解

Albert

算法 LeetCode 2月春节不断更

一文搞懂TCP的三次握手和四次挥手

不脱发的程序猿

三次握手 四次挥手 TCP/IP 网络通信协议 二月春节不断更

日记 2021年2月19日(周五)

Changing Lin

2月春节不断更

数据中心决策如何快人一步?一块大屏轻松实现3D数据可视化

一只数据鲸鱼

物联网 数据中心 数据可视化 IDC 机房管理

万字长文:解读区块链7类共识算法

华为云开发者联盟

区块链 公有链 拜占庭容错 共识算法 公式算法

Elasticsearch Query DSL 概述

escray

elastic 七日更 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

诊所数字化:就诊流程标准化和产品SOP设计

boshi

数字化转型 医疗 七日更

最新金三银四阿里巴巴内部Java架构师面试突击面试题手册,面试前必看

Java架构追梦

Java 阿里巴巴 架构 面试 金三银四

android进阶之光!还有人不知道什么是AndroidX的吗?通用流行框架大全

欢喜学安卓

android 程序员 面试 移动开发

解密协议层的攻击——HTTP请求走私

京东科技开发者

安全 HTTP

架构师week12心得

Geek_xq

2021金三银四想进字节大厂必看:LeetCode算法收割机+算法刷题宝典

比伯

Java 编程 架构 面试 算法

LeetCode题解:1143. 最长公共子序列,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

开源数据库管理系统现在比商业产品更受欢迎

PostgreSQLChina

数据库 postgresql 软件 开源社区

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