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 у нас будет структура, подобная той, что показана на изображении ниже:
Давайте рассмотрим содержимое класса HelloResource
:
@Path("/hello")
public class HelloResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
Пока все выглядит хорошо. На данный момент у нас есть простое приложение с одной конечной точкой RESTEasy JAX-RS. Давайте продолжим и протестируем его, открыв терминал и выполнив команду:
./mvnw compile quarkus:dev:
Наша конечная точка 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
, чтобы убедиться, что наш собственный артефакт был правильно сконструирован:
Во- вторых, мы создадим образ контейнера, используя наш собственный исполняемый файл . Для этого на нашей машине должна быть запущена среда выполнения контейнера (например, 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
Контейнер стартовал за невероятно короткое время — 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 . Удачного кодирования!