Como Quarkus combina a programación imperativa e reactiva

Este ano pensamos desenvolver seriamente temas de contedores, Java nativo na nube и Kubernetes. Unha continuación lóxica destes temas será xa unha historia sobre o framework Quarkus considerado sobre Habré. O artigo de hoxe trata menos sobre o deseño de "Java superrápido subatómico" e máis sobre a promesa que Quarkus trae a Enterprise.

Como Quarkus combina a programación imperativa e reactiva

Java e a JVM seguen sendo moi populares, pero cando se traballa con tecnoloxías sen servidor e microservizos nativos da nube, Java e outras linguaxes JVM úsanse cada vez menos porque ocupan demasiado espazo de memoria e son demasiado lentos para cargar, polo que os fai. pouco axeitado para o seu uso con recipientes de curta duración. Por sorte, esta situación agora comeza a cambiar grazas a Quarkus.

O Java subatómico superrápido alcanzou un novo nivel!

42 lanzamentos, 8 meses de traballo comunitario e 177 desenvolvedores incribles; o resultado de todo foi o lanzamento en novembro de 2019 Quarkus 1.0, unha versión que marca un fito importante no desenvolvemento do proxecto e que ofrece moitas funcións e capacidades interesantes (podes ler máis sobre elas en anuncio).

Hoxe mostrarémosche como Quarkus combina modelos de programación imperativo e reactivo nun único núcleo reactivo. Comezaremos cunha breve historia e despois entraremos en detalles sobre o que é o dualismo do núcleo reactivo de Quarkus e como Java-Os desenvolvedores poden aproveitar estes beneficios.

Microservizos, arquitecturas impulsadas por eventos и sen servidor-funcións: todo isto, como din, está en aumento na actualidade. Recentemente, a creación de arquitecturas centradas na nube fíxose moito máis fácil e accesible, pero seguen existindo problemas, especialmente para os desenvolvedores de Java. Por exemplo, no caso das funcións sen servidor e dos microservizos, hai unha necesidade urxente de reducir o tempo de inicio, reducir o consumo de memoria e aínda así facer máis cómodo e agradable o seu desenvolvemento. Java realizou varias melloras nos últimos anos, como a funcionalidade de ergonomía mellorada para contedores, etc. Non obstante, conseguir que Java funcione correctamente nun contedor segue sendo un reto. Entón, comezaremos por analizar algunhas das complexidades inherentes de Java, que son particularmente agudas cando se desenvolven aplicacións Java orientadas a contedores.

En primeiro lugar, vexamos a historia.

Como Quarkus combina a programación imperativa e reactiva

Regos e contedores

A partir da versión 8u131, Java comezou a admitir máis ou menos contedores debido ás melloras na funcionalidade ergonómica. En particular, a JVM agora sabe en cantos núcleos de procesador se está a executar e pode configurar grupos de fíos (normalmente grupos de bifurcación/unión) en consecuencia. Por suposto, isto é xenial, pero digamos que temos unha aplicación web tradicional que usa servlets HTTP e que se executa en Tomcat, Jetty, etc. Como resultado, esta aplicación dará a cada solicitude un fío separado e permitiralle bloquear este fío mentres espera as operacións de E/S, por exemplo, ao acceder á base de datos, ficheiros ou outros servizos. É dicir, o tamaño desta aplicación non depende do número de núcleos dispoñibles, senón do número de solicitudes simultáneas. Ademais, isto significa que as cotas ou os límites en Kubernetes sobre o número de núcleos non serán de moita axuda aquí e o asunto acabará en estrangulamento.

Esgotamento da memoria

Os fíos son memoria. E as limitacións de memoria dentro do contedor non son de ningún xeito unha panacea. Só ten que comezar a aumentar o número de aplicacións e fíos e, tarde ou cedo, atopará un aumento crítico na frecuencia de conmutación e, como resultado, unha degradación do rendemento. Ademais, se a súa aplicación usa marcos de microservizos tradicionais, ou se conecta a unha base de datos, ou usa almacenamento en caché ou usa memoria, obviamente precisa dunha ferramenta que lle permita mirar dentro da JVM e ver como xestiona a memoria sen matala. JVM en si (por exemplo, XX:+UseCGroupMemoryLimitForHeap). E aínda que, desde Java 9, a JVM aprendeu a aceptar cgroups e adaptarse en consecuencia, reservar e xestionar memoria segue sendo un asunto bastante complexo.

Cotas e límites

