简介

Java并不是为了Web而诞生,但似乎B/S架构让Java生机无限,Spring全家桶的助推也使得Java在Web更为强大,微服务体系Spring Cloud更是顺风顺水,不得不说的Spring应用的痛点就是启动过慢,内存占用偏高,对服务器资源占用较大,而且JVM的本身就难逃离内存的过度依赖。

随着容器化技术Docker、Kubernetes,让云原生似乎成为了未来的发展方向,云原生(Cloud-Native)这个概念最早由Pivotal公司的Matt Stine于2013年首次提出,提到云原生首先想到的关键词可能就是容器化、微服务、Lambda,服务网格等,当然这些是必要元素,但是不代表拥有这些元素就是云原生应用,很多应用的部署只能说是基于云来完成,比如私有云、公有云,这也是未来的趋势。云原生本质上不是部署,而是以什么方式来构建应用,云原生的最终目的是为了提高开发效率,提升业务敏捷度、扩容性、可用性、资源利用率,降低成本。

Go语言作为一种云原生语言也体现出了强大的生命力,Java也在变化,2018年Java出现了大量轻量级微服务框架,来面对未来的云原生趋势,Red Hat推出的Quarkus、Oracle的Helidon以及Spring Native都在快速发展,拥抱云原生。

本文简单介绍Quarkus的使用。

SUPERSONIC SUBATOMIC JAVA

官方网站简洁明了的介绍,直译就是超音速借给药JAVA,简单来说就是快。image.png
在内存或者启动方面都占据了大大的优势,而且支持响应式编程。

安装

准备

使用Quarkus需要准备环境

  • GraalVM Open-JDK-11
  • Maven 3.8.1+
  • Quarkus 2.6.2.Final

更多内容查看文档:https://quarkus.io/guides/getting-started

下载

官方网址:https://quarkus.io
下载地址:

下载时候注意Graal有基于不同JDK版本的支持,如JDK8,JDK11,JDK11,可根据自己需求下载。

环境变量

配置环境变量方式同Java一样

  • 配置JAVA_HOMEC:\Program Files\Java\graalvm-ce-java8-21.0.0.2
  • 环境变量配置不生效解决方案:

多个JDK版本情况下出现环境变量切换不生效,Windows本身系统system32里面的环境变量加载等级要优先于用户设置的环境变量,其根本原因是%JAVA_HOME%在path中配置的位置在%SystemRoot%\system32;后面,放到path最前面就好了。image.png

  • 配置好后执行命令确保使用的是GraalVM
C:\Users\starsray>java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-b07)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.0.2 (build 25.282-b07-jvmci-21.0-b06, mixed mode)

启动

创建项目

  • 使用web页面:访问通过网站:https://code.quarkus.io,这种方法类似于spring.io提供的web页面
  • 使用IDEA,这里不得不说IDEA的强大
    • image.png

运行

GraalVM运行

开发阶段,配置有用项目信息,默认在本机VM环境运行,在改变代码的同时无需重启项目即可实时生效大大提高了开发效率。

/opt/develop/graalvm-ce-java11-21.3.0/bin/java -Dmaven.multiModuleProjectDirectory=/home/starsray -Dmaven.home=/opt/ideaIU-2021.2.3/plugins/maven/lib/maven3 -Dclassworlds.conf=/opt/ideaIU-2021.2.3/plugins/maven/lib/maven3/bin/m2.conf -javaagent:/opt/ideaIU-2021.2.3/lib/idea_rt.jar=39437:/opt/ideaIU-2021.2.3/bin -Dfile.encoding=UTF-8 -classpath /opt/ideaIU-2021.2.3/plugins/maven/lib/maven3/boot/plexus-classworlds.license:/opt/ideaIU-2021.2.3/plugins/maven/lib/maven3/boot/plexus-classworlds-2.6.0.jar org.codehaus.classworlds.Launcher -Didea.version=2021.2.3 -DskipTests=true quarkus:dev
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------------< cn.starsray:quarkus-web >-----------------------
[INFO] Building quarkus-web 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- quarkus-maven-plugin:2.6.2.Final:dev (default-cli) @ quarkus-web ---
[INFO] Invoking org.apache.maven.plugins:maven-resources-plugin:2.6:resources) @ quarkus-web
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Invoking io.quarkus.platform:quarkus-maven-plugin:2.6.2.Final:generate-code) @ quarkus-web
[INFO] Invoking org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile) @ quarkus-web
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 5 source files to /home/starsray/IdeaProjects/quarkus-web/quarkus-web/target/classes
[INFO] Invoking org.apache.maven.plugins:maven-resources-plugin:2.6:testResources) @ quarkus-web
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/starsray/IdeaProjects/quarkus-web/quarkus-web/src/test/resources
[INFO] Invoking io.quarkus.platform:quarkus-maven-plugin:2.6.2.Final:generate-code-tests) @ quarkus-web
[INFO] Invoking org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile) @ quarkus-web
[INFO] Changes detected - recompiling the module!
Listening for transport dt_socket at address: 5005
Press [h] for more options>
Tests paused
Press [r] to resume testing, [h] for more options>
Press [r] to resume testing, [o] Toggle test output, [h] for more options>
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2022-01-16 23:20:15,687 ERROR [io.qua.run.Application] (Quarkus Main Thread) Port 8080 seems to be in use by another process. Quarkus may already be running or the port is used by another application.
2022-01-16 23:20:15,689 WARN  [io.qua.run.Application] (Quarkus Main Thread) Use 'netstat -anop | grep 8080' to identify the process occupying the port.
2022-01-16 23:20:15,690 WARN  [io.qua.run.Application] (Quarkus Main Thread) You can try to kill it with 'kill -9 <pid>'.
Press [space] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [h] for more options>

