Come Quarkus unisce MicroProfile e Spring

Ciao a tutti, e benvenuti al terzo post della serie su Quarkus!

Come Quarkus unisce MicroProfile e Spring

Nello sviluppo di microservizi Java, si considera spesso che Eclipse MicroProfile e Spring Boot sia un insieme di API distinte e indipendenti l'una dall'altra. Di norma, gli sviluppatori tendono a utilizzare le API con cui sono già familiari, poiché imparare nuovi framework e componenti runtime richiede molto tempo. Oggi cercheremo di semplificare l'apprendimento di alcune popolari API MicroProfile per gli sviluppatori Spring e mostreremo come utilizzare contemporaneamente le API di Spring e nuove funzionalità utili. Quarkus.

Se approfondiamo, inizieremo esaminando il campo di applicazione e i dettagli di come Quarkus supporta le interfacce API di Spring, per mostrare agli sviluppatori Spring come applicare le API MicroProfile nel loro lavoro quotidiano. Poi parleremo delle API MicroProfile che saranno utili agli sviluppatori Spring nella creazione di microservizi.

Perché Quarkus? Innanzitutto, si tratta di coding dal vivo (live coding), cioè il riavvio automatico di qualsiasi modifica nelle API MicroProfile, nelle API di Spring e nelle altre API Java, che avviene con un solo comando: mvn quarkus:dev. In secondo luogo, nel nostro esempio si esamina il nostro esempio Il servizio Person (si compila da API di Spring, MicroProfile e JPA in un file binario utilizzando l'immagine nativa di GraalVM) si avvia in soli 0,055 secondi e richiede circa 90 MB di memoria RAM (RSS) all'endpoint dell'applicazione RESTful. Inoltre, la sua compilazione avviene con un solo comando: mvn package -Pnative.

Non approfondiremo i dettagli di MicroProfile, ma cercheremo di aiutare gli sviluppatori Spring a comprendere come sia possibile utilizzare le API di Spring con le API di MicroProfile in Quarkus.

Contenitori e Kubernetes

Per non appesantire questo articolo, considereremo solo aspetti di alto livello del supporto Kubernetes, poiché è importante comprendere. Quarkus si presenta come uno stack Java per Kubernetes, concepito per minimizzare il consumo di memoria e il tempo di avvio delle applicazioni e dei servizi Java, aumentando così la densità di distribuzione sull'host e riducendo i costi complessivi.

Quarkus supporta anche la generazione automatica di risorse Kubernetes e offre del manuale per il deployment su piattaforme Kubernetes e Red Hat OpenShift. Inoltre, Quarkus genera automaticamente i file Dockerfile.jvm (packaging JVM) e Dockerfile.native (packaging binario nativo), necessari per creare contenitori.

Infine, considerando Kubernetes come l'ambiente di distribuzione target, Quarkus non utilizza framework Java nei casi in cui una funzionalità analoga è implementata a livello della piattaforma Kubernetes stessa. Nella Tabella 1 è presentata una mappa di corrispondenza delle funzionalità tra Kubernetes e i principali framework Java utilizzati dagli sviluppatori Spring.

Tabella 1. Mappa di corrispondenza delle funzionalità tra framework Java e Kubernetes.

Funzionalità
Spring Boot tradizionale
Kubernetes

Service discovery
Eureka
DNS

Configurazione
Spring Cloud Config
Config Maps / Secrets

Bilanciamento del carico
Ribbon (lato client)
Service, Replication Controller (lato server)

Compilazione e avvio del codice dall'esempio

In questo articolo ci riferiamo a un esempio di progetto, dove si utilizzano insieme le API Spring e MicroProfile e persino quella stessa classe Java. Il codice di questo esempio può essere compilato e avviato dalla riga di comando, ulteriore aiuto è disponibile nel file README.md.

API della Spring Framework

Dependency Injection

Quarkus supporta un'intera serie di API di Contexts and Dependency Injection (CDI) e API di Spring Dependency Injection (Spring DI). Se stai lavorando con MicroProfile, Java EE e Jakarta EE, sei già ben familiare con CDI. D'altra parte, gli sviluppatori Spring possono utilizzare l'estensione Quarkus per l'API Spring DI per garantire la compatibilità con Spring DI. Esempi dell'uso delle API Spring DI supportate sono riportati nella Tabella 2.

In progetto dal nostro esempio utilizza sia CDI che Spring Dependency Injection. Ulteriori informazioni e esempi a riguardo possono essere trovati nella guida Quarkus intitolata Spring DI Guide.

Tabella 2. Esempi di utilizzo delle interfacce API Spring DI supportate.

Funzionalità supportate di Spring DI
Esempi

Constructor Injection

public PersonSpringController(
   PersonSpringRepository personRepository,  // iniettato      
   PersonSpringMPService personService) {    // iniettato
      this.personRepository = personRepository;
      this.personService = personService;
}

Field Injection
Autowired
Valore

@Autowired
@RestClient
SalutationRestClient salutationRestClient;

@Value("${fallbackSalutation}")
String fallbackSalutation;

Bean
@Configuration

@Configuration
public class AppConfiguration {
   @Bean(name = "capitalizeFunction")
   public StringFunction capitalizer() {
      return String::toUpperCase;
   }
}

Component

@Component("noopFunction")
public class NoOpSingleStringFunction implements StringFunction {
   @Override
   public String apply(String s) {
      return s;
   }
}

Service

@Service
public class MessageProducer {
   @Value("${greeting.message}")
   String message;

   public String getPrefix() {
      return message;
   }
}

Framework web

Agli utenti di MicroProfile piacerà sapere che Quarkus supporta JAX-RS, MicroProfile Rest Client, JSON-P e JSON-B come modello principale per lo sviluppo web. Gli sviluppatori Spring saranno contenti del supporto recentemente introdotto da Quarkus per Spring Web API, in particolare per le interfacce dedicate a REST. Analogamente a Spring DI, l'obiettivo principale del supporto a Spring Web API è consentire agli sviluppatori Spring di utilizzare le interfacce API di Spring Web insieme a quelle di MicroProfile. Esempi di utilizzo delle Spring Web API supportate sono forniti nella tabella 3, mentre ulteriori informazioni e esempi su questo tema possono essere trovati nella guida di Quarkus intitolata Guida a Spring Web.

Tabella 3. Esempi di utilizzo delle interfacce API di Spring Web supportate.

Funzionalità supportate di Spring Web
Esempi

@RestController
@RequestMapping

@RestController
@RequestMapping("/person")
public class PersonSpringController {
   ...
   ...
   ...
}

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@RequestParam
@RequestHeader
@MatrixVariable
@PathVariable
@CookieValue
@RequestBody
@ResponseStatus
@ExceptionHandler
@RestControllerAdvice (parziale)

@GetMapping(path = "/greet/{id}",
   produces = "text/plain")
   public String greetPerson(
   @PathVariable(name = "id") long id) {
   ...
   ...
   ...
}

Spring Data JPA

Anche agli utenti di MicroProfile piacerà sapere che Quarkus supporta JPA utilizzando Hibernate ORM. Buone notizie anche per gli sviluppatori Spring: Quarkus supporta le annotazioni e i tipi standard di Spring Data JPA. Gli esempi di utilizzo delle API supportate da Spring Data JPA sono riportati nella tabella 4.
In progetto dal nostro esempio sono utilizzate le API di Spring Data JPA, e ulteriori informazioni sono disponibili nella guida Quarkus intitolata Guida a Spring Data JPA.

Tabella 4. Esempi di utilizzo delle API supportate da Spring Data JPA.

Funzionalità supportate di Spring Data JPA
Esempi

CrudRepository

public interface PersonRepository
         extends JpaRepository,
                 PersonFragment {
   ...
}

Repository
JpaRepository
PagingAndSortingRepository

public class PersonRepository extends 

    Repository {

    Person save(Person entity);

    Optional findById(Person entity);
}

Frammenti di Repository

public interface PersonRepository
         extends JpaRepository,
                 PersonFragment {
   ...
}

Metodi di query derivati

public interface PersonRepository extends CrudRepository {

    List findByName(String name);
    
    Person findByNameBySsn(String ssn);
    
    Optional 
       findByNameBySsnIgnoreCase(String ssn);

    Boolean existsBookByYearOfBirthBetween(
            Integer start, Integer end);
}

Query definite dall'utente

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 MicroProfile

Tolleranza ai guasti (Fault tolerance)

Le costruzioni di Fault Tolerance sono fondamentali per prevenire i fallimenti a cascata e per creare architetture di microservizi affidabili. Gli sviluppatori Spring utilizzano da molti anni i circuit-breaker per garantire la resilienza. Hystrix. Tuttavia, Hystrix non è stato aggiornato da tempo, mentre il Fault Tolerance di MicroProfile è attivamente sviluppato e ha già diversi anni di utilizzo in produzione. Pertanto, per migliorare l'affidabilità dei servizi in Quarkus, si raccomanda di utilizzare le API di MicroProfile Fault Tolerance, i cui esempi di utilizzo sono riportati nella tabella 5. Maggiori informazioni possono essere trovate nella guida a Quarkus. Guida alla Fault Tolerance.

Tabella 5. Esempi di utilizzo delle API supportate di MicroProfile Fault Tolerance.

Funzionalità di MicroProfile Fault Tolerance
Descrizione
Esempi

@Asynchronous

Esecuzione della logica in un thread separato

@Asynchronous
@Retry
public Future getSalutation() {
   ...
   return future;
}

@Bulkhead

Limitazione del numero di richieste simultanee

@Bulkhead(5)
public void fiveConcurrent() {
   makeRemoteCall(); //...
}

@CircuitBreaker

Gestione intelligente dei guasti e recupero dai guasti

@CircuitBreaker(delay=500 // millisecondi
   failureRatio = .75,
   requestVolumeThreshold = 20,
   successThreshold = 5)
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
   makeRemoteCall(); //...
}

