Comment Quarkus intègre MicroProfile et Spring

Bonjour à tous, et voici le troisième post de notre série sur Quarkus !

Comment Quarkus intègre MicroProfile et Spring

Lors du développement de microservices Java, il est souvent considéré que Eclipse MicroProfile et Spring Boot – ce sont des API distinctes et indépendantes les unes des autres. Par défaut, les programmeurs utilisent généralement les API auxquelles ils sont déjà habitués, car apprendre de nouveaux frameworks et composants runtime demande beaucoup de temps. Aujourd'hui, nous allons essayer de simplifier l'apprentissage de certains des API populaires MicroProfile pour les développeurs Spring et montrer comment utiliser à la fois les API Spring et de nouvelles fonctionnalités utiles Quarkus.

Pour entrer dans les détails, nous allons d'abord examiner le domaine d'application et les détails de la façon dont Quarkus prend en charge les interfaces API Spring, afin de montrer aux développeurs Spring comment ils peuvent appliquer les API MicroProfile dans leur travail quotidien. Ensuite, nous parlerons des API MicroProfile qui seront utiles aux développeurs Spring lors de la création de microservices.

Pourquoi Quarkus ? Tout d'abord, il s'agit de la programmation en direct (live coding), c'est-à-dire le rechargement automatique de tout changement dans les API MicroProfile, les API Spring et d'autres API Java, qui s'effectue par une simple commande : mvn quarkus:dev. Deuxièmement, l'exemple traité dans notre exemple le service Person (il est compilé à partir des interfaces API Spring, MicroProfile et JPA en un fichier binaire à l'aide de l'image native GraalVM) se lance en seulement 0,055 seconde et occupe environ 90 Mo de mémoire vive (RSS) sur le point d'application RESTful. De plus, sa compilation s'effectue par une simple commande : mvn package -Pnative.

Nous n'allons pas entrer dans les détails de MicroProfile, mais nous allons essayer d'aider les développeurs Spring à comprendre comment utiliser les interfaces API Spring avec les interfaces API MicroProfile dans Quarkus.

Conteneurs et Kubernetes

Pour ne pas alourdir cet article, nous allons examiner ici seulement les aspects de haut niveau du support Kubernetes, car il est important de comprendre cela. Quarkus se positionne comme une stack Java pour Kubernetes, visant à minimiser la consommation de mémoire et le temps de démarrage des applications et services Java, augmentant ainsi leur densité d'hébergement et réduisant les coûts globaux.

Quarkus prend également en charge la génération automatique des ressources Kubernetes et propose du manuel des solutions de déploiement sur les plateformes Kubernetes et Red Hat OpenShift. De plus, Quarkus génère automatiquement des fichiers Dockerfile.jvm (emballage JVM) et Dockerfile.native (emballage binaire natif), nécessaires à la création de conteneurs.

Enfin, en utilisant Kubernetes comme environnement de déploiement cible, Quarkus n’utilise pas de frameworks Java lorsque des fonctionnalités similaires sont mises en œuvre au niveau de la plateforme Kubernetes elle-même. La table 1 présente une carte de correspondance fonctionnelle entre Kubernetes et les frameworks Java typiques utilisés par les développeurs Spring.

Tableau 1. Carte de correspondance entre les frameworks Java et Kubernetes.

Fonctionnalités
Spring Boot traditionnel
Kubernetes

Découverte de services
Eureka
DNS

Configuration
Spring Cloud Config
Cartes de configuration / Secrets

Équilibrage de charge
Ribbon (côté client)
Service, Contrôleur de réplique (côté serveur)

Compilation et exécution du code de l’exemple

Dans cet article, nous faisons référence à un exemple de projet, où les API Spring et MicroProfile sont utilisées ensemble, ainsi que cette classe Java. Le code de cet exemple peut être compilé et exécuté à partir de la ligne de commande ; pour plus de détails, voir le fichier README.md.

APIs du Framework Spring

Dependency Injection

Quarkus prend en charge toute une gamme de API de Contextes et d'Injection de Dépendances (CDI) et d’APIs d’Injection de Dépendances Spring (Spring DI). Si vous travaillez avec MicroProfile, Java EE et Jakarta EE, vous êtes déjà bien familiarisé avec CDI. D'autre part, les développeurs Spring peuvent utiliser l’extension Quarkus pour l’API Spring DI afin d’assurer la compatibilité avec Spring DI. Des exemples d'utilisation des APIs Spring DI prises en charge sont présentés dans le tableau 2.

Dans dans notre exemple de projet tant CDI que l’Injection de Dépendances Spring. Pour des informations supplémentaires et des exemples sur ce sujet, vous pouvez consulter le guide Quarkus intitulé Guide Spring DI.

Tableau 2. Exemples d’utilisation des APIs Spring DI prises en charge.