Docker运行

如果配置文件引入了数据库相关驱动,却没有指定可用的jdbc配置信息,启动项目会要求有可用的docker环境,自动创建docker镜像并运行,这也说明了quarkus对云原生的良好支持。

/opt/develop/graalvm-ce-java11-21.3.0/bin/java -Dmaven.multiModuleProjectDirectory=/home/starsray -Dmaven.home=/opt/ideaIU-2021.2.3/plugins/maven/lib/maven3 -Dclassworlds.conf=/opt/ideaIU-2021.2.3/plugins/maven/lib/maven3/bin/m2.conf -javaagent:/opt/ideaIU-2021.2.3/lib/idea_rt.jar=43095:/opt/ideaIU-2021.2.3/bin -Dfile.encoding=UTF-8 -classpath /opt/ideaIU-2021.2.3/plugins/maven/lib/maven3/boot/plexus-classworlds.license:/opt/ideaIU-2021.2.3/plugins/maven/lib/maven3/boot/plexus-classworlds-2.6.0.jar org.codehaus.classworlds.Launcher -Didea.version=2021.2.3 -DskipTests=true quarkus:dev
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------------< cn.starsray:quarkus-web >-----------------------
[INFO] Building quarkus-web 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- quarkus-maven-plugin:2.6.2.Final:dev (default-cli) @ quarkus-web ---
[INFO] Invoking org.apache.maven.plugins:maven-resources-plugin:2.6:resources) @ quarkus-web
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Invoking io.quarkus.platform:quarkus-maven-plugin:2.6.2.Final:generate-code) @ quarkus-web
[INFO] Invoking org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile) @ quarkus-web
[INFO] Nothing to compile - all classes are up to date
[INFO] Invoking org.apache.maven.plugins:maven-resources-plugin:2.6:testResources) @ quarkus-web
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/starsray/IdeaProjects/quarkus-web/quarkus-web/src/test/resources
[INFO] Invoking io.quarkus.platform:quarkus-maven-plugin:2.6.2.Final:generate-code-tests) @ quarkus-web
[INFO] Invoking org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile) @ quarkus-web
[INFO] Nothing to compile - all classes are up to date
Listening for transport dt_socket at address: 5005
Press [h] for more options>
Tests paused
Press [r] to resume testing, [h] for more options>
Press [r] to resume testing, [o] Toggle test output, [h] for more options>
2022-01-16 23:25:11,416 INFO  [org.tes.doc.DockerClientProviderStrategy] (build-37) Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2022-01-16 23:25:11,888 INFO  [org.tes.doc.DockerClientProviderStrategy] (build-37) Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2022-01-16 23:25:11,890 INFO  [org.tes.DockerClientFactory] (build-37) Docker host IP address is localhost
2022-01-16 23:25:11,935 INFO  [org.tes.DockerClientFactory] (build-37) Connected to docker: 
  Server Version: 19.03.8
  API Version: 1.40
  Operating System: UnionTech OS Desktop 20 Home
  Total Memory: 15688 MB
