Java和JVM仍然是最流行的编程语言,但对于无服务器和云原生微服务,Java使用率正在下降,原因是传统Java应用内存占用大,而且短期容器需要慢启动时间; 但由于 Quarkus的出现, 现在即将改变。
介绍
随着我越来越多地进入DevOps,Containers和Serverless; 我发现自己使用Python或JavaScript 在轻量级容器或FaaS中 编写容器化代码。Python和JavaScript是云原生微服务的最佳语言,Java在启动时无法在无服务器框架中使用,而且对于微服务来说,JavaScript或Python具有比Java更快的启动时间和更小的容器大小,从而使它们更高效。
Java已经有20多年的历史了,世界背后的Java与现在大不相同。JVM解决了一个巨大的问题,并允许我们编写一次代码并在多个平台和操作系统中运行它。通过Docker之类的容器,我们现在可以将我们的应用程序、库和操作系统资源打包到一个可以在任何地方运行的容器中,因此今天JVM本身的可移植性不太重要了。在当天,额外的开销是我们愿意支付便携性的费用,但现在不再支付。现在我们需要始终可用的快速,低延迟和反应式应用程序。容器和容器编排工具(如 Kubernetes) 提供独立于编程语言的功能。
随着公司迁移到微服务,他们采用 Spring Java服务,将它们捆绑到一个Jar中,添加JDK并在基于Linux的容器中运行它。这个解决方案有效,但你必须管理500MB大小的重量级容器,需要10到30秒才能使用; 这是一个问题。迁移后的许多公司,他们慢慢转向Python或Java作为后端服务; 并最终迁移到 FaaS 。无服务器和FaaS现在非常受欢迎,因为我们可以专注于编写函数而无需担心基础架构。它们仍在容器内运行,但云提供商管理其生命周期。巧妙的是,在一定时间之后,云提供商将完全杀死容器并在下次呼叫时再次启动它,因此您只需支付使用费用。对函数的第一次调用可能需要更长的时间,这就是著名的冷启动。发生这种情况是因为容器需要启动。使用Python或JavaScript时这不是一个大问题,但对于Java来说,这可能是10-15秒,这是一个交易破坏和Java下降的原因。现在我们需要能够运行,完成其工作然后停止的代码。我们不需要多个线程或长时间运行的进程,我们需要可以快速启动的短期进程。
介绍Quarkus
如果您阅读科技博客或关注新闻,您可能会认为 无服务器 正在蚕食这个世界,每个人都对它感到非常兴奋。创业企业现在可以使用JavaScript将函数编写为云中的服务,并将其扩展为支持数百万用户,而无需管理任何基础架构。然而如你在硅谷之外的话:比如金融机构,政府,零售和许多其他拥有数百万行代码的行业,他们无法承受重写,所以他们有点接受这样一个事实,即他们需要使用重量级容器。
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相比,生成的程序具有更快的启动时间和更低的运行时内存开销。这很好,但你可能会想,AOT?这违反了拥有JVM的整个想法,这是我无法在任何地方运行的Java代码!这太疯狂了!。但想想看,我们现在有容器,我们不需要JVM。
基于容器 的常见Spring启动应用程序具有额外的抽象级别,这在Kubernetes世界中是完全没有必要的。你有一个在容器内的JVM上运行的Java应用程序,这个容器永远不会改变,因为现在的交付容器不是应用程序的容器,你打包容器而不是WAR。所以,所有在容器内的JVM中运行应用程序的开销是无用的,因此如果要将应用程序打包到容器中,AOT就非常有意义。
但是,Java的动态特性受到AOT编译(运行时类加载,反射,代理等)的严重限制。实际上,这意味着90%的Java生态系统在没有变动的情况下就无法运行。所以Java生态系统必须适应。好消息是我们可以在构建时间做大部分工作!
这是Quarkus的力量。它使用GraalVM并提供在构建时支持AOT的生态系统,因此您可以使用Java创建本机二进制文件。Quarkus使GraalVM可用于Java开发人员!
Quarkus入门
如上所述,Quarkus提前为Java应用程序编译,创建了一个超小型的Subatomic Java生态系统,它具有极小的体积和超快的启动时间,使Java重新进入游戏以进行云原生开发。多年来我从未对新技术感到兴奋,而且我不是 唯一一个 。
尝试使用 入门指南 ,亲自查看。按照3个指南来查看Quarkus的力量并确定启动时间。仍然有成千上万的公司在容器内使用Java + JPA,这可能需要15秒才能启动,在Quarkus 0.005中!
您可以使用与Spring Boot世界中相同的IDE和工具。您使用Maven或Gradle来构建项目。您可以直接在IDE中运行它,最重要的是,您可以热重新加载任何更改,无需重新启动应用程序。Quarkus不是Spring,所以如果你使用Spring Boot,你将需要迁移Spring特定的代码,幸运的是,Quarkus附带了一个 Spring DI兼容层 ,这使得这很容易。Quarkus框架基于标准,这意味着代码将是可移植的并且易于维护。
Quarkus开发流程
Quarkus可以在开发模式下运行,类似于Spring Boot,您也可以将项目打包到Jar中。这非常适合测试代码和调试,因为它支持实时重载; 但是为了提前编译,需要编译。
Quarkus特点
Quarkus有更多只有原生Java代码才有的功能。
简而言之,现在您可以在任何环境,云或本地的超快速轻量级容器中运行传统的JPA / JTA事务服务。
Quarkus案例
在本节中,我们将简化 入门指南, 以了解Quarkus的强大功能。
创建新Quarkus项目的最简单方法是打开终端并运行以下命令:
mvn io.quarkus:quarkus-maven-plugin:0.12.0:create / -DprojectGroupId=org.acme / -DprojectArtifactId=getting-started / -DclassName=<font>"org.acme.quickstart.GreetingResource"</font><font> / -Dpath=</font><font>"/hello"</font><font> </font>
它生成一个带有GreetingResuce公开/ hello终点的Maven项目。它还为native和jvm(胖jar传统镜像)docker生成Dockerfile镜像。代码非常简洁:
@Path(<font>"/hello"</font><font>) <b>public</b> <b>class</b> GreetingResource { @GET @Produces(MediaType.TEXT_PLAIN) <b>public</b> String hello() { <b>return</b> </font><font>"hello"</font><font>; } } </font>
运行我们的应用程序。使用: ./mvnw compile quarkus:dev
该应用程序使用打包 ./mvnw package。它产生2个jar文件:
您可以使用以下命令运行该应用 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 .
现在您可以在任何容器orchectration引擎中运行它,以防您使用 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的格局,并使正常企业真正迁移到cloid。
Kubernetes + Knative + Quarkus是云原生开发的游戏规则改变者,也是任何Java开发人员的乐事。
通过大量示例查看 GIT Hub源码!