Fonctionnalités prises en charge de Spring DI
Exemples

Injection par constructeur

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

Injection par champ
Autowired
Valeur

@Autowired
@RestClient
SalutationRestClient salutationRestClient;

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

Bean
@Configuration

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

Composant

@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

Les utilisateurs de MicroProfile apprécieront que Quarkus prenne en charge JAX-RS, MicroProfile Rest Client, JSON-P et JSON-B comme modèle principal de programmation web. Les développeurs Spring seront ravis de la prise en charge récemment ajoutée de Spring Web API dans Quarkus, notamment des interfaces responsables du REST. À l'instar de Spring DI, l'objectif principal du support de Spring Web API est de permettre aux développeurs Spring d'utiliser les API Spring Web en conjonction avec les API MicroProfile. Des exemples d'utilisation des API Spring Web prises en charge sont présentés dans le tableau 3, et des informations supplémentaires et des exemples sur ce sujet peuvent être trouvés dans le guide Quarkus intitulé Guide de Spring Web.

Tableau 3. Exemples d'utilisation des interfaces API Spring Web prises en charge.

Fonctionnalités prises en charge de Spring Web
Exemples

@RestController
@RequestMapping

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

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

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

Spring Data JPA

Les utilisateurs de MicroProfile apprécieront également que Quarkus prenne en charge JPA avec Hibernate ORM. Il y a également de bonnes nouvelles pour les développeurs Spring : Quarkus prend en charge les annotations et types standards de Spring Data JPA. Des exemples d'utilisation des API Spring Data JPA prises en charge sont présentés dans le tableau 4.
Dans dans notre exemple de projet des interfaces API Spring Data JPA sont utilisés, et des informations supplémentaires sont disponibles dans le guide Quarkus intitulé Guide de Spring Data JPA.

Tableau 4. Exemples d'utilisation des interfaces API Spring Data JPA prises en charge.

Fonctionnalités prises en charge de Spring Data JPA
Exemples

CrudRepository

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

Repository
JpaRepository
PagingAndSortingRepository

public class PersonRepository extends 

    Repository {

    Person save(Person entity);

    Optional findById(Person entity);
}

Fragments de Repository

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

Méthodes de requête dérivées

public interface PersonRepository extends CrudRepository {

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

    Boolean existsBookByYearOfBirthBetween(
            Integer start, Integer end);
}

Requêtes définies par l'utilisateur

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);
}

Interfaces API MicroProfile

Tolérance aux pannes

Les constructions de tolérance aux pannes sont très importantes pour prévenir les défaillances en cascade et créer des architectures de microservices robustes. Les développeurs de Spring utilisent depuis de nombreuses années des disjoncteurs pour la tolérance aux pannes. Hystrix. Cependant, Hystrix n'a pas été mis à jour depuis longtemps, tandis que la tolérance aux pannes de MicroProfile est actuellement en développement actif et a déjà plusieurs années d'utilisation en production. Par conséquent, pour améliorer la fiabilité des services dans Quarkus, il est recommandé d'utiliser les interfaces API de MicroProfile Fault Tolerance, dont des exemples d'utilisation sont fournis dans le tableau 5. Des informations supplémentaires peuvent être trouvées dans le guide Quarkus. Guide de tolérance aux pannes.

Tableau 5. Exemples d'utilisation des interfaces API MicroProfile Fault Tolerance prises en charge.

Fonctions de MicroProfile Fault Tolerance
Description
Exemples

@Asynchronous

Exécution de la logique dans un thread séparé

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

@Bulkhead

Limitation du nombre de requêtes simultanées

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

@CircuitBreaker

Gestion intelligente des échecs et récupération après une panne

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

@Fallback

Appel de la logique alternative en cas d'échec

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

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

Retry

Réessayer en cas d'échec de la requête

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

Timeout

Temps d'attente contrôlé en cas d'échec

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

Vérification des services (Service Health)

Les plateformes Kubernetes surveillent l'intégrité des conteneurs à l'aide de services spéciaux. Pour que la plateforme sous-jacente puisse surveiller les services, les développeurs de Spring utilisent généralement des HealthIndicators configurables et Spring Boot Actuator. Dans Quarkus, cela peut être réalisé avec MicroProfile Health, qui effectue par défaut un contrôle de l'état de vie (liveness check), mais peut également être configuré pour effectuer simultanément une vérification de l'état de vie et de la préparation (readiness). Des exemples d'utilisation des API MicroProfile Health prises en charge sont fournis dans le tableau 6, et des informations supplémentaires sont disponibles dans le guide Quarkus. Guide de santé.

Tableau 6. Exemples d'utilisation des interfaces API MicroProfile Health prises en charge.

Fonctions de MicroProfile Health
Description
Exemples

@Liveness

