Guia do QuarkusIO

Guia do QuarkusIO

1. Introdução

Hoje em dia, é muito comum escrever um aplicativo e implantar na nuvem e não se preocupar com a infraestrutura. Sem servidor e FaaS se tornaram muito populares.

Nesse tipo de ambiente, onde as instâncias são criadas e destruídas com frequência, o tempo de inicialização e o tempo para a primeira solicitação são extremamente importantes, pois podem criar uma experiência do usuário completamente diferente.

Idiomas como JavaScript e Python estão sempre em destaque nesse tipo de cenário. Em outras palavras, Java com seus JARs gordos e longo tempo de inicialização nunca foi um dos principais candidatos.

Neste tutorial,we’ll present Quarkus and discuss if it’s an alternative for bringing Java more effectively to the cloud.

2. QuarkusIO

QuarkusIO, o Supersonic Subatomic Java,promises to deliver small artifacts, extremely fast boot time, and lower time-to-first-request. Quando combinado comGraalVM, o Quarkus compilará antes do tempo (AOT).

And, since Quarkus is built on top of standards, we don’t need to learn anything new. Conseqüentemente, podemos usar CDI e JAX-RS, entre outros. Além disso,Quarkus has a lot of extensions, incluindo aqueles que são compatíveis com Hibernate, Kafka, OpenShift, Kubernetes e Vert.x.

3. Nossa Primeira Aplicação

A maneira mais fácil de criar um novo projeto do Quarkus é abrir um terminal e digite:

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

Isso irá gerar o esqueleto do projeto, umHelloResource com um endpoint/hello exposto, configuração, projeto Maven e Dockerfiles.

Depois de importados para nosso IDE, teremos uma estrutura semelhante à mostrada na imagem abaixo:

image

Vamos examinar o conteúdo da aulaHelloResource:

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

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

Tudo parece bom até agora. Neste ponto, temos um aplicativo simples com um único terminal RESTEasy JAX-RS. Vamos testar isso abrindo um terminal e executando o comando:

./mvnw compile quarkus:dev:

image

Nosso terminal REST deve ser exposto em localhost: 8080 / hello. Vamos testar com o comandocurl:

$ curl localhost:8080/hello
hello

4. Recarga a quente

Quando executado no modo de desenvolvimento (./mvn compile quarkus:dev), o Quarkus fornece um recurso de recarregamento a quente. Em outras palavras,changes made to Java files or to configuration files will automatically be compiled once the browser is refreshed. O recurso mais impressionante aqui é que não precisamos salvar nossos arquivos. Isso pode ser bom ou ruim, dependendo da nossa preferência.

Agora vamos modificar nosso exemplo para demonstrar a capacidade de recarregamento a quente. Se o aplicativo estiver parado, podemos simplesmente reiniciá-lo no modo dev. Usaremos o mesmo exemplo de antes como nosso ponto de partida.

Primeiro, vamos criar uma classeHelloService:

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

Agora, vamos modificar a classeHelloResource, injetando oHelloServicee adicionando um novo método:

@Inject
HelloService helloService;

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

A seguir, vamos testar nosso novo endpoint:

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

Faremos mais uma alteração para demonstrar que o mesmo pode ser aplicado aos arquivos de propriedades. Vamos editar o arquivoapplication.properties e adicionar mais uma chave:

greeting=Good morning

Depois disso, vamos modificar oHelloService para usar nossa nova propriedade:

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

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

Se executarmos o mesmo comandocurl, devemos ver agora:

Good morning example

Podemos facilmente empacotar o aplicativo executando:

./mvnw package

Isso irá gerar 2 arquivos jar dentro do diretóriotarget:

  • quarkus-project-1.0-SNAPSHOT-runner.jar - um jar executável com as dependências copiadas paratarget/lib

  • quarkus-project-1.0-SNAPSHOT.jar - contém classes e arquivos de recursos

Agora podemos executar o aplicativo empacotado:

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

5. Imagem nativa

A seguir, produziremos uma imagem nativa de nosso aplicativo. Uma imagem nativa melhorará o tempo de inicialização e o tempo da primeira resposta. Em outras palavras, écontains everything it needs to run, including the minimal JVM necessary to run the application.

Para começar, precisamos terGraalVM instalado e a variável de ambiente GRAALVM_HOME configurada.

Vamos agora parar o aplicativo (Ctrl + C), se ainda não tiver sido interrompido, e executar o comando:

./mvnw package -Pnative

Isso pode levar alguns segundos para ser concluído. Como as imagens nativas tentam criar todo o código AOT para inicializar mais rápido, como resultado, teremos tempos de construção mais longos.

Podemos executar./mvnw verify -Pnative para verificar se nosso artefato nativo foi construído corretamente:

image

Em segundo lugar, vamoscreate a container image using our native executable. Para isso, precisamos ter um tempo de execução do contêiner (ou seja, Docker) em execução em nossa máquina. Vamos abrir uma janela de terminal e executar:

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

Isso criará um executável Linux de 64 bits, portanto, se estivermos usando um sistema operacional diferente, ele pode não ser mais executável. Tudo bem por enquanto.

A geração do projeto criou umDockerfile.native para nós:

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"]

Se examinarmos o arquivo, teremos uma dica do que vem a seguir. Primeiro, vamoscreate a docker image:

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

Agora, podemos executar o contêiner usando:

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

image O contêiner começou em um tempo incrivelmente baixo de 0,009 s. Esse é um dos pontos fortes do Quarkus.

Por fim, devemos testar nosso REST modificado para validar nosso aplicativo:

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

6. Implantando no OpenShift

Assim que terminarmos o teste local usando o Docker, implantaremos nosso contêiner emOpenShift. Supondo que tenhamos a imagem do Docker em nosso registro, podemos implantar o aplicativo seguindo as etapas abaixo:

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

Agora, podemos obter o URL do aplicativo executando:

oc get route

Por último, acessaremos o mesmo endpoint (observe que o URL pode ser diferente, dependendo do nosso endereço IP):

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

7. Conclusão

Neste artigo, demonstramos que o Quarkus é um ótimo complemento que pode levar o Java de maneira mais eficaz à nuvem. Por exemplo, agora é possível imaginar Java no AWS Lambda. Além disso, o Quarkus é baseado em padrões como JPA e JAX / RS. Portanto, não precisamos aprender nada novo.

Ultimamente, o Quarkus chamou muita atenção e muitos novos recursos são adicionados todos os dias. Existem vários projetos de início rápido para experimentarmos o Quarkus emQuarkus GitHub repository.

Como sempre, o código deste artigo está disponívelover on GitHub. Feliz codificação!