Статьи

Начало работы с Quarkus

Quarkus — Собственный Java-стек Kubernetes, разработанный специально для OpenJDK HotSpot и GraalVM, созданный на основе лучших в своем классе библиотек и стандартов Java. — это контейнерная среда, оптимизированная для быстрой загрузки и низкого потребления памяти. Фреймворк построен на основе многих популярных библиотек Java и обеспечивает поддержку для создания стандартных REST, а также микрореактивных и управляемых сообщениями микросервисов. Благодаря быстрому запуску и низкому использованию памяти Quarkus также может использоваться для реализации функций в безсерверной среде. Quarkus предоставляет множество возможностей для быстрой разработки приложений благодаря унифицированной конфигурации, удивительным функциям перезагрузки в реальном времени и поддержке инструментов.

Узнайте, как начать работу с Quarkus и создать API-интерфейс REST PetClinic.

Эта запись блога охватывает:

  • Требования к среде разработки
  • Создание нового проекта
  • Разработка, сборка и запуск приложения с Java 11
  • Конфигурация источника данных с Postgres и Flyway
  • CRUD сервис с нумерацией страниц
  • Создание интеграционных тестов
  • Живая перезагрузка и отладка
  • Докеризация приложения (как нативного, так и нативного)

О PetClinic API

Я решил повторно использовать модель PetClinic, которую использовал в этом блоге Spring Boot и Spring Data REST .

По сути, это базовая служба CRUD для управления воображаемой PetClinic: домашние животные, ветеринары, визиты и т. Д.

Prerequisities

докер

Docker будет использоваться для запуска докеризованной версии самой службы, но он также будет использоваться для запуска сервера PostgreSQL .

JDK 11 с GraalVM

API PetClinic будет построен с Java 11, поэтому JDK 11 должен быть установлен. Для сборки собственных исполняемых файлов должен присутствовать GraalVM 19.3+, и, поскольку он построен поверх OpenJDK 11, это будет лучшим выбором для этого урока. Самый простой способ установить (и управлять несколькими версиями) Java SDK с SDKMAN!

Узнайте, как управлять несколькими Java SDK с SDKMAN! легко

Для поддержки собственных образов убедитесь, что установлены все необходимые зависимости. Дополнительную информацию можно найти в документации GraalVM: https://www.graalvm.org/docs/reference-manual/native-image/

GraalVM официальная документация: GraalVM

Терминал

Сервис был разработан на macOS с iTerm2 и oh-my-zsh . Я также использую httpie как мой HTTP-клиент по умолчанию.

IntelliJ

Мой предпочтительный IDE — IntelliJ, и я использовал это, работая над этим проектом.

Узнайте больше об инструментах, которые я использовал на macOS в этой статье: macOS: необходимые инструменты для разработчика (Java)

Запустите PostgreSQL с помощью Docker

Приложение будет подключаться к серверу Postgres и в зависимости от профиля ( dev , test , prod ) будут применяться разные конфигурации. Для этого нам понадобятся три сервера: каждый с разными именем базы данных, портом и учетными данными. Чтобы упростить настройку, можно использовать Docker.

База данных разработчиков

  • Создайте и запустите контейнер:
1
$ docker run --name petclinic-db-dev -p 5433:5432 -e POSTGRES_DB=petclinic-dev -e POSTGRES_USER=petclinic-dev -e POSTGRES_PASSWORD=petclinic-dev -d postgres:alpine
  • Запустить ранее остановленный контейнер:
1
$ docker start petclinic-db-dev

Тестовая база данных

  • Создайте и запустите контейнер:
1
$ docker run --name petclinic-db-test -p 5434:5432 -e POSTGRES_DB=petclinic-test -e POSTGRES_USER=petclinic-test -e POSTGRES_PASSWORD=petclinic-test -d postgres:alpine
  • Запустить ранее остановленный контейнер:
1
$ docker start petclinic-db-test

База данных

  • Создайте и запустите контейнер:
1
$ docker run --name petclinic-db -p 5432:5432 -e POSTGRES_DB=petclinic -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -d postgres:alpine
  • Запустить ранее остановленный контейнер:
1
$ docker start petclinic-db

Начиная

Загрузите приложение

Вы можете загрузить приложение с помощью Maven из командной строки или использовать онлайн-генератор. Онлайновый генератор позволяет исследовать расширения и технологии, из которых может быть сделано приложение Quarkus, и не требует локальной установки Maven . Вы можете получить доступ к генератору здесь: https://code.quarkus.io

