欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

开发环境

下载JDK19

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

修改maven的配置

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

➜  ~ mvn -version
Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0)
Maven home: /Users/zhaoqin/software/apache-maven-3.8.5
Java version: 19, vendor: Azul Systems, Inc., runtime: /Library/Java/JavaVirtualMachines/zulu-19.jdk/Contents/Home
Default locale: zh_CN_#Hans, platform encoding: UTF-8
OS name: "mac os x", version: "12.6", arch: "aarch64", family: "mac"

创建Quarkus项目

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

IDEA设置

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

编码

<?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>com.bolingcavalry</groupId>
    <artifactId>quarkus-virual-threads-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <compiler-plugin.version>3.8.1</compiler-plugin.version>
        <maven.compiler.release>19</maven.compiler.release>
        <maven.compiler.source>19</maven.compiler.source>
        <maven.compiler.target>19</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
        <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
        <quarkus.platform.version>2.13.2.Final</quarkus.platform.version>
        <skipITs>true</skipITs>
        <surefire-plugin.version>3.0.0-M7</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-reactive-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-reactive-pg-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-arc</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-reactive</artifactId>
        </dependency>
        <!-- 生成测试数据 -->
        <dependency>
            <groupId>net.datafaker</groupId>
            <artifactId>datafaker</artifactId>
            <version>1.6.0</version>
        </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>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus.platform.version}</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                            <goal>generate-code</goal>
                            <goal>generate-code-tests</goal>
                        </goals>
                    </execution>
                </executions>
                <!-- 这里是新增的虚拟线程相关特性,start -->
                <configuration>
                    <source>19</source>
                    <target>19</target>
                    <compilerArgs>
                        <arg>--enable-preview</arg>
                    </compilerArgs>
                    <jvmArgs>--enable-preview --add-opens java.base/java.lang=ALL-UNNAMED</jvmArgs>
                </configuration>
                <!-- 这里是新增的虚拟线程相关特性,end -->
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                        <configuration>
                            <systemPropertyVariables>
                                <native.image.path>${project.build.directory}/${project.build.finalName}-runner
                                </native.image.path>
                                <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                                <maven.home>${maven.home}</maven.home>
                            </systemPropertyVariables>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <properties>
                <skipITs>false</skipITs>
                <quarkus.package.type>native</quarkus.package.type>
            </properties>
        </profile>
    </profiles>
</project>

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

quarkus.datasource.db-kind=postgresql
quarkus.datasource.jdbc.max-size=8
quarkus.datasource.jdbc.min-size=2
quarkus.datasource.username=quarkus
quarkus.datasource.password=123456
quarkus.datasource.reactive.url=postgresql://192.168.0.1:5432/quarkus_test
package com.bolingcavalry;
import io.quarkus.runtime.Quarkus;
import io.quarkus.runtime.annotations.QuarkusMain;
@QuarkusMain
public class VirtualThreadsDemoApp {
    public static void main(String... args) {
        Quarkus.run(args);
    }
}
package com.bolingcavalry.model;
public enum Gender {
    MALE, FEMALE;
}
package com.bolingcavalry.model;
import io.vertx.mutiny.sqlclient.Row;
public class Person {
    private Long id;
    private String name;
    private int age;
    private Gender gender;
    private Integer externalId;
    public String getThreadInfo() {
        return threadInfo;
    }
    public void setThreadInfo(String threadInfo) {
        this.threadInfo = threadInfo;
    }
    private String threadInfo;
    public Person() {
    }
    public Person(Long id, String name, int age, Gender gender, Integer externalId) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.externalId = externalId;
        this.threadInfo = Thread.currentThread().toString();
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Gender getGender() {
        return gender;
    }
    public void setGender(Gender gender) {
        this.gender = gender;
    }
    public Integer getExternalId() {
        return externalId;
    }
    public void setExternalId(Integer externalId) {
        this.externalId = externalId;
    }
    public static Person from(Row row) {
        return new Person(
                row.getLong("id"),
                row.getString("name"),
                row.getInteger("age"),
                Gender.valueOf(row.getString("gender")),
                row.getInteger("external_id"));
    }
}
package com.bolingcavalry.repository;
import com.bolingcavalry.model.Person;
import io.vertx.mutiny.pgclient.PgPool;
import io.vertx.mutiny.sqlclient.Row;
import io.vertx.mutiny.sqlclient.RowSet;
import io.vertx.mutiny.sqlclient.Tuple;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@ApplicationScoped
public class PersonRepositoryAsyncAwait {
    @Inject
    PgPool pgPool;
    public Person findById(Long id) {
        RowSet<Row> rowSet = pgPool
           .preparedQuery("SELECT id, name, age, gender, external_id FROM person WHERE id = $1")
           .executeAndAwait(Tuple.of(id));
        List<Person> persons = iterateAndCreate(rowSet);
        return persons.size() == 0 ? null : persons.get(0);
    }
    private List<Person> iterateAndCreate(RowSet<Row> rowSet) {
        List<Person> persons = new ArrayList<>();
        for (Row row : rowSet) {
            persons.add(Person.from(row));
        }
        return persons;
    }
}
package com.bolingcavalry.resource;
import com.bolingcavalry.model.Person;
import com.bolingcavalry.repository.PersonRepositoryAsyncAwait;
import io.smallrye.common.annotation.RunOnVirtualThread;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@Path("/vt/persons")
@RunOnVirtualThread
public class VTPersonResource {
    @Inject
    PersonRepositoryAsyncAwait personRepository;
    @GET
    @Path("/{id}")
    public Person getPersonById(@PathParam("id") Long id) {
        return personRepository.findById(id);
    }
}
package com.bolingcavalry.resource;
import com.bolingcavalry.model.Person;
import com.bolingcavalry.repository.PersonRepositoryAsyncAwait;
import io.smallrye.common.annotation.RunOnVirtualThread;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@Path("/pool/persons")
public class PoolPersonResource {
    @Inject
    PersonRepositoryAsyncAwait personRepository;
    @GET
    @Path("/{id}")
    public Person getPersonById(@PathParam("id") Long id) {
        return personRepository.findById(id);
    }
}

IDEA启动设置

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

启动和验证

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

构建镜像

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

FROM openjdk:19
ENV LANGUAGE='en_US:en'
# 执行工作目录
WORKDIR application
COPY --chown=185 target/*.jar ./
RUN mkdir config
EXPOSE 8080
USER 185
ENTRYPOINT ["java", "-jar", "--enable-preview", "quarkus-virual-threads-demo-1.0-SNAPSHOT-runner.jar"]
mvn clean package -U -DskipTests -Dquarkus.package.type=uber-jar
docker build -f src/main/docker/Dockerfile.19 -t bolingcavalry/quarkus-virual-threads-demo:0.0.2 .

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

异常测试(没有enable-preview参数会怎么样?)

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用

小结和展望

欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

发表回复