La plateforme redémarre les applications conteneurisées défaillantes
Point de terminaison :
hôte: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 plateforme ne dirigera pas le trafic vers les applications conteneurisées si celles-ci ne sont pas prêtes
Point de terminaison :
hôte: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étriques

Les applications fournissent des métriques soit à des fins opérationnelles (pour le contrôle des indicateurs de performance SLA), soit à des fins non opérationnelles (indicateurs de performance SLA business). Les développeurs Spring fournissent des métriques via Spring Boot Actuator et Micrometer. D'autre part, Quarkus utilise MicroProfile Metrics pour fournir des métriques de base (JVM et système d'exploitation), des métriques fournisseur (Quarkus) et des métriques d'application. MicroProfile Metrics exige que l'implémentation prenne en charge les formats de sortie JSON et OpenMetrics (Prometheus). Des exemples d'utilisation de l'API MicroProfile Metrics sont donnés dans le tableau 7.

Dans dans notre exemple de projet MicroProfile Metrics sont utilisés pour fournir des métriques d'application. Des informations supplémentaires peuvent être trouvées dans le guide Quarkus Guide des métriques.

Tableau 7. Exemples d'utilisation des interfaces API MicroProfile Metrics.

Fonctions des MicroProfile Metrics
Description
Exemples

@Counted

Désigne un compteur qui compte le nombre d'appels à l'objet annoté

@Counted(name = "fallbackCounter", 
  displayName = "Compteur de secours", 
  description = "Compteur de secours")
public String salutationFallback() {
   return fallbackSalutation;
}

@ConcurrentGauge

Désigne un capteur qui compte le nombre d'appels parallèles à l'objet annoté

@ConcurrentGuage(
  name = "fallbackConcurrentGauge", 
  displayName="Concurrent de secours", 
  description="Concurrent de secours")
public String salutationFallback() {
   return fallbackSalutation;
}

@Gauge

Désigne un capteur mesurant la valeur de l'objet annoté

@Metered(name = "FallbackGauge",
   displayName="Indicateur de secours",
   description="Fréquence de secours")
public String salutationFallback() {
   return fallbackSalutation;
}

@Metered

Désigne un compteur qui suit la fréquence d'appel de l'objet annoté

@Metered(name = "MeteredFallback",
   displayName="Fallback mesuré",
   description="Fréquence de secours")
public String salutationFallback() {
   return fallbackSalutation;
}

Métrique

Annotation contenant des informations sur les métadonnées lors de la réception d'une demande pour introduire ou produire une métrique

@Metric
@Metered(name = "MeteredFallback",
   displayName="Fallback mesuré",
   description="Fréquence de secours")
public String salutationFallback() {
   return fallbackSalutation;
}

Minutage

Désigne un chronomètre qui suit la durée de l'objet annoté

@Timed(name = "TimedFallback",
   displayName="Timed Fallback",
   description="Délai de secours")
public String salutationFallback() {
   return fallbackSalutation;
}

Points de terminaison des métriques (Metrics Endpoints)

Métriques des applications localhost:8080/metrics/application
Métriques de base localhost:8080/metrics/base
Métriques du vendeur localhost:8080/metrics/vendor
Toutes les métriques localhost:8080/metrics

Client REST MicroProfile

Les microservices offrent souvent des points de terminaison RESTful, pour lesquels des API clients appropriées sont nécessaires. Pour utiliser ces points de terminaison RESTful, les développeurs Spring utilisent généralement RestTemplate. Quarkus, quant à lui, propose des interfaces API MicroProfile Rest Client pour cela, dont des exemples d'utilisation sont fournis dans le tableau 8.

Dans dans notre exemple de projet L'utilisation des points de terminaison RESTful se fait à l'aide de MicroProfile Rest Client. Plus d'informations et des exemples à ce sujet peuvent être trouvés dans le guide Quarkus. Guide du Client REST.

Tableau 8. Exemples d'utilisation des interfaces API MicroProfile Rest Client.

Fonctionnalités du Client REST MicroProfile
Description
Exemples

@RegisterRestClient

Enregistre une interface Java typée en tant que client REST

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

@RestClient

Indique l'injection d'une instance d'interface typée de client REST

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

Invocation

Appelle le point de terminaison REST

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

mp-rest/url

Définit le point de terminaison REST

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

Résultats

Dans ce blog, principalement utile pour les développeurs Spring, nous avons brièvement examiné comment utiliser les interfaces API Spring avec les API MicroProfile pour développer des microservices Java, et ensuite les compiler en code binaire natif, économisant des centaines de mégaoctets de mémoire vive et démarrant en quelques millisecondes.

Comme vous l'avez déjà compris, des informations supplémentaires sur la prise en charge des interfaces API Spring et MicroProfile, ainsi qu'une multitude d'autres informations utiles peuvent être trouvées dans les guides Quarkus.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster