Java云原生框架Quarkus初探

Java云原生框架Quarkus初探

Quarkus 介绍

Quarkus 是一个云原生,容器优先的Java应用框架,它号称是超音速和亚原子的框架,主要特点是构建速度、启动速度快和占用资源少等特点。它为OpenJDK HotSpot和GraalVM量身定制,

根据Java库和标准精心打造的框架。主要有以下特性:

  1. 容器优先。Quarkus为GraalVM和HotSpot定制应用程序。令人惊讶的快速启动时间,令人难以置信的低RSS内存(不仅仅是堆的大小!),在Kubernetes等容器协调平台中提供近乎即时的扩展和高密度的内存利用。使用一种称之为编译时启动的技术。
  2. 统一指令式和响应式。在开发应用程序时,将熟悉的指令式和响应式代码风格结合起来。
  3. 基于Java社区和标准。Quarkus提供了一个有凝聚力的、有趣的、全栈式的框架,它利用了各类不断增长的50多个常用的最好的库。所有这些都在一个标准的主干上,让Java开发人员能够快速上手应用。
  4. Kube-Native。Quarkus和Kubernetes的组合为创建可伸缩、快速和轻量级的应用程序提供了理想的环境。Quarkus通过工具、预构建集成、应用程序服务等显著提高了开发人员的生产率。
  5. 对于Spring框架开发人员友好.Quarkus 的 Spring API 兼容性包括 Spring DI、Spring Web 和 Spring Data JPA。同时也在计划其他 Spring API,如 Spring Security 和 Spring Config。在 JVM 上运行时,Quarkus 应用程序几乎可以利用任何 Java 库。只要不使用 Java 反射,这些Java库就可以编译为原生。

安装Quarkus

官方推荐通过CLI方式安装。

  1. Linux/MacOS 和 Windows WSL 用户按以下方式安装。

    curl -Ls https://sh.jbang.dev | bash -s - trust add https://repo1.maven.org/maven2/io/quarkus/quarkus-cli/

    curl -Ls https://sh.jbang.dev | bash -s - app install --fresh --force quarkus@quarkusio

  2. Windows Powershell 用户以下方式安装。

    iex "& { $(iwr https://ps.jbang.dev) } trust add https://repo1.maven.org/maven2/io/quarkus/quarkus-cli/"
    iex "& { $(iwr https://ps.jbang.dev) } app install --fresh --force quarkus@quarkusio"

  3. 个人还是比较喜欢使用SDKMAN来管理安装Java相关软件,Windows用户安装SDKMAN需要WSL、Cygwin或者MinGW.

    sdk install quarkus

安装成功后在命令行下输入:quarkus -- version 将显示版本号 x.y.z.Final 表示安装成功。

创建和运行Quarkus应用

  1. 使用Quarkus CLI 或者Maven 创建应用

    quarkus create rw-getstarted-quarkus && cd rw-getstarted-quarkus

    mvn io.quarkus.platform:quarkus-maven-plugin:3.2.3.Final:create
    -DprojectGroupId=org.wangyun
    -DprojectArtifactId=rw-getstarted-quarkus
    -Dextensions='resteasy-reactive'
    cd rw-getstarted-quarkus

作为一个老派的Java开发人员,我选择Maven的方式创建应用,可以充分使用国内Maven资源让下载更快.

  1. 在rw-getstarted-quarkus目录下运行Quarkus应用

    quarkus dev 或者 ./mvnw compile quarkus:dev

第一次运行需要时间比较长,需要从maven仓库下载大量的依赖,需要保持充分的耐心,如遇下载失败请多试几次,http默认监听端口是8080,直到看到如下界面。

Quarkus应用已经在localhost:8080运行了
应用启动首页显示
应用启动完成控制台选项
  1. 使用实时修改应用生效

默认生成的代码

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from RESTEasy Reactive - Rxx Wang";
    }
}

以上代码运行后如下图:

直接用文本编辑器或者IDE修改以下代码

package org.wangyun;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String hello() {
		return "Hello from RESTEasy Reactive - Rxx Wang";
	}

	@GET
	@Produces(MediaType.TEXT_PLAIN)
	@Path("/greeting/{name}")
	public String greeting(String name) {
		return "hello " + name;
	}
}

刷新浏览器后直接生效,如下图。

测试Quarkus应用

可以使用任何的Javar测试框架来测试Quarkus应用,Quarkus默认支持Junit5进行单元测试,同时集成了REST-Assured测试框架进行验证REST服务接口。

在刚才使用Quarkus脚手架生成项目的同时也生成了测试用例,如GreetingResourceTest和GreetingResourceTest。执行mvn test即可看到以下测试执行信息。

[INFO] Running org.wangyun.GreetingResourceTest
2023-08-12 11:44:24,724 INFO  [io.quarkus] (main) rw-getstarted-quarkus 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.2.3.Final) started in 0.742s. Listening on: http://localhost:8083
2023-08-12 11:44:24,734 INFO  [io.quarkus] (main) Profile test activated. 
2023-08-12 11:44:24,734 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy-reactive, smallrye-context-propagation, vertx]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.456 s - in org.wangyun.GreetingResourceTest
2023-08-12 11:44:25,211 INFO  [io.quarkus] (main) rw-getstarted-quarkus stopped in 0.012s
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.412 s
[INFO] Finished at: 2023-08-12T11:44:25+08:00
[INFO] ------------------------------------------------------------------------

需要注意运行了REST-Assured测试框架时会启动一个Servlet容器,默认使用的测试端口是8081,如果被占用会提示测试失败。在application.properties文件修改默认测试端口即可测试通过,具体例子如下:

quarkus.http.test-port=8083
quarkus.http.test-ssl-port=8446

为了加速应用开发流程,Quarkus支持实时编码。当应用运行在开发模式时,也可以将实时编码和持续测试结合,可以在DevUI或者控制台的命令行中执行测试用例,让代码修改和代码测试执行更快捷。具体可参考以下:

== Continuous Testing

[r] - Re-run all tests
[f] - Re-run failed tests
[b] - Toggle 'broken only' mode, where only failing tests are run (disabled)
[v] - Print failures from the last test run
[p] - Pause tests
[o] - Toggle test output (disabled)

也可在Dev UI上面执行:

具体的测试代码如下:

java: 复制代码
package org.wangyun;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import java.util.UUID;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class GreetingResourceTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/hello")
          .then()
             .statusCode(200)
             .body(is("Hello from RESTEasy Reactive - Rxx Wang"));
    }

	@Test
	public void testGreetingEndpoint() {
		String uuid = UUID.randomUUID().toString();
		given()
				.pathParam("name", uuid)
				.when().get("/hello/greeting/{name}")
				.then()
				.statusCode(200)
				.body(is("hello " + uuid));
	}
}

构建Quarkus应用

Quarkus 支持将应用程序编译为原生可执行文件,再将原生的可执行文件打包到一个容器中,天然地支持了Serverless和云原生应用。构建一个原生可执行文件需要使用GraalVM的发行版,在执行打包之前需要需设置GRAALVM_HOME环境变量,建议代码版本与Graalvm版本保持一致。编译后应用程序的原生可执行文件将包含应用程序代码、所需的库、Java API 和一个缩小版的虚拟机。较小的虚拟机基础提高了应用程序的启动时间和最小的磁盘占用。

可通过以下命令执行构建:

quarkus build --native
或
./mvnw install -Dnative

构建产生了 target/getting-started-1.0.0-SNAPSHOT-runner 。可以用以下方式运行应用程序: ./target/getting-started-1.0.0-SNAPSHOT-runner。

另外在没有安装GraalVM的情况下创建一个Linux可执行文件,但需要依赖一个工作的容器运行环境如Docker或者podman. 为了避免对GraalVM的版本依赖,Quarkus提供了一个非常方便的方法,通过利用容器运行时(如Docker或podman)来创建一个原生Linux可执行文件。完成这项任务的最简单方法是执行:

quarkus build --native --no-tests -Dquarkus.native.container-build=true
或
./mvnw install -Dnative -DskipTests -Dquarkus.native.container-build=true

部署Quarkus应用

Quarkus应用支持像一个标准Java应用程序一样部署,同时支持作为本地可执行文件部署。

应用程序创建原生(二进制)可执行文件之后,提供了一个具备快速启动时间和消耗更少内存的应用程序。针对现在容器化部署的场景,Quarkus提供了非常方便的镜像制作方式,提供了一个完整的Dockerfile, 只需要简单修改几处配置即可完成制作。动生成的项目在 src/main/docker 目录中提供了一个 Dockerfile.xxxxx,如Dockerfile.native-micro 内容如下:

FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

可以用以下方法构建docker镜像:

docker build -f src/main/docker/Dockerfile.native-micro -t quarkus-quickstart/getting-started .

用以下方式运行:

docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started

总结

Quarkus 作为一个全新的云原生和微服务框架,通过编译成本地运行的方式,对比传统的Java应用程序有着天然的运行性能优势,且占用较少的内存资源。同时又兼容常用的Java框架,降低了Java程序员的学习成本,让Java程序员可以快速上手开发应用。但是要看到目前业界采用并大规模部署的并不多,跟传统的Java程序兼容性还存在一定的问题,社区相对传统的Spring成熟度也有一些距离。对于一些新应用且对性能要求高的应用值得考虑。

相关推荐
学会沉淀。5 分钟前
Docker学习
java·开发语言·学习
如若1236 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
西猫雷婶36 分钟前
python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶
开发语言·python·opencv
kiiila36 分钟前
【Qt】对象树(生命周期管理)和字符集(cout打印乱码问题)
开发语言·qt
初晴~36 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
有一个好名字1 小时前
zookeeper分布式锁模拟12306买票
分布式·zookeeper·云原生
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾1 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
黑胡子大叔的小屋1 小时前
基于springboot的海洋知识服务平台的设计与实现
java·spring boot·毕业设计
ThisIsClark1 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试