Для построения службы PetClinic API необходимы следующие расширения:

  • RESTEasy JAX-RS — платформа REST, реализующая JAX-RS и многое другое
  • RESTEasy Jackson — поддержка сериализации Jackson для RESTEasy
  • SmallRye OpenAPI — Документирование ваших REST API с помощью OpenAPI — поставляется с Swagger UI
  • Hibernate ORM с Panache — Определите свою постоянную модель в Hibernate ORM с Panache
  • Hibernate Validator — проверка данных, поступающих на конечные точки REST
  • Драйвер JDBC — PostgreSQL — коннектор базы данных PostgreSQL
  • Flyway — управляйте миграцией схемы базы данных

После того, как зависимости выбраны, вы можете скачать zip, распаковать его и начать разработку сервиса.

Загруженный проект имеет стандартную компоновку проекта Maven . Он содержит Maven Wrapper, поэтому для разработки проекта не требуется локальная установка Maven . Вы также заметите src/main/docker с файлами Docker как для собственного, так и для образа JVM.

Основной файл конфигурации — application.properties — находится в src/main/resources . Эта папка также содержит папку META-INF/resources для статических ресурсов приложения, таких как файл index.html .

Установите версию Java на 11 в pom.xml а также в файлах Docker

Онлайновый генератор генерирует проект с Java 8 по умолчанию, поэтому для использования Java 11 необходимы некоторые корректировки.

  • В pom.xml сгенерированного проекта измените версию Java:
1
2
<maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  • В src/main/docker/Dockerfile.jvm установите ARG JAVA_PACKAGE=java-11-openjdk-headless

Запустите проект в режиме разработки

После внесения изменений вы можете запустить приложение. Откройте свой терминал, перейдите в папку проекта и выполните следующую команду:

1
$ ./mvnw compile quarkus:dev

Примечание. Quarkus имеет три встроенных режима: dev , test и prod зависимости от того, как вы запускаете приложение.

Разработка в IntelliJ

В IntelliJ вы просто открываете папку проекта или pom.xml . ( File > Open ). Проект можно запустить только с Maven . Это можно сделать с помощью конфигураций запуска Maven, поскольку нет основного класса для запуска приложения, как, например, в Spring Boot .

Для меня лучший опыт при разработке с Quarkus был, когда я запускал приложение в терминале, за пределами IntelliJ.

Отладка

Когда приложение Quarkus выполняется в режиме разработки, оно запускается с включенным протоколом отладки (на порту 5005). Для отладки приложения Quarkus в IntelliJ необходимо подключить отладчик к запущенному процессу через « Run > Attach to Process . У меня не было проблем с отладкой приложения.

Примечание. Вы можете запустить приложение в режиме разработки с отключенной отладкой: ./mvnw quarkus:dev -Ddebug=false , но, честно говоря, я не заметил каких-либо проблем с производительностью, если по умолчанию включен отладчик.

Live Обновить

На мой взгляд, живая перезагрузка — одна из самых сильных сторон Quarkus. Это работает потрясающе. По сути, вы можете изменить все, что захотите в исходном коде, выполнить запрос, и приложение перезагрузится в мгновение ока. Я перекрашивал классы и пакеты, перемещал файлы, добавлял и удалял конечные точки и все это без единого перезапуска.

Конфигурация источника данных

Все свойства находятся в src/main/resources/application.properties .

Свойства источника данных по умолчанию ( prod )

1
2
3
4
quarkus.datasource.url=jdbc:postgresql://localhost:5432/petclinic
quarkus.datasource.driver=org.postgresql.Driver
quarkus.datasource.username=petclinic
quarkus.datasource.password=petclinic

Свойства источника данных Dev ( dev )

Для настройки режима (или профиля) определенных свойств используйте %mode :

1
2
3
%dev.quarkus.datasource.url=jdbc:postgresql://localhost:5433/petclinic-dev
%dev.quarkus.datasource.username=petclinic-dev
%dev.quarkus.datasource.password=petclinic-dev

Тестирование свойств источника данных ( test )

1
2
3
%test.quarkus.datasource.url=jdbc:postgresql://localhost:5434/petclinic-test
%test.quarkus.datasource.username=petclinic-test
%test.quarkus.datasource.password=petclinic-test

Смотрите также: https://quarkus.io/guides/datasource

Миграция

Чтобы использовать Flyway, создайте папку db/migration igration в src/main/resources и добавьте свои файлы миграции. Мой первый файл миграции называется V1.0.0__PetClinic.sql и содержит всю схему (DDL) и пример данных для службы.

Примечание. Quarkus поддерживает импорт SQL, который можно настроить с помощью quarkus.hibernate-orm.sql-load-script для каждого профиля, но я не смог заставить его работать. Смотрите проблему, о которой я сообщил на Github: https://github.com/quarkusio/quarkus/issues/7358

Смотрите также: https://quarkus.io/guides/flyway

JPA Entities

Модель предметной области PetClinic относительно проста, но она состоит из однонаправленных и двунаправленных ассоциаций, а также базового наследования, что делает ее немного лучше, чем простая модель Hello World .

Обратите внимание, что в этом примере сущности JPA возвращаются непосредственно в ресурсах JAX-RS соответствующими репозиториями Panache (см. Ниже), поэтому классы сущностей содержат смесь аннотаций JPA и Джексона.

Например:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Entity
@Table(name = "visits")
public class Visit extends BaseEntity {
 
    @Column(name = "visit_date")
    @JsonFormat(pattern = "yyyy/MM/dd HH:mm")
    private LocalDateTime date;
 
    @NotEmpty
    @Column(name = "description")
    private String description;
 
    @ManyToOne
    @JoinColumn(name = "pet_id")
    private Pet pet;
 
    @ManyToOne
    @JoinColumn(name = "vet_id")
    private Vet vet;
 
    public Visit() {
        this.date = LocalDateTime.now();
    }
}
 
@Entity
@Table(name = "vets",
        uniqueConstraints =
        @UniqueConstraint(columnNames = {"first_name", "last_name"})
)
public class Vet extends Person {
 
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"),
            inverseJoinColumns = @JoinColumn(name = "specialty_id"))
    @JsonIgnore
    private Set<Specialty> specialties;
 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "vet", fetch = FetchType.EAGER)
    @JsonIgnore
    private Set<Visit> visits;
}

Все объекты находятся в пакете pl.codeleak.samples.petclinic.model .

Hibernate ORM с Panache

Если вы знакомы с Spring, я думаю, вы слышали о проекте Spring Data. На мой взгляд, Hibernate ORM с Panache имеет аналогичную цель: она упрощает разработку JPA, устраняя необходимость в повторяющейся и утомительной работе. Panache поддерживает сортировку, разбиение на страницы, java.util.Optional и java.utitl.stream.Stream и т. Д.

У вас есть два подхода для работы с Panache: создание сущностей с PanacheEntity или создание репозиториев с PanacheRepository . В этом проекте я попробовал оба подхода, но из-за некоторых проблем с наследованием в сущностях я решил придерживаться старомодного способа.

Базовое определение репозитория с Hibernate ORM с Panache:

1
2
3
4
5
public class OwnerRepository implements PanacheRepository<Owner> {
    List<Owner> findByLastName(String lastName) {
        return list("lastName", lastName);
    }
}

Все репозитории находятся в пакете pl.codeleak.samples.petclinic.repository .

Смотрите также: https://quarkus.io/guides/hibernate-orm-panache

Создание REST API

Ресурсы JAX-RS

Quarkus использует JAX-RS с RESTEasy. Для создания конечных точек API нам нужно создать ресурсы JAX-RS:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@Path(OwnerResource.RESOURCE_PATH)
@Produces(MediaType.APPLICATION_JSON)
public class OwnerResource {
 
    public static final String RESOURCE_PATH = "/owners";
 
    @Context
    UriInfo uriInfo;
 
    @Inject
    OwnerRepository ownerRepository;
 
    @Inject
    PetRepository petRepository;
 
    @GET
    public Response getAll(@BeanParam PageRequest pageRequest) {
         
    }
 
    @GET
    @Path("{id}")
    public Response getOne(@PathParam("id") Long id) {
 
    }
 
    @GET
    @Path("{id}/pets")
    public List<Pet> getPets(@PathParam("id") Long id) {
     
    }
 
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Transactional
    public Response create(@Valid Owner owner) {
     
    }
}

Внедрение зависимостей выполняется с помощью CDI — Context и Dependency Injection . Объекты ресурса будут автоматически настроены Quarkus. Все остальные зависимости должны быть настроены для внедрения зависимостей с аннотациями CDI.

Например, репозитории можно аннотировать с помощью @ApplicationScoped а затем вводить с помощью @Inject :

01
02
03
04
05
06
07
08
09
10
11
@ApplicationScoped
public class OwnerRepository implements PanacheRepository<Owner> {
    List<Owner> findByLastName(String lastName) {
        return list("lastName", lastName);
    }
}
 
@ApplicationScoped
public class PetRepository implements PanacheRepository<Pet> {
 
}

Все ресурсы находятся в пакете pl.codeleak.samples.petclinic.api .

Смотрите также: https://quarkus.io/guides/cdi-reference

пагинация

Как упоминалось ранее, Panache обеспечивает поддержку разбитых на страницы результатов. Мы можем легко использовать это в наших ресурсах:

1
2
3
4
5
6
@GET
public Response getAll(@BeanParam PageRequest pageRequest) {
    return Response.ok(((PanacheRepository) petRepository).findAll()
                    .page(Page.of(pageRequest.getPageNum(), pageRequest.getPageSize()))
                    .list()).build();
}

PageRequest — это bean-компонент, содержащий параметры запроса pageNum и pageSize :

01
02
03
04
05
06
07
08
09
10
11
public class PageRequest {
 
    @QueryParam("pageNum")
    @DefaultValue("0")
    private int pageNum;
 
    @QueryParam("pageSize")
    @DefaultValue("10")
    private int pageSize;
 
}

Выполнение разбитого на страницы запроса может быть легко выполнено с помощью httpie:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ http get :8080/owners pageNum==0 pageSize==2
 
HTTP/1.1 200 OK
Content-Length: 250
Content-Type: application/json
 
[
    {
        "address": "110 W. Liberty St.",
        "city": "Madison",
        "firstName": "George",
        "id": 1,
        "lastName": "Franklin",
        "telephone": "6085551023"
    },
    {
        "address": "638 Cardinal Ave.",
        "city": "Sun Prairie",
        "firstName": "Betty",
        "id": 2,
        "lastName": "Davis",
        "telephone": "6085551749"
    }
]

операции

Создание нового объекта в JPA требует активной транзакции. Чтобы привязать транзакцию к текущему методу в объекте ресурса, используйте @Transactional , в противном случае во время выполнения метода будет @Transactional исключение:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Transactional
public Response create(@Valid Owner owner) {
 
    ownerRepository.persist(owner);
 
    var location = uriInfo.getAbsolutePathBuilder()
            .path("{id}")
            .resolveTemplate("id", owner.getId())
            .build();
 
    return Response.created(location).build();
}

Создать новый ресурс с httpie:

01
02
03
04
05
06
07
08
09
10
11
12
$ http post :8080/owners <<< '
{
    "address": "110 W. Liberty St.",
    "city": "Madison",
    "firstName": "George",
    "lastName": "Franklin",
    "telephone": "6085551023"
}'
 
HTTP/1.1 201 Created
Content-Length: 0
Location: http://localhost:8080/owners/1042

Проверка

В проекте используется расширение Hibernate Validator. С этим расширением вы можете использовать стандартные аннотации проверки Hibernate (например, @NotBlank ), и когда входной параметр для методов ресурса аннотируется @Valid проверка будет автоматически инициирована, и клиенту, вызывающему этот метод, будет возвращен ответ об ошибке.

Пример ответа на следующий запрос:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ http post :8080/owners <<< '{}'
 
HTTP/1.1 400 Bad Request
Content-Length: 626
Content-Type: application/json
validation-exception: true
 
{
    "classViolations": [],
    "exception": null,
    "parameterViolations": [
        {
            "constraintType": "PARAMETER",
            "message": "must not be empty",
            "path": "create.owner.address",
            "value": ""
        },
         
        ...
 
        {
            "constraintType": "PARAMETER",
            "message": "must not be empty",
            "path": "create.owner.telephone",
            "value": ""
        }
    ],
    "propertyViolations": [],
    "returnValueViolations": []
}

Замечание о фукциональности прямой перезагрузки: вы можете внести любые изменения в исходный код и выполнить новый запрос с помощью httpie. Приложение быстро перезагружается, и вы получаете немедленные результаты. Никаких перезапусков не требуется.

Смотрите также: https://quarkus.io/guides/validation

Поддержка Java 8 Date & Time

Типы java.util.time поддерживаются во время сериализации и десериализации JSON, когда расширение RESTEasy Jackson находится в проекте.

В следующем примере дата посещения должна быть сериализована и десериализована в формате, предоставленном аннотацией @JsonFormat :

1
2
3
4
5
6
7
8
9
@Entity
@Table(name = "visits")
public class Visit extends BaseEntity {
 
    @Column(name = "visit_date")
    @JsonFormat(pattern = "yyyy/MM/dd HH:mm")
    private LocalDateTime date;
 
}

Проверьте, как дата сериализуется с помощью htppie:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
$ http get :8080/visits/1
 
HTTP/1.1 200 OK
Content-Length: 174
Content-Type: application/json
 
{
    "date": "2013/01/01 00:00",
    "description": "rabies shot",
    "id": 1,
    "pet": {
        "birthDate": "2012/09/04",
        "id": 7,
        "name": "Samantha"
    },
    "vet": {
        "firstName": "Helen",
        "id": 2,
        "lastName": "Leary"
    }
}

Вы также можете сохранить посещение, используя требуемый формат даты и времени в теле запроса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
$ http post :8080/visits <<< '
{
    "date": "2020/01/01 00:00",
    "description": "lorem ipsum",
    "pet": {
        "id": 7
    },
    "vet": {
        "id": 2
    }
}'
 
HTTP/1.1 201 Created
Content-Length: 0
Location: http://localhost:8080/visits/1042

Поддержка OpenAPI / Swagger

Расширение SmallRye OpenAPI заботится о предоставлении документации по API, а SwaggerUI включен в режиме разработки.

Конечные точки по умолчанию:

  • Документация OpenAPI — /openapi
  • SwaggerUI — /swaggerui

Смотрите также: https://quarkus.io/guides/openapi-swaggerui

Интеграционные тесты

Quarkus использует JUnit 5 и RESTAssured для интеграционного тестирования. Тесты могут быть созданы с использованием аннотаций @QuarkusTest и они выполняются с активным профилем test по умолчанию.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@QuarkusTest
public class PetResourceTest {
 
    @Test
    public void pagedList() {
        given()
                .when().get("/pets?pageNum=0&pageSize=2")
                .then()
                .statusCode(200)
                .body(
                        "$.size()", is(2),
                        "name", containsInAnyOrder("Leo", "Basil")
                );
    }
}

Тесты Quarkus требуют, чтобы приложение работало. Существуют возможности замены выбранных bean-компонентов в тесте с использованием определений @Alternate компонентов CDI @Alternate . Альтернативные bean-компоненты должны быть помещены в src/test/java .

Примечание. Благодаря поддержке профилей вы можете легко настроить источник данных для test профиля с отдельным контейнером базы данных. См. Проверка свойств источника данных .

Смотрите также: https://quarkus.io/guides/getting-started-testing

Упаковка и запуск приложения

Приложение может быть упаковано ./mvnw package .

Он создает исполняемый файл quarkus-petclinic-api-1.0.0-runner.jar каталоге /target а зависимости копируются в каталог target/lib .

1
2
3
4
5
6
7
8
[INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building thin jar: /Users/rafal.borowiec/Projects/quarkus/quarkus-petclinic-api/target/quarkus-petclinic-api-1.0.0-runner.jar
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 1888ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  15.868 s
[INFO] Finished at: 2020-02-23T19:18:25+01:00
[INFO] ------------------------------------------------------------------------

Теперь приложение можно запустить с помощью java -jar target/quarkus-petclinic-api-1.0.0-runner.jar .

1
2
3
2020-02-23 19:19:10,169 INFO  [io.quarkus] (main) quarkus-petclinic-api 1.0.0 (running on Quarkus 1.2.1.Final) started in 2.011s. Listening on: http://0.0.0.0:8080
2020-02-23 19:19:10,171 INFO  [io.quarkus] (main) Profile prod activated.
2020-02-23 19:19:10,171 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, flyway, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, rest-client, resteasy, resteasy-jackson, smallrye-openapi]

Примечание: uber-jar может быть упакован с ./mvnw clean package -DskipTests=true -Dquarkus.package.uber-jar=true

Создайте контейнер Docker, который запускает приложение в режиме JVM

1
2
3
4
5
$ ./mvnw clean package
$ docker build -f src/main/docker/Dockerfile.jvm -t quarkus/petclinic-api-jvm .
 
Successfully built 1a5d963fedfa
Successfully tagged quarkus/petclinic-api-jvm:latest

Запустите контейнер со ссылкой, создайте контейнер базы данных Postgres и переопределите URL источника данных переменной среды:

1
2
3
4
5
6
$ docker run -i --rm -p 8080:8080 --link petclinic-db -e QUARKUS_DATASOURCE_URL='jdbc:postgresql://petclinic-db/petclinic' quarkus/petclinic-api-jvm
 
 
2020-02-23 20:39:18,949 INFO  [io.quarkus] (main) quarkus-petclinic-api 1.0.0 (running on Quarkus 1.2.1.Final) started in 3.475s. Listening on: http://0.0.0.0:8080
2020-02-23 20:39:18,949 INFO  [io.quarkus] (main) Profile prod activated.
2020-02-23 20:39:18,949 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, flyway, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, rest-client, resteasy, resteasy-jackson, smallrye-openapi

Примечание: petclinic-db — это имя контейнера Postgres, созданного здесь: База данных Prod . Нам также нужно передать URL источника данных. Подробнее о переопределении свойств конфигурации во время выполнения: Переопределение свойств во время выполнения

Создать собственный исполняемый файл

Вы можете создать собственный исполняемый файл, используя следующую команду:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ./mvnw package -Pnative
 
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Building native image from /Users/rafal.borowiec/Projects/quarkus/quarkus-petclinic-api/target/quarkus-petclinic-api-1.0.0-native-image-source-jar/quarkus-petclinic-api-1.0.0-runner.jar
 
...
 
[quarkus-petclinic-api-1.0.0-runner:50503]   (typeflow):  72,535.72 ms
[quarkus-petclinic-api-1.0.0-runner:50503]    (objects):  49,325.68 ms
[quarkus-petclinic-api-1.0.0-runner:50503]   (features):   3,115.04 ms
[quarkus-petclinic-api-1.0.0-runner:50503]     analysis: 135,220.10 ms
[quarkus-petclinic-api-1.0.0-runner:50503]     (clinit):   1,966.77 ms
[quarkus-petclinic-api-1.0.0-runner:50503]     universe:   6,919.51 ms
[quarkus-petclinic-api-1.0.0-runner:50503]      (parse):  13,679.33 ms
[quarkus-petclinic-api-1.0.0-runner:50503]     (inline):  18,193.40 ms
[quarkus-petclinic-api-1.0.0-runner:50503]    (compile):  70,849.75 ms
[quarkus-petclinic-api-1.0.0-runner:50503]      compile: 111,062.75 ms
[quarkus-petclinic-api-1.0.0-runner:50503]        image:   8,843.46 ms
[quarkus-petclinic-api-1.0.0-runner:50503]        write:   1,789.58 ms
[quarkus-petclinic-api-1.0.0-runner:50503]      [total]: 282,727.03 ms
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 287304ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  04:58 min
[INFO] Finished at: 2020-02-23T19:25:10+01:00
[INFO] ------------------------------------------------------------------------

Процесс создания собственного исполняемого файла занимает довольно много времени, но стоит дождаться его завершения, чтобы увидеть время запуска приложения:

1
2
3
4
5
6
$ ./target/quarkus-petclinic-api-1.0.0-runner
 
 
2020-02-23 19:26:03,959 INFO  [io.quarkus] (main) quarkus-petclinic-api 1.0.0 (running on Quarkus 1.2.1.Final) started in 0.066s. Listening on: http://0.0.0.0:8080
2020-02-23 19:26:03,959 INFO  [io.quarkus] (main) Profile prod activated.
2020-02-23 19:26:03,959 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, flyway, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, rest-client, resteasy, resteasy-jackson, smallrye-openapi]

0,67 секунды для собственного исполняемого файла, чтобы начать сравнение с 2 секундами для версии JVM.

Создайте контейнер Docker, который запускает приложение в основном режиме

По умолчанию собственный исполняемый файл создается в формате, поддерживаемом вашей операционной системой. Поскольку контейнер может не использовать тот же формат исполняемого файла, что и в вашей операционной системе, сборка Maven может создать исполняемый файл из контейнера:

1
$ ./mvnw package -Pnative -Dquarkus.native.container-build=true

Чтобы настроить версию образа строителя, вам нужно установить quarkus.native.builder-image :

1
$ ./mvnw clean package -Pnative -DskipTests=true -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-native-image:20.0.0-java11

А теперь соберите и запустите контейнер:

1
2
3
$ docker build -f src/main/docker/Dockerfile.native -t quarkus/petclinic-api .
 
$ docker run -i --rm -p 8080:8080 quarkus/petclinic-api

Примечание. Подробнее о создании собственных исполняемых файлов можно найти в документации по Quarkus: https://quarkus.io/guides/building-native-image

Исходный код

Исходный код этой статьи можно найти на Github: https://github.com/kolorobot/quarkus-petclinic-api

Смотрите оригинальную статью здесь: Начало работы с Quarkus

Мнения, высказанные участниками Java Code Geeks, являются их собственными.