本文要点:
2019年,Quarkus在企业Java生态系统中引起了不小的轰动。Quarkus到底是什么?它与市场上的其他技术有何不同?Quarkus为我或我的组织提供了什么帮助?让我们一起找出答案。
更多 Quarkus 的项目进展和路线图,敬请关注QCon全球软件开发大会(北京站)2020。届时红帽高级软件工程师冯征将进一步介绍 Quarkus 框架设计和特点,利用 Quarkus 进行应用开发、通过 Kubernetes 进行应用部署的实践案例。对下一代面向云原生的编程框架 Quarkus感兴趣的读者不要错过。
Quarkus项目自称是超音速亚原子Java。这是真的吗?这是什么意思?我们需要了解下软件开发的现状,才能更好地理解Quarkus项目背后的动机。
以前部署应用程序的方法是使用物理硬件。购买了物理机,我们就预先为硬件需求付了款。我们已经进行了投资,因此,使用所有的或者只是少量的机器资源都没有关系。在大多数情况下,只要能够运行应用程序,我们就不会关心其他事情了。然而,云正在改变我们开发和部署应用程序的方式。
因为云上按需付费,所以我们对硬件的使用越来越讲究。如果应用程序启动需要10秒,那么即使应用程序还没有准备好供其他人使用,我们也必须为这10秒付费。
你还记得第一个Java版本是什么时候发布的吗?请允许我提醒你一下,那是在1996年。那时还没有云。事实上,云是几年后才出现的。Java显然不适合这种新模式,必须进行调整。但是,这么多年来,我们都是在使用物理机,成本不像在云上那么重要,我们怎么才能改变这种模式呢?
多年来,许多Java库和框架的发展方式都是在运行时执行一组增强。这是一种安全、方便的向代码添加功能的声明性方法。你需要依赖注入吗?当然!使用注解。你需要事务吗?当然!使用注解。实际上,使用这些注解,你可以编写许多代码,运行时将提取并处理它们。但这有一个缺点,运行时需要扫描类路径和类以获取元数据。这是一个消耗时间和内存的昂贵操作。
Quarkus通过将昂贵的操作(如字节码增强、动态类加载、代理等)转移到编译时解决了这个问题。其结果是一个消耗内存和CPU更少、启动速度更快的环境。这非常适合云的应用场景,对于其他用例也非常有用。无论是什么样的环境,每个人都将受益于更少的资源消耗。
你听说过或使用过CDI、JAX-RS或JPA之类的技术吗?Quarkus技术栈就是由这些已经存在了好多年的技术组成的。如果你知道如何使用这些技术进行开发,那么你就会知道如何开发Quarkus应用程序。
你能读懂下面的代码吗?
@Path("books")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public class BookApi {
@Inject
BookRepository bookRepository;
@GET
@Path("/{id}")
Response get(@PathParam("id")Long id) {
return bookRepository.find(id)
.map(Response::ok)
.orElse(Response.status(NOT_FOUND))
.build();
}
}
恭喜,你已经有了自己的第一个Quarkus应用!
Quarkus编程模型建立在经过验证的标准之上,无论是官方标准还是事实标准。目前,Quarkus对Hibernate、CDI、Eclipse MicroProfile、Kafka、Camel、Vert.x、Spring、Flyway、Kubernetes、Vault等技术提供了一等支持。当使用Quarkus时,你从第一天开始就会很有效率,因为你真的不需要学习新技术。你只需要使用过去10年一直存在的东西。
你打算使用一个不在Quarkus生态系统中的库吗?除非你想在GraalVM Native模式下运行它,否则很有可能不需要任何额外的设置就可以直接使用。如果想更进一步,那么你可以轻松地实现自己的Quarkus扩展,为特定的技术提供支持,并丰富Quarkus生态系统。
那么,你可能会问,是否有什么东西还需要开发人员自己探索。实际上是有的。你需要在你的项目中使用Quarkus提供的一组特定的依赖项。别担心,Quarkus同时支持Maven和Gradle。方便起见,你可以在Quarkus starter页面中生成一个框架项目,并选择要使用哪些技术。将它导入到你喜欢的IDE中,就可以开始了。以下是一个使用JAX-RS with RESTEasy和JPA with Hibernate的Maven示例项目:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>code-with-quarkus</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus-plugin.version>1.3.0.Final</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>1.3.0.Final</quarkus.platform.version>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</project>
你可能已经注意到,大多数依赖项都是从groupId io.quarkus开始的,而且它们不是Hibernate、Resteasy或Junit的常见依赖项。
现在,你可能想知道,为什么Quarkus围绕这些流行库提供自己的包装器版本。其原因是为了在这些库和Quarkus之间提供一个桥梁,以便在编译时解析运行时依赖项。这就是Quarkus的神奇之处,其项目启动速度快,占用内存少。
这是否意味着你只能使用特定于Quarkus的库?绝对不是。你可以使用任何你想用的库。你可以在JVM上像往常一样运行Quarkus应用程序,这样就不会有任何限制。
也许你已经听说过Oracle实验室的GraalVM项目。本质上讲,GraalVM是一个通用的虚拟机,可以运行多种语言的应用程序。它最有趣的其中一个特性是,可以在原生镜像中构建应用程序并以更快的速度运行它!实际上,这意味着你有了一个可执行文件,应用程序所需的所有依赖项都是在编译时解析的。它不是在JVM上运行的——它是一个普通的可执行二进制文件,但是包含所有必需的组件,比如内存管理和线程调度,从一个特别的虚拟机Substrate VM运行你的应用程序。
方便起见,Maven示例项目已经具备了将你的项目构建为原生项目所需的设置。你需要在系统中安装GraalVM和native-image工具。请按照以下说明操作。之后,只需像其他任何Maven项目一样构建,但是使用本机配置文件:mvn verify -Pnative。这将在目标文件夹中生成一个二进制运行器,你可以使用./project-name-runner像运行任何其他二进制文件一样运行它。以下是我机器上的一个运行器输出样例:
[io.quarkus] (main) code-with-quarkus 1.0.0-SNAPSHOT (powered by Quarkus 1.3.0.Final) started in 0.023s. Listening on: http://0.0.0.0:8080
INFO [io.quarkus] (main) Profile prod activated.
[io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, narayana-jta, resteasy, resteasy-jsonb]
注意到启动时间了吗?只有0.023秒。是的,我们的应用程序不大,但仍然令人印象深刻。即使是真实的应用程序,你也会看到毫秒级的启动时间。你可以在他们的网站上了解更多关于GraalVM的信息。
我们已经看到,Quarkus可以帮助你的公司成为云原生公司。太棒了。但是开发人员呢?我们都喜欢闪亮的新东西,我们也超级懒。Quarkus为开发者做了哪些其他技术做不到的事情?
那么,在不使用外部工具或复杂技巧的情况下,热重载是否也能正常工作呢?是的,这是真的。在Java诞生25年后,我们现在有了一种更改代码的可靠方法,并且通过简单的刷新就可以查看这些更改。这也是通过Quarkus的内部工作方式实现的。一切都是代码,所以你不必再担心那些使热重载变得困难的事情。这是一个很简单的操作。
要做到这一点,你必须在开发模式下运行Quarkus。只要运行mvn quarkus:dev就可以了。Quarkus将启动,你可以自由地对代码进行更改并立即看到它们。例如,你可以更改REST端点参数、添加新方法和更改路径。一旦你调用它们,它们将被更新以反映你的代码更改。这很酷吧?
所有这一切似乎好得令人难以置信,但Quakus真的准备好投入生产环境了吗?是的。
许多公司已经采用Quarkus作为他们的开发/运行环境。Quarkus有一个非常快的发布周期(每隔几周),以及一个强大的开源社区,它可以帮助Java社区中的每个开发人员,无论他们是刚刚开始使用Quarkus,还是已经是一个高级用户。
要查看这个示例应用程序,你可以下载或克隆它。你还可以阅读一些讲述采用故事的博文,更好地了解Quarkus的使用体验。
在官方发布一年后,Quarkus已经发布了1.3.1.Final版本。这个项目做了大量的工作来帮助公司和开发人员编写云原生应用程序。
我们不知道Quarkus能走多远,但有一件事可以肯定:Quarkus震撼了整个被Spring主宰着的Java生态系统。我认为,Java生态系统要想胜出,就需要提供多种可以相互推动的产品,并通过创新保持产品的竞争力。
相关资源:
作者简介:
Roberto Cortez是一位热诚的Java开发人员,拥有超过10年的经验。他参与开源社区,帮助其他人传播Java技术知识。他经常在JavaOne、Devoxx、Devnexus、JFokus等会议上发言。他领导着Coimbra JUG,并在葡萄牙创办了JNation会议。在业余时间,他会和朋友出去玩,玩电脑游戏或与家人呆在一起。
原文链接:
领取专属 10元无门槛券
私享最新 技术干货