¡Hola a todos! Y aquí está la tercera publicación de la serie sobre Quarkus.

Al desarrollar microservicios en Java, a menudo se considera que y son API separadas e independientes entre sí. Por defecto, los programadores tienden a usar las API con las que ya están familiarizados, ya que aprender nuevos frameworks y componentes runtime requiere mucho tiempo. Hoy intentaremos facilitar el aprendizaje de algunas APIs populares y mostraremos cómo utilizar simultáneamente las API de Spring y nuevas funcionalidades útiles. .
Si nos adentramos un poco más, primero exploraremos el ámbito de aplicación y los detalles de cómo Quarkus soporta las interfaces API de Spring, para mostrar a los desarrolladores de Spring cómo pueden aplicar las APIs de MicroProfile en su trabajo diario. Luego hablaremos sobre las APIs de MicroProfile que serán útiles para los desarrolladores de Spring al crear microservicios.
¿Por qué Quarkus? En primer lugar, permite la codificación en vivo (live coding), es decir, la recarga automática de cualquier cambio en las APIs de MicroProfile, las APIs de Spring y otras APIs de Java, que se realiza con un solo comando: mvn quarkus:dev. En segundo lugar, el servicio que discutimos en el servicio Person (que se compila desde las interfaces de API de Spring, MicroProfile y JPA en un archivo binario utilizando la imagen nativa de GraalVM) se inicia en solo 0.055 segundos y ocupa alrededor de 90 MB de RAM (RSS) en el punto final de una aplicación RESTful. Además, su compilación se lleva a cabo con un solo comando: mvn package -Pnative.
No profundizaremos en los detalles de MicroProfile, sino que intentaremos ayudar a los desarrolladores de Spring a comprender cómo se pueden utilizar las interfaces de API de Spring junto con las interfaces de API de MicroProfile en Quarkus.
Contenedores y Kubernetes
Para no sobrecargar este artículo, aquí examinaremos solo los aspectos de alto nivel del soporte , ya que es importante entender. Quarkus se posiciona como un stack de Java para Kubernetes, diseñado para minimizar el consumo de memoria y el tiempo de arranque de las aplicaciones y servicios Java, y, como resultado, aumentar la densidad de su despliegue en el host y reducir los costos generales.
Quarkus también de recursos de Kubernetes y ofrece para el despliegue en plataformas Kubernetes y Red Hat OpenShift. Además, Quarkus genera automáticamente los archivos Dockerfile.jvm (empaquetado JVM) y Dockerfile.native (empaquetado binario nativo) necesarios para crear contenedores.
Y finalmente, al orientar Kubernetes como el entorno objetivo de despliegue, Quarkus no utiliza marcos de Java en los casos en que la funcionalidad equivalente se implementa a nivel de la propia plataforma Kubernetes. En la tabla 1 se presenta un mapa de correspondencia funcional entre Kubernetes y los marcos de Java típicos utilizados por los desarrolladores de Spring.
Tabla 1. Mapa de correspondencia funcional entre marcos de Java y Kubernetes.
Funcionalidad
Spring Boot tradicional
Kubernetes
Descubrimiento de servicios
Eureka
DNS
Configuración
Spring Cloud Config
Config Maps / Secrets
Balanceo de carga
Ribbon (del lado del cliente)
Servicio, Replication Controller (del lado del servidor)
Compilación y ejecución del código del ejemplo
En este artículo nos referimos a , donde se utilizan conjuntamente las API de Spring y MicroProfile, y el mismo Java. El código de este ejemplo se puede compilar y ejecutar desde la línea de comandos; para más detalles, consulte el archivo README.md.
APIs del Spring Framework
Inyección de Dependencias
Quarkus admite toda una serie de y APIs de Inyección de Dependencias de Spring (Spring DI). Si trabaja con MicroProfile, , ya estará familiarizado con CDI. Por otro lado, los desarrolladores de Spring pueden usar la Extensión Quarkus para la API de Spring DI para asegurar la compatibilidad con Spring DI. Se presentan ejemplos de uso de las APIs de Spring DI compatibles en la tabla 2.
En se utiliza tanto CDI como Inyección de Dependencias de Spring. Se pueden encontrar más detalles y ejemplos sobre este tema en la guía de Quarkus titulada .
Tabla 2. Ejemplos de uso de las APIs de Spring DI compatibles.
Funciones compatibles de Spring DI
Ejemplos
Inyección por Constructor
public PersonSpringController(
PersonSpringRepository personRepository, // inyectado
PersonSpringMPService personService) { // inyectado
this.personRepository = personRepository;
this.personService = personService;
}
Inyección por Campo
@Autowired
@RestClient
SalutationRestClient salutationRestClient;
@Value("${fallbackSalutation}")
String fallbackSalutation;
@Configuration
@Configuration
public class AppConfiguration {
@Bean(name = "capitalizeFunction")
public StringFunction capitalizer() {
return String::toUpperCase;
}
}
@Component("noopFunction")
public class NoOpSingleStringFunction implements StringFunction {
@Override
public String apply(String s) {
return s;
}
}
@Service
public class MessageProducer {
@Value("${greeting.message}")
String message;
public String getPrefix() {
return message;
}
}
Marco web
A los usuarios de MicroProfile les gustará que Quarkus soporte JAX-RS, MicroProfile Rest Client, JSON-P y JSON-B como su modelo principal de programación web. Los desarrolladores de Spring estarán complacidos con la reciente adición del soporte para la Spring Web API en Quarkus, especialmente para las interfaces que manejan REST. Al igual que con la inyección de dependencias de Spring, el objetivo principal del soporte para la Spring Web API es que los desarrolladores de Spring puedan usar las interfaces de la Spring Web junto con las interfaces de MicroProfile. Los ejemplos de uso de las API de Spring Web soportadas se encuentran en la tabla 3, y más información y ejemplos sobre este tema pueden encontrarse en la guía de Quarkus llamada .
Tabla 3. Ejemplos de uso de las API de Spring Web soportadas.
Funciones soportadas de Spring Web
Ejemplos
@RestController
@RequestMapping
@RestController
@RequestMapping("/person")
public class PersonSpringController {
...
...
...
}
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@RequestParam
@RequestHeader
@MatrixVariable
@PathVariable
@CookieValue
@RequestBody
@ResponseStatus
@ExceptionHandler
@RestControllerAdvice (parcial)
@GetMapping(path = "/greet/{id}",
produces = "text/plain")
public String greetPerson(
@PathVariable(name = "id") long id) {
...
...
...
}
Spring Data JPA
A los usuarios de MicroProfile también les agradará que Quarkus soporte JPA utilizando Hibernate ORM. También hay buenas noticias para los desarrolladores de Spring: Quarkus soporta las anotaciones y tipos comunes de Spring Data JPA. Los ejemplos de uso de las API de Spring Data JPA soportadas se encuentran en la tabla 4.
En se utilizan las API de Spring Data JPA, y más información está disponible en la guía de Quarkus titulada .
Tabla 4. Ejemplos de uso de las API de Spring Data JPA soportadas.
Funciones soportadas de Spring Data JPA
Ejemplos
CrudRepository
public interface PersonRepository
extends JpaRepository,
PersonFragment {
...
}
Repositorio
JpaRepository
PagingAndSortingRepository
public class PersonRepository extends
Repository {
Person save(Person entity);
Optional findById(Person entity);
}
Fragmentos de Repositorio
public interface PersonRepository
extends JpaRepository,
PersonFragment {
...
}
Métodos de consulta derivados
public interface PersonRepository extends CrudRepository {
List findByName(String name);
Person findByNameBySsn(String ssn);
Optional
findByNameBySsnIgnoreCase(String ssn);
Boolean existsBookByYearOfBirthBetween(
Integer start, Integer end);
}
Consultas definidas por el usuario
public interface MovieRepository
extends CrudRepository {
Movie findFirstByOrderByDurationDesc();
@Query("select m from Movie m where m.rating = ?1")
Iterator findByRating(String rating);
@Query("from Movie where title = ?1")
Movie findByTitle(String title);
}
API de MicroProfile
Tolerancia a fallos
Las construcciones de tolerancia a fallos son muy importantes para prevenir fallos en cascada y crear arquitecturas de microservicios confiables. Los desarrolladores de Spring han estado utilizando durante años circuit-breakers para la tolerancia a fallos. . Sin embargo, Hystrix no se ha actualizado desde hace tiempo, mientras que la tolerancia a fallos de MicroProfile está actualmente en desarrollo activo y cuenta con varios años de uso en producción. Por lo tanto, para aumentar la fiabilidad de los servicios en Quarkus, se recomienda utilizar las interfaces de API de MicroProfile Fault Tolerance, cuyos ejemplos de uso se presentan en la tabla 5. Puede encontrar información adicional sobre esto en la guía de Quarkus. .
Tabla 5. Ejemplos de uso de las interfaces de API de MicroProfile Fault Tolerance soportadas.
Funciones de MicroProfile Fault Tolerance
Descripción
Ejemplos
@Asynchronous
Ejecución de lógica en un hilo separado
@Asynchronous
@Retry
public Future getSalutation() {
...
return future;
}
@Bulkhead
Límite en la cantidad de solicitudes simultáneas
@Bulkhead(5)
public void fiveConcurrent() {
makeRemoteCall(); //...
}
@CircuitBreaker
Manejo inteligente de fallos y recuperación de fallos
@CircuitBreaker(delay=500 // milisegundos
failureRatio = .75,
requestVolumeThreshold = 20,
successThreshold = 5)
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
@Fallback
Llamado a lógica alternativa en caso de fallo
@Timeout(500) // milisegundos
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
public String fallback() {
return "hello";
}
Reintento ante un fallo de solicitud
@Retry(maxRetries=3)
public String getSalutation() {
makeRemoteCall(); //...
}
Tiempo máximo de espera ante un fallo
@Timeout(value = 500) // milisegundos
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
Verificación de servicios (Service Health)
Las plataformas de Kubernetes monitorean la salud de los contenedores mediante servicios específicos. Para que la plataforma subyacente pueda monitorear los servicios, los desarrolladores de Spring suelen utilizar HealthIndicator personalizables y Spring Boot Actuator. En Quarkus, esto se puede lograr mediante MicroProfile Health, que por defecto realiza una verificación de operatividad (liveness check), aunque también se pueden configurar para verificar simultáneamente la operatividad y la preparación (readiness). Los ejemplos de uso de las API soportadas de MicroProfile Health se presentan en la tabla 6, y más información se proporciona en la guía de Quarkus. .
Tabla 6. Ejemplos de uso de las interfaces de API de MicroProfile Health soportadas.
Funciones de MicroProfile Health
Descripción
Ejemplos
@Liveness
La plataforma reinicia aplicaciones contenedorizadas defectuosas
Endpoint:
host:8080/health/live
@Liveness
public class MyHC implements HealthCheck {
public HealthCheckResponse call() {
...
return HealthCheckResponse
.named("myHCProbe")
.status(ready ? true:false)
.withData("mydata", data)
.build();
}
@Readiness
La plataforma no enviará tráfico a la aplicación containerizada si no está lista.
Endpoint:
host:8080/health/ready
@Readiness
public class MyHC implements HealthCheck {
public HealthCheckResponse call() {
...
return HealthCheckResponse
.named("myHCProbe")
.status(live ? true:false)
.withData("mydata", data)
.build();
}
Métricas
Las aplicaciones proporcionan métricas ya sea para fines operativos (para monitorear los indicadores de rendimiento de SLA) o no operativos (indicadores comerciales de SLA). Los desarrolladores de Spring proporcionan métricas utilizando Spring Boot Actuator y Micrometer. A su vez, Quarkus utiliza MicroProfile Metrics para proporcionar métricas básicas (JVM y sistema operativo), métricas de proveedores (Quarkus) y métricas de aplicaciones. MicroProfile Metrics requiere que la implementación soporte los formatos de salida JSON y OpenMetrics (Prometheus). Ejemplos de uso de la API de MicroProfile Metrics se presentan en la tabla 7.
En Las métricas de MicroProfile se utilizan para proporcionar métricas de aplicación. Más información se puede encontrar en la guía de Quarkus. .
Tabla 7. Ejemplos de uso de las API de MicroProfile Metrics.
Funciones de MicroProfile Metrics
Descripción
Ejemplos
@Counted
Indica un contador que cuenta la cantidad de llamadas al objeto anotado.
@Counted(name = "fallbackCounter",
displayName = "Fallback Counter",
description = "Fallback Counter")
public String salutationFallback() {
return fallbackSalutation;
}
@ConcurrentGauge
Indica un medidor que cuenta la cantidad de llamadas concurrentes al objeto anotado.
@ConcurrentGuage(
name = "fallbackConcurrentGauge",
displayName="Fallback Concurrent",
description="Fallback Concurrent")
public String salutationFallback() {
return fallbackSalutation;
}
@Gauge
Indica un medidor que mide el valor del objeto anotado.
@Metered(name = "FallbackGauge",
displayName="Fallback Gauge",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
@Metered
Indica un medidor que rastrea la frecuencia de llamadas al objeto anotado.
@Metered(name = "MeteredFallback",
displayName="Metered Fallback",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
Anotación que contiene información sobre los metadatos al recibir una solicitud para agregar o producir una métrica.
@Metric
@Metered(name = "MeteredFallback",
displayName="Metered Fallback",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
Indica un temporizador que rastrea la duración del objeto anotado.
@Timed(name = "TimedFallback",
displayName="Fallback de tiempo",
description="Retraso de fallback")
public String salutationFallback() {
return fallbackSalutation;
}
Puntos finales de métricas
Métricas de aplicaciones :8080/metrics/application
Métricas básicas :8080/metrics/base
Métricas del proveedor :8080/metrics/vendor
Todas las métricas :8080/metrics
Cliente REST de MicroProfile
Los microservicios suelen proporcionar puntos finales RESTful, para los cuales se requieren API de cliente adecuadas. Para utilizar estos puntos finales RESTful, los desarrolladores de Spring normalmente utilizan RestTemplate. Quarkus, por su parte, ofrece interfaces API de MicroProfile Rest Client, cuyos ejemplos de uso se muestran en la tabla 8.
En El uso de los puntos finales RESTful se realiza a través de MicroProfile Rest Client. Puede encontrar más información y ejemplos sobre este tema en la guía de Quarkus. .
Tabla 8. Ejemplos de uso de las interfaces API de MicroProfile Rest Client.
Funciones del cliente REST de MicroProfile
Descripción
Ejemplos
@RegisterRestClient
Registra una interfaz Java tipificada como cliente REST
@RegisterRestClient
@Path("/")
public interface MyRestClient {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getSalutation();
}
@RestClient
Marca la inyección de una instancia de la interfaz tipificada del cliente REST
@Autowired // o @Inject
@RestClient
MyRestClient restClient;
Invocación
Llama al punto final REST
System.out.println(
restClient.getSalutation());
mp-rest/url
Define el punto final REST
application.properties:
org.example.MyRestClient/mp-rest/url=
http://localhost:8081/myendpoint
Resultados
En este blog, que será especialmente útil para los desarrolladores de Spring, hemos explorado brevemente cómo utilizar las interfaces API de Spring junto con las interfaces de MicroProfile en Quarkus para desarrollar microservicios Java y luego compilarlos en un binario nativo que ahorra cientos de megabytes de memoria RAM y se inicia en cuestión de milisegundos.
Como ya habrás entendido, puede encontrar más información sobre el soporte para las API de Spring y MicroProfile, así como mucha otra información útil en .
Fuente: habr.com
