Quarkus-云原生Java的新外观

哈Ha!

在新的一年中,我们计划认真开发容器主题, Cloud-Native JavaKubernetes 。 这些主题在俄语中的合乎逻辑的延续将是关于Quarkus框架的故事,该故事已在有关Habré的精彩文章中进行了讨论。 今天的文章并没有把重点放在Quarkus带给企业的“ 亚原子超快速Java设备”上。

Java和JVM仍然非常流行,但是当使用无服务器技术和面向云的微服务时,JVM的Java和其他语言使用的越来越少,因为它们占用了太多的内存空间并且加载速度太慢,这就是为什么它们不适合用于与短寿命的容器一起使用。 幸运的是,由于Quarkus,这种情况目前开始改变。

引言


我从事DevOps,容器和无服务器技术的工作越多,就越发现我在轻量级容器或Python或JavaScript的 FaaS 编写了容器化代码 Java太重了,无法启动以在无服务器框架中使用。 关于微服务,JavaScript或Python提供了更快的加载速度和更紧凑的容器,从而使Java更加高效。



Python和JavaScript是创建基于云的微服务的最佳语言

Java已经有20多年的历史了 ,在Java诞生之初,世界就与现在完全不同。 随着JVM的出现,解决了巨大的问题-我们能够编写一次代码,并在许多平台和操作系统上运行它。 容器使您可以将应用程序,库和操作系统资源打包到单独的容器中,并且每个这样的容器都可以在任何地方工作。 JVM提供的可移植性现在不再那么重要了 。 一次,我们准备承担额外的费用以确保可移植性,但是现在已经过去了。 现在,您需要以最小的延迟快速进行工作,并且始终可以使用反应性应用程序 。 容器和容器编排工具(如Kubernetes)提供这些功能,而与编程语言无关。

转向微服务架构的公司将其用Java编写的基于Spring的服务,将它们链接到大量的jar归档文件,添加JDK并在基于Linux的容器中运行它们。 此解决方案有效,但您必须处理500MB的重容器,每个重容器进入可访问状态的时间为10-30秒。 这是一个严重的问题。 迁移之后,许多公司正在缓慢地转向使用Python,而将服务器端服务留在Java中,最后停在FaaS。

无服务器技术和FaaS在今天非常流行,因为它们使您可以专注于编写功能而不必担心基础结构。 尽管如此,它们都在容器中工作,但云提供商管理其生命周期。 最好的部分是,在一定时间后,提供程序会完全停止容器并仅在下一次调用之后恢复工作,也就是说,您只需为实际工作时间付费。 第一个函数调用的持续时间可能比平时更长,这就是著名的冷启动 。 事实是容器需要主要装载。 使用Python或JavaScript并不是什么大问题,但是对于Java,初始加载可能需要10到15秒,这是一句话,也是Java普及率下降的原因之一。 现在,我们需要一个可以启动,完成任务然后停止的代码 。 我们不想处理许多线程或长时间运行的进程,我们需要可以快速加载的短期进程

介绍Quarkus


如果您阅读技术博客或关注新闻,您可能会认为无服务器模式正在占领整个世界,并且每个人都怀着极大的热情接受它。 现在,由于使用了JavaScript,初创企业可以编写功能并将其作为服务提供到云中,并且可以扩展功能以支持数百万个用户,而无需管理基础结构。 的确,硅谷之外还有一个现实世界:金融机构,政府,零售以及许多其他行业,这些行业由数百万条Java代码提供服务,这些代码太昂贵而无法重写。 因此,我们必须理所当然地认为,在这些行业中,仍然需要继续使用重型集装箱。



今天GraalVM ,尤其是Substrate VM,为Java语言的光荣和长期前景打开了大门。 GraalVM是一种通用虚拟机,用于运行以JavaScript,Python,Ruby,R和JVM语言(尤其是Java,Scala或Kotlin)编写的应用程序。 最酷的事情是GraalVM允许您将程序预编译(以AOT模式)到本机可执行文件中 。 这意味着您可以将Java代码直接编译为特定于计算机的代码。 生成的程序无法在Java HotSpot VM上运行,但使用所有必需的组件,尤其是内存管理,来自称为Substrate VM的虚拟机的另一种实现的线程调度。 Substrate VM用Java编写,其代码被编译为本地可执行文件。 与Java VM相比,生成的程序启动速度更快,因此在内存使用方面的开销较低。 很好,但是您可能会认为:早期编译? 它与创建JVM的基本思想相矛盾,也就是说,到处都使用一次编写的代码! 这太疯狂了! 但是,请自己想一想:现在我们有了容器,它们不需要JVM。 使用Spring Boot创建的常规容器应用程序具有额外的抽象级别,在Kubernetes所在的世界中绝对没有必要 。 您有一个Java应用程序在容器内的JVM上运行,该容器保持不变,因为今天成品是容器,而不是应用程序。 现在,我们正在包装容器,而不是WAR文件。 因此, 与在容器内使用JVM应用程序相关的所有成本都变得毫无用处 ,如果要将应用程序打包到容器中,则AOT成为非常合乎逻辑的决定。

的确,AOT编译严重限制了Java的动态功能(在运行时加载类,反射,代理等)。 实际上,这意味着90%的Java生态系统如果不进行更改将无法工作。 因此, Java生态系统必须适应 。 有个好消息:大多数可以在组装过程中完成!

这就是Quarkus的力量。 它使用GraalVM并提供了一个在构建时支持AOT编译的生态系统。 因此,使用Java,您可以创建本机二进制文件。 感谢Quarkus, Java开发人员可以使用 GraalVM。

Quarkus入门


如上所述,Quarkus提供了Java应用程序的早期编译,这产生了超音速亚原子Java生态系统。 Quarkus的特点是超快速加载-Java返回基于云的开发领域。 多年来,没有新技术启发过我-而且我并不孤单

阅读初学者指南 -自己看看。 仍然有许多公司在容器内使用Java + JPA,但是在这种配置下,加载可能需要15秒,而对于Quarkus,则需要0.005!



夸库斯统计

您使用的是与Spring Boot世界中相同的IDE和相同的工具。 要构建您的项目,请使用Maven或Gradle。 该项目可以直接在IDE中运行,并且可以在其之上进行热实时重启并进行任何更改,并且您无需重启应用程序。 Quarkus不是Spring,因此,如果您使用Spring Boot,则必须迁移特定于Spring的代码。 幸运的是,Quarkus 为实现Spring依赖关系提供了一定程度的兼​​容性 ,从而大大简化了工作。 Quarkus框架符合标准,这意味着易于移植和对其代码的支持。

Quarkus开发流程


Quarkus可以在开发模式下使用,这让人联想到Spring Boot。 有了它,您也可以将项目包装在厚罐中。 由于支持实时重启,因此这对于测试和调试代码非常方便。 但是您需要事先进行编译才能投入生产。 下图显示了整个过程:



  • 首先,在您喜欢的IDE中构建该应用程序,然后可以像使用Spring Boot应用程序那样在开发人员模式下使用“ mvnw compile quarkus:dev ”运行它。 您也可以将其包装在一个厚罐中。
  • 一旦完成上一步,并且结果适合您-准备创建Java二进制文件,只需运行:“ mvnw package -Pnative ”。 这将需要一些时间,因为将在编译过程中预先生成本机代码! 完成此步骤后,您将可以使用超小且超快速的可执行文件,但是该文件只能在您的平台/ OS上运行,也就是说,将无法移植! 但这是正常的,因为我们可以将其放入容器中,从而确保可移植性。 操作方法如下: ./mvnw package -Pnative -Dnative-image.docker-build=true 4-然后从Docker容器中删除可执行文件,也就是说,我们在容器内执行本机汇编并创建一个二进制文件。 如果笔记本电脑的操作系统不同于在项目创建过程中DockerFile生成的DockerFile中指定的目标平台,则该技术可能不适用于您的笔记本电脑。
  • 然后,在拥有二进制文件之后,只需基于docker文件创建映像。 docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/quickstart
  • 最后,可以在Docker或Kubernetes中启动该应用程序:docker docker run -i --rm -p 8080:8080 quarkus-quickstart/quickstart

Quarkus功能


Quarkus比本地Java代码具有更多功能。

  • 命令式和响应式功能的统一:允许您将熟悉的命令式代码与以响应式风格编写的非阻塞代码结合在一起。
  • 开发人员很高兴 :统一配置,零配置,立即实时重启,针对80%的普通案例的优化精简代码和针对其余20%案例的灵活代码,无忧无虑的本机可执行文件的生成,实时编码。
  • 惊人的快速加载,非常小的驻留内存区域(是的,不仅仅是堆大小!),当在Kubernetes等平台上协调容器时,它提供了几乎即时的垂直扩展和非常密集的内存使用。 查看更多详细信息
  • Quarkus提供了一个整体的,用户友好的全栈框架,在支持结构中嵌入了您熟悉和喜爱的一流库。 更多细节
  • 支持Hibernate,JPA,REST,JWT等库。
  • KubernetesOpenShift中部署的受支持的配置
  • 使用Jaeger进行公开跟踪
  • Kotlin支持
  • 与Kafka,Camel通讯...
  • 还有更多,请查看扩展列表

Quarkus生态系统


简而言之,您现在可以在超快速的轻量级容器中运行传统的事务服务JPA / JTA,无论是在云端还是在本地

Quarkus的例子


在本节中,让我们简单地看一下初学者指南,以使您对Quarkus的功能有一个印象。



创建新的Quarkus项目的最简单方法是打开命令提示符窗口,并在其中运行以下命令:

 mvn io.quarkus:quarkus-maven-plugin:0.12.0:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=getting-started \ -DclassName="org.acme.quickstart.GreetingResource" \ -Dpath="/hello" 

这将生成一个带有GreetingResuce的Maven项目,以提供端点/问候。 还会生成用于本机文件和jvm的Dockerfile docker映像(厚罐形式的传统映像)。 该代码非常简洁:

 @Path("/hello") public class GreetingResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "hello"; } } 

要运行该应用程序,请使用: ./mvnw compile quarkus:dev
该应用程序使用./mvnw软件包进行打包。 结果是2个jar文件:

  • Getting-started-1.0-SNAPSHOT.jar-仅包含类和项目资源。 这是Maven组装产生的常见工件。
  • Getting-started-1.0-SNAPSHOT-runner.jar是一个可执行jar。 请注意,这不是“ uber-jar”,这里有依赖项,它们被复制到target / lib目录。

您可以使用以下命令启动应用程序:java -jar target / Getting-started-1.0-SNAPSHOT-runner.jar

然后,您需要下载并安装GraalVM并设置环境变量GRAALVM_HOME

现在,您可以使用以下命令创建本机可执行文件: ./mvnw package -Pnative -Dnative-image.docker-build=true

以下是创建Docker映像的方法: docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/quickstart

现在,可以使用任何容器编排引擎启动它,如果您使用minishift

 kubectl run quarkus-quickstart --image=quarkus-quickstart/quickstart:latest --port=8080 --image-pull-policy=IfNotPresent 

 kubectl expose deployment quarkus-quickstart --type=NodePort 

仅此而已! 现在您有了一个带有Java REST服务的容器,该容器将在0.004秒内启动!

结论


现在,我明白了为什么Red Hat支持的Quarkus框架给我留下了深刻的印象。 我真的相信它将改变Java的技术面貌,并为大型传统企业提供迁移到云的真正机会。

Kubernetes + Knative + Quarkus在面向云的开发中更改了游戏规则,并将令任何Java开发人员满意

这个仓库有很多有趣的例子!

Source: https://habr.com/ru/post/zh-CN482968/


All Articles