Java 11 introduciu soporte para as cotas de CPU (como PreferContainerQuotaForCPUCount). Kubernetes tamén ofrece soporte para límites e cotas. Si, todo isto ten sentido, pero se a aplicación volve superar a cota asignada, volvemos a ter o tamaño -como é o caso das aplicacións tradicionais de Java- determinado polo número de núcleos e coa asignación dun fío separado para cada un. petición, entón hai pouco sentido en todo isto.
Ademais, se usas cotas e límites ou as funcións de escalado horizontal da plataforma subxacente a Kubernetes, o problema tampouco se resolve por si só. Simplemente gastamos máis recursos en resolver o problema orixinal ou acabamos gastando de máis. E se se trata dun sistema de alta carga nunha nube pública pública, case seguro que acabamos usando máis recursos dos que realmente necesitamos.

E que facer con todo isto?

Para dicilo simplemente, use bibliotecas e marcos de E/S asíncronos e non bloqueantes como Netty, Vert.x ou Akka. Son moito máis axeitados para traballar en contedores debido á súa natureza reactiva. Grazas á E/S sen bloqueo, o mesmo fío pode procesar varias solicitudes simultáneas. Mentres unha solicitude está á espera dos resultados de E/S, o fío que a procesa é liberado e asumido por outra solicitude. E cando finalmente chegan os resultados de E/S, o procesamento da primeira solicitude continúa. Mediante o procesamento intercalado de solicitudes dentro do mesmo fío, pode reducir o número total de fíos e reducir o consumo de recursos para procesar as solicitudes.

Con E/S sen bloqueo, o número de núcleos convértese nun parámetro clave porque determina o número de fíos de E/S que se poden executar en paralelo. Cando se usa correctamente, isto permítelle distribuír eficazmente a carga entre núcleos e xestionar cargas de traballo máis altas con menos recursos.

Como, iso é todo?

Non, hai outra cousa. A programación reactiva axuda a facer un mellor uso dos recursos, pero tamén ten un prezo. En particular, o código terá que ser reescrito segundo os principios de non bloqueo e evitar o bloqueo de fíos de E/S. E este é un modelo de desenvolvemento e execución completamente diferente. E aínda que aquí hai moitas bibliotecas útiles, non deixa de ser un cambio radical na forma de pensar habitual.

En primeiro lugar, cómpre aprender a escribir código que se execute de forma asíncrona. Unha vez que comece a usar E/S sen bloqueo, cómpre especificar explícitamente o que debe ocorrer cando se recibe unha resposta a unha solicitude. Simplemente bloquear e esperar xa non funcionará. Pola contra, pode pasar as devolucións de chamada, utilizar a programación reactiva ou a continuación. Pero iso non é todo: para usar E/S sen bloqueo, necesitas servidores e clientes sen bloqueo, preferiblemente en todas partes. No caso de HTTP, todo é sinxelo, pero tamén hai bases de datos, sistemas de ficheiros e moito máis.

E aínda que a reactividade total de extremo a extremo maximiza a eficiencia, tal cambio pode ser difícil de soportar na práctica. Polo tanto, a capacidade de combinar código reactivo e imperativo convértese nun requisito previo para:

  1. Utilizar eficazmente os recursos nas áreas máis cargadas do sistema de software;
  2. Usa un código de estilo máis sinxelo nas partes restantes.

Presentación de Quarkus

En realidade, esta é a esencia de Quarkus: combinar modelos reactivos e imperativos nun único ambiente de execución.

Quarkus está baseado en Vert.x e Netty, cunha gama de cadros reactivos e extensións para axudar ao programador. Quarkus está deseñado para crear non só microservizos HTTP, senón tamén arquitecturas dirixidas a eventos. Pola súa natureza reactiva, funciona de forma moi eficaz con sistemas de mensaxería (Apache Kafka, AMQP, etc.).

O truco é como usar o mesmo motor reactivo para o código imperativo e reactivo.

Como Quarkus combina a programación imperativa e reactiva

Quarkus fai isto de xeito brillante. A elección entre imperativo e reactivo é obvia: use un núcleo reactivo para ambos. O que realmente axuda é un código rápido e sen bloqueo que xestiona case todo o que pasa polo fío do bucle de eventos, tamén coñecido como fío IO. Pero se tes aplicacións REST clásicas ou do lado do cliente, Quarkus ten preparado un modelo de programación imperativo. Por exemplo, o soporte HTTP en Quarkus baséase no uso dun motor reactivo e non bloqueador (Eclipse Vert.x e Netty). Todas as solicitudes HTTP recibidas pola túa aplicación pasan primeiro a través dun bucle de eventos (IO Thread) e despois envíanse á parte do código que xestiona as solicitudes. Segundo o destino, o código de xestión de solicitudes pódese chamar dentro dun fío separado (o chamado fío de traballo, usado no caso de servlets e Jax-RS) ou utilizar o fío de E/S de orixe (ruta reactiva).