2022-01-16 23:25:11,938 INFO  [org.tes.uti.ImageNameSubstitutor] (build-37) Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
2022-01-16 23:25:12,005 INFO  [org.tes.uti.RegistryAuthLocator] (build-37) Failure when attempting to lookup auth config. Please ignore if you don't have images in an authenticated registry. Details: (dockerImageName: testcontainers/ryuk:0.3.3, configFile: /home/starsray/.docker/config.json. Falling back to docker-java default behaviour. Exception message: /home/starsray/.docker/config.json (没有那个文件或目录)
2022-01-16 23:25:12,676 INFO  [org.tes.DockerClientFactory] (build-37) Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
2022-01-16 23:25:12,676 INFO  [org.tes.DockerClientFactory] (build-37) Checking the system...
2022-01-16 23:25:12,677 INFO  [org.tes.DockerClientFactory] (build-37) ✔︎ Docker server version should be at least 1.6.0
2022-01-16 23:25:12,755 INFO  [org.tes.DockerClientFactory] (build-37) ✔︎ Docker environment should have more than 2GB free disk space
2022-01-16 23:25:12,780 INFO  [🐳 .io/.0.24]] (build-37) Creating container for image: docker.io/mysql:8.0.24
2022-01-16 23:25:12,781 INFO  [org.tes.uti.RegistryAuthLocator] (build-37) Failure when attempting to lookup auth config. Please ignore if you don't have images in an authenticated registry. Details: (dockerImageName: docker.io/mysql:8.0.24, configFile: /home/starsray/.docker/config.json. Falling back to docker-java default behaviour. Exception message: /home/starsray/.docker/config.json (没有那个文件或目录)
2022-01-16 23:25:12,874 INFO  [🐳 .io/.0.24]] (build-37) Starting container with ID: ec24cbadb7cdd72ce95cbdcb01011173939705e4c7685c070074fa7c0fbb270e
2022-01-16 23:25:13,122 INFO  [🐳 .io/.0.24]] (build-37) Container docker.io/mysql:8.0.24 is starting: ec24cbadb7cdd72ce95cbdcb01011173939705e4c7685c070074fa7c0fbb270e
2022-01-16 23:25:13,131 INFO  [🐳 .io/.0.24]] (build-37) Waiting for database connection to become available at jdbc:mysql://localhost:32773/default using query 'SELECT 1'
2022-01-16 23:25:26,498 INFO  [🐳 .io/.0.24]] (build-37) Container is started (JDBC URL: jdbc:mysql://localhost:32773/default)
2022-01-16 23:25:26,499 INFO  [🐳 .io/.0.24]] (build-37) Container docker.io/mysql:8.0.24 started in PT13.732728S
2022-01-16 23:25:26,499 INFO  [io.qua.dev.mys.dep.MySQLDevServicesProcessor] (build-37) Dev Services for MySQL started.
2022-01-16 23:25:26,500 INFO  [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-37) Dev Services for the default datasource (mysql) started.
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2022-01-16 23:25:27,968 ERROR [io.qua.hib.orm.run.sch.SchemaManagementIntegrator] (Hibernate post-boot validation thread for <default>) Failed to validate Schema: Schema-validation: missing table [employee]
2022-01-16 23:25:27,979 ERROR [io.qua.hib.orm.run.sch.SchemaManagementIntegrator] (Hibernate post-boot validation thread for <default>) The following SQL may resolve the database issues, as generated by the Hibernate schema migration tool. WARNING: You must manually verify this SQL is correct, this is a best effort guess, do not copy/paste it without verifying that it does what you expect.

create table employee (emp_no integer not null, birth_date date not null, first_name varchar(14) not null, gender char(1) not null, hire_date date not null, last_name varchar(16) not null, primary key (emp_no)) engine=InnoDB;

2022-01-16 23:25:28,003 INFO  [io.quarkus] (Quarkus Main Thread) quarkus-web 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.6.2.Final) started in 17.707s. Listening on: http://localhost:8080
2022-01-16 23:25:28,006 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2022-01-16 23:25:28,006 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, config-yaml, hibernate-orm, hibernate-orm-panache, jdbc-mysql, mybatis, mybatis-plus, narayana-jta, reactive-mysql-client, rest-client, rest-client-jackson, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-openapi, swagger-ui, vertx]

Native Image运行

这也是quarkus最强大的地方,通过GraalVM的可选组件native image可以将Java应用打包成原生镜像,真正做到秒级启动,解决了传统spring启动的痛点,当然也期待spring的下一代产品Spring Native

  • 使用命令安装native支持
sudo gu install native-image
  • 打包项目
mvn package -Pnative -DskipTests
  • 启动 做到了秒启动。

image.png

源码

仓库地址

完整代码地址

项目说明

项目组件说明:

  • quarkus-smallrye-openapi openapi实现引入支持swagger-ui
  • quarkus-mybatis/quarkus-mybatis-plus mybatis及mybatis-plus组件
  • quarkus-hibernate-orm-panache hibernate JPA实现
  • quarkus-config-yaml yaml语法配置文件相关依赖
  • quarkus-reactive-mysql-client mysql客户端依赖
  • quarkus-jdbc-mysql mysql JDBC驱动依赖
  • quarkus-resteasy-jackson rest接口依赖

注解相关说明:
Spring中有一套自己针对相关功能的注解实现,Quarkus也有自己的整合实现,列举相关的对应关系。
DI --> CDI
Spring Web --> JAX-RS
Spring Data JPA --> Panache
Swagger/Knife --> OpenAPI

更多注解对应关系查看文档:https://quarkus.io/guides/spring-web

Logo

更多推荐