@Fallback

Chiamata di logica alternativa in caso di errore

@Timeout(500) // millisecondi
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
   makeRemoteCall(); //...
}

public String fallback() {
   return "hello";
}

Riprova

Riprova in caso di errore della richiesta

@Retry(maxRetries=3)
public String getSalutation() {
   makeRemoteCall(); //...
}

Timeout

Tempo di attesa controllato in caso di errore

@Timeout(value = 500) // millisecondi
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
   makeRemoteCall(); //...
}

Controllo dei servizi (Service Health)

Le piattaforme Kubernetes monitorano la salute dei container tramite servizi speciali. Affinché la piattaforma sottostante possa monitorare i servizi, gli sviluppatori di Spring utilizzano spesso HealthIndicator personalizzati e Spring Boot Actuator. In Quarkus, questo può essere realizzato utilizzando MicroProfile Health, che per impostazione predefinita esegue controlli di funzionalità (liveness check), ma può anche essere configurato per eseguire controlli di funzionalità (liveness) e prontezza (readiness) simultaneamente. Esempi dell'uso delle API supportate da MicroProfile Health sono forniti nella tabella 6, ulteriori informazioni sono disponibili nella guida di Quarkus. Guida alla Salute.

Tabella 6. Esempi dell'uso delle API supportate da MicroProfile Health.