Como Quarkus combina a programación imperativa e reactiva

Os conectores do sistema de mensaxería usan clientes sen bloqueo que se executan sobre o motor Vert.x. Polo tanto, pode enviar, recibir e procesar mensaxes de forma eficaz desde sistemas de middleware de mensaxería.

A web Quarkus.io Aquí tes algúns bos tutoriais para axudarche a comezar con Quarkus:

Tamén creamos titoriais prácticos en liña para ensinarche varios aspectos da programación reactiva só nun navegador, sen necesidade de IDE e sen necesidade de ordenador. Podes atopar estas leccións aquí.

Recursos útiles

10 videoleccións sobre Quarkus para familiarizarse co tema

Como din na web Quarkus.io, quarkus - é Kubernetespila Java orientada, adaptada para GraalVM e OpenJDK HotSpot e montada a partir das mellores bibliotecas e estándares de Java.

Para axudarche a comprender o tema, seleccionamos 10 videotutoriais que abranguen varios aspectos de Quarkus e exemplos do seu uso:

1. Presentación de Quarkus: o marco Java de próxima xeración para Kubernetes

Por Thomas Qvarnstrom e Jason Greene
O obxectivo do proxecto Quarkus é crear unha plataforma Java para Kubernetes e entornos sen servidor, e combinar modelos de programación reactivos e imperativos nun único ambiente de execución para que os desenvolvedores poidan variar de forma flexible o seu enfoque cando traballan cunha ampla gama de arquitecturas de aplicacións distribuídas. Obtén máis información na charla introdutoria a continuación.

2. Quarkus: Java subatómico superrápido

Por: Burr Sutter
Este vídeo titorial de DevNation Live mostra como usar Quarkus para optimizar aplicacións empresariais Java, API, microservizos e funcións sen servidor nun ambiente Kubernetes/OpenShift, facéndoos moito máis pequenos, rápidos e escalables.

3. Quarkus e GraalVM: acelerando Hibernate a súper velocidades e reducindoo a tamaños subatómicos

Autor: Sanne Grinovero
Na presentación aprenderás como nace Quarkus, como funciona e como che permite facer bibliotecas complexas, como Hibernate ORM, compatibles coas imaxes nativas de GraalVM.

4. Aprende a desenvolver aplicacións sen servidor

Autor: Martín Lutero
O seguinte vídeo mostra como crear unha aplicación Java sinxela usando Quarkus e implementala como unha aplicación sen servidor en Knative.

5. Quarkus: divírtete codificando

Autor: Edson Yanaga
Unha guía de vídeo para crear o teu primeiro proxecto Quarkus, que che permite entender por que Quarkus está a gañar o corazón dos desenvolvedores.

6. Java e contedores: cal será o seu futuro xuntos

Publicado por Mark Little
Esta presentación presenta a historia de Java e explica por que Quarkus é o futuro de Java.

7. Quarkus: Java subatómico superrápido

Autor: Dimitris Andreadis
Unha visión xeral das vantaxes de Quarkus que recibiron o recoñecemento dos desenvolvedores: sinxeleza, velocidades ultra altas, as mellores bibliotecas e estándares.

8. Quarkus e sistemas de foguetes subatómicos

Autor: Clement Escoffier
A través da integración con GraalVM, Quarkus ofrece unha experiencia de desenvolvemento ultrarrápida e un ambiente de execución subatómico. O autor fala do lado reactivo de Quarkus e de como usalo para crear aplicacións reactivas e de streaming.

9. Quarkus e desenvolvemento rápido de aplicacións en Eclipse MicroProfile

Autor: John Clingan
Ao combinar Eclipse MicroProfile e Quarkus, os desenvolvedores poden crear aplicacións MicroProfile en contenedores con todas as funcións que se lanzan en decenas de milisegundos. O vídeo entra en detalles sobre como codificar unha aplicación MicroProfile en contedores para a súa implantación na plataforma Kubernetes.

10. Java, versión "Turbo".

Autor: Marcus Biel
O autor mostra como usar Quarkus para crear contedores Java super-pequenos e súper rápidos que permiten auténticos avances, especialmente en ambientes sen servidor.



Fonte: www.habr.com

Engadir un comentario