Перейти к основному содержимому

Руководство по QuarkusIO

· 6 мин. чтения

1. Введение

В настоящее время очень распространено написать приложение и развернуть его в облаке, не беспокоясь об инфраструктуре. Бессерверные технологии и FaaS стали очень популярными.

В этом типе среды, где экземпляры часто создаются и уничтожаются, время загрузки и время первого запроса чрезвычайно важны, поскольку они могут создать совершенно другой пользовательский опыт.

Такие языки, как JavaScript и Python, всегда находятся в центре внимания в таких сценариях. Другими словами, Java с ее толстыми JAR-файлами и долгим временем загрузки никогда не была главным соперником.

В этом руководстве мы представим Quarkus и обсудим, является ли он альтернативой для более эффективного переноса Java в облако .

2. КваркусIO

QuarkusIO , сверхзвуковая субатомная Java, обещает предоставлять небольшие артефакты, чрезвычайно быстрое время загрузки и меньшее время до первого запроса. В сочетании с GraalVM Quarkus будет компилировать с опережением времени (AOT).

А поскольку Quarkus построен на основе стандартов, нам не нужно изучать что-то новое. Следовательно, мы можем использовать, среди прочего, CDI и JAX-RS. Также у Quarkus есть множество расширений , в том числе поддерживающих Hibernate, Kafka, OpenShift, Kubernetes и Vert.x.

3. Наше первое приложение

Самый простой способ создать новый проект Quarkus — открыть терминал и ввести:

mvn io.quarkus:quarkus-maven-plugin:0.13.1:create \
-DprojectGroupId=com.foreach.quarkus \
-DprojectArtifactId=quarkus-project \
-DclassName="com.foreach.quarkus.HelloResource" \
-Dpath="/hello"

Это создаст скелет проекта, HelloResource с открытой конечной точкой /hello , конфигурацией, проектом Maven и Dockerfiles.

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

./4cea22125fabcfd5a59d2ea67655c230.png

Давайте рассмотрим содержимое класса HelloResource :

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

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}

Пока все выглядит хорошо. На данный момент у нас есть простое приложение с одной конечной точкой RESTEasy JAX-RS. Давайте продолжим и протестируем его, открыв терминал и выполнив команду:

./mvnw compile quarkus:dev:

./ec2d1842c7d18cdd61ffebd53fbf54c3.png

Наша конечная точка REST должна быть открыта по адресу localhost:8080/hello. Давайте проверим это с помощью команды curl :

$ curl localhost:8080/hello
hello

4. Горячая перезагрузка

При работе в режиме разработки ( ./mvn compile quarkus:dev ) Quarkus предоставляет возможность горячей перезагрузки. Другими словами, изменения, внесенные в файлы Java или файлы конфигурации, будут автоматически скомпилированы после обновления браузера . Самая впечатляющая особенность здесь в том, что нам не нужно сохранять наши файлы. Это может быть хорошо или плохо, в зависимости от наших предпочтений.

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

Сначала мы создадим класс HelloService :

@ApplicationScoped
public class HelloService {
public String politeHello(String name){
return "Hello Mr/Mrs " + name;
}
}

Теперь мы изменим класс HelloResource , внедрив HelloService и добавив новый метод:

@Inject
HelloService helloService;

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/polite/{name}")
public String greeting(@PathParam("name") String name) {
return helloService.politeHello(name);
}

Далее, давайте проверим нашу новую конечную точку:

$ curl localhost:8080/hello/polite/ForEach
Hello Mr/Mrs ForEach

Мы внесем еще одно изменение, чтобы продемонстрировать, что то же самое можно применить к файлам свойств. Отредактируем файл application.properties и добавим еще один ключ:

greeting=Good morning

После этого мы изменим HelloService , чтобы использовать наше новое свойство:

@ConfigProperty(name = "greeting")
private String greeting;

public String politeHello(String name){
return greeting + " " + name;
}

Если мы выполним ту же команду curl , мы должны увидеть:

Good morning ForEach

Мы можем легко упаковать приложение, запустив:

./mvnw package

Это создаст 2 файла jar внутри целевого каталога:

  • quarkus-project-1.0-SNAPSHOT-runner.jar — исполняемый файл jar с зависимостями, скопированными в target/lib
  • quarkus-project-1.0-SNAPSHOT.jar — содержит классы и файлы ресурсов

Теперь мы можем запустить упакованное приложение:

java -jar target/quarkus-project-1.0-SNAPSHOT-runner.jar

5. Родное изображение

Далее мы создадим собственный образ нашего приложения. Нативное изображение уменьшит время запуска и время до первого ответа. Другими словами, он содержит все необходимое для запуска, включая минимальную JVM, необходимую для запуска приложения .

Для начала нам нужно установить GraalVM и настроить переменную среды GRAALVM_HOME.

Теперь мы остановим приложение (Ctrl + C), если оно еще не остановлено, и выполним команду:

./mvnw package -Pnative

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

Мы можем запустить ./mvnw verify -Pnative , чтобы убедиться, что наш собственный артефакт был правильно сконструирован:

./2ed9f1516fbc82fca22d412a6b891c18.png

Во- вторых, мы создадим образ контейнера, используя наш собственный исполняемый файл . Для этого на нашей машине должна быть запущена среда выполнения контейнера (например, Docker ). Давайте откроем окно терминала и выполним:

./mvnw package -Pnative -Dnative-image.docker-build=true

Это создаст 64-битный исполняемый файл Linux, поэтому, если мы используем другую ОС, он может больше не работать. Это нормально на данный момент.

Генерация проекта создала для нас Dockerfile.native :

FROM registry.fedoraproject.org/fedora-minimal
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

Если мы изучим файл, у нас будет намек на то, что будет дальше. Сначала мы создадим образ докера :

docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-project .

Теперь мы можем запустить контейнер, используя:

docker run -i --rm -p 8080:8080 quarkus/quarkus-project

./fe23eb9e43410b0e56410d3e7eed33b3.png

Контейнер стартовал за невероятно короткое время — 0,009 с. Это одна из сильных сторон Quarkus.

Наконец, мы должны протестировать наш модифицированный REST, чтобы проверить наше приложение:

$ curl localhost:8080/hello/polite/ForEach
Good morning ForEach

6. Развертывание в OpenShift

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

oc new-build --binary --name=quarkus-project -l app=quarkus-project
oc patch bc/quarkus-project -p '{"spec":{"strategy":{"dockerStrategy":{"dockerfilePath":"src/main/docker/Dockerfile.native"}}}}'
oc start-build quarkus-project --from-dir=. --follow
oc new-app --image-stream=quarkus-project:latest
oc expose service quarkus-project

Теперь мы можем получить URL-адрес приложения, запустив:

oc get route

Наконец, мы получим доступ к той же конечной точке (обратите внимание, что URL-адрес может отличаться в зависимости от нашего IP-адреса):

$ curl http://quarkus-project-myproject.192.168.64.2.nip.io/hello/polite/ForEach
Good morning ForEach

7. Заключение

В этой статье мы продемонстрировали, что Quarkus — отличное дополнение, которое может более эффективно перенести Java в облако. Например, теперь можно представить Java на AWS Lambda. Кроме того, Quarkus основан на таких стандартах, как JPA и JAX/RS. Поэтому нам не нужно узнавать ничего нового.

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

Как всегда, код для этой статьи доступен на GitHub . Удачного кодирования!