Funzionalità di MicroProfile Health
Descrizione
Esempi

@Liveness

La piattaforma riavvia le applicazioni containerizzate non funzionanti
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 piattaforma non invierà traffico all'applicazione containerizzata in caso di non prontezza.
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();  
}

Metriche

Le applicazioni forniscono metriche sia per scopi operativi (per monitorare le prestazioni SLA) sia per scopi non operativi (indicatori di prestazione aziendale). Gli sviluppatori Spring forniscono metriche tramite Spring Boot Actuator e Micrometer. D'altra parte, Quarkus utilizza MicroProfile Metrics per fornire metriche di base (JVM e sistema operativo), metriche fornitore (Quarkus) e metriche applicative. MicroProfile Metrics richiede che l'implementazione supporti formati di output JSON e OpenMetrics (Prometheus). Esempi di utilizzo dell'API MicroProfile Metrics sono riportati nella tabella 7.

In progetto dal nostro esempio Le MicroProfile Metrics sono utilizzate per fornire metriche applicative. Maggiori informazioni sono disponibili nella guida di Quarkus. Guida alle Metriche.

Tabella 7. Esempi di utilizzo delle API MicroProfile Metrics.

Funzioni MicroProfile Metrics
Descrizione
Esempi

@Counted

Indica un contatore che calcola il numero di chiamate all'oggetto annotato

@Counted(name = "fallbackCounter", 
  displayName = "Contatore Fallback", 
  description = "Contatore Fallback")
public String salutationFallback() {
   return fallbackSalutation;
}

@ConcurrentGauge

Indica un gauge che calcola il numero di chiamate parallele all'oggetto annotato

@ConcurrentGauge(
  name = "fallbackConcurrentGauge", 
  displayName="Concurrent Fallback", 
  description="Concurrent Fallback")
public String salutationFallback() {
   return fallbackSalutation;
}

@Gauge

Indica un gauge che misura il valore dell'oggetto annotato

@Metered(name = "FallbackGauge",
   displayName="Gauge Fallback",
   description="Frequenza Fallback")
public String salutationFallback() {
   return fallbackSalutation;
}

@Metered

Indica un meter che tiene traccia della frequenza di chiamata all'oggetto annotato

@Metered(name = "MeteredFallback",
   displayName="Metered Fallback",
   description="Frequenza Fallback")
public String salutationFallback() {
   return fallbackSalutation;
}

Metric

Annotazione che contiene informazioni sui metadati, ricevute durante una richiesta di inserimento o produzione di metriche

@Metric
@Metered(name = "MeteredFallback",
   displayName="Metered Fallback",
   description="Frequenza Fallback")
public String salutationFallback() {
   return fallbackSalutation;
}

Temporizzato

Indica un timer che monitora la durata dell'oggetto annotato

@Timed(name = "TimedFallback",
   displayName="Timed Fallback",
   description="Fallback delay")
public String salutationFallback() {
   return fallbackSalutation;
}

EndPoint delle metriche (Metrics Endpoints)

Metriche delle applicazioni localhost:8080/metrics/application
Metriche di base localhost:8080/metrics/base
Metriche del fornitore localhost:8080/metrics/vendor
Tutte le metriche localhost:8080/metrics

Client REST MicroProfile

I microservizi forniscono spesso endpoint RESTful, per i quali sono necessari i client API corrispondenti. Per utilizzare gli endpoint RESTful, gli sviluppatori Spring di solito utilizzano RestTemplate. Quarkus invece offre interfacce API MicroProfile Rest Client per affrontare questo problema, con esempi di utilizzo riportati nella Tabella 8.

In progetto dal nostro esempio l'uso degli endpoint RESTful è gestito tramite MicroProfile Rest Client. Ulteriori informazioni e esempi su questo argomento possono essere trovati nella guida di Quarkus Guida al Client REST.

Tabella 8. Esempi di utilizzo delle interfacce API MicroProfile Rest Client.

Funzionalità del MicroProfile Rest Client
Descrizione
Esempi

@RegisterRestClient

Registra l'interfaccia Java tipizzata come client REST

@RegisterRestClient
@Path("/")
public interface MyRestClient {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getSalutation();
}

@RestClient

Segnala l'implementazione di un'istanza di interfaccia tipizzata REST-client

@Autowired // oppure @Inject
@RestClient
MyRestClient restClient;

Invocazione

Chiama il punto finale REST

System.out.println(
   restClient.getSalutation());

mp-rest/url

Definisce il punto finale REST

application.properties:
org.example.MyRestClient/mp-rest/url=
   http://localhost:8081/myendpoint

Risultati

In questo blog, che sarà particolarmente utile per gli sviluppatori di Spring, esamineremo brevemente come utilizzare le interfacce API di Spring insieme alle interfacce API di MicroProfile in Quarkus per sviluppare microservizi Java e poi compilarli in codice binario nativo, risparmiando centinaia di megabyte di memoria e avviandosi in pochi millisecondi.

Come avrete già capito, ulteriori informazioni sul supporto delle interfacce API di Spring e MicroProfile, così come molte altre informazioni utili, possono essere trovate nelle guide di Quarkus.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster