Wie Quarkus MicroProfile und Spring vereint

Hallo zusammen, und willkommen zum dritten Beitrag unserer Quarkus-Serie!

Wie Quarkus MicroProfile und Spring vereint

Bei der Entwicklung von Java-Microservices wird oft angenommen, dass Eclipse MicroProfile und Spring Boot separate und unabhängige APIs sind. Standardmäßig verwenden Programmierer in der Regel die APIs, mit denen sie bereits vertraut sind, da das Erlernen neuer Frameworks und Runtime-Komponenten viel Zeit benötigt. Heute wollen wir die Einarbeitung in einige beliebte MicroProfile-APIs für Spring-Entwickler vereinfachen und demonstrieren, wie man sowohl Spring APIs als auch die neuen, nützlichen Funktionen von Quarkus.

nutzen kann. Zunächst betrachten wir den Anwendungsbereich und die Details, wie Quarkus die APIs von Spring unterstützt, um Spring-Entwicklern zu zeigen, wie sie MicroProfile-APIs in ihrem Alltag einsetzen können. Anschließend werden wir die MicroProfile-APIs vorstellen, die für Spring-Entwickler beim Erstellen von Microservices nützlich sein werden.

Warum gerade Quarkus? Erstens ermöglicht es Live-Coding, also die automatische Neuladefunktion für alle Änderungen an MicroProfile-APIs, Spring-APIs und anderen Java-APIs, die mit nur einem Befehl ausgeführt werden: mvn quarkus:dev. Zweitens behandelt es unserem Beispiel der Service Person (er wird aus den APIs von Spring, MicroProfile und JPA in eine Binärdatei kompiliert, die mit einem nativen Bild von GraalVM erstellt wird) startet in nur 0,055 Sekunden und benötigt etwa 90 MB im Arbeitsspeicher (RSS) am Endpunkt der RESTful-Anwendung. Die gesamte Kompilierung erfolgt mit nur einem Befehl: mvn package -Pnative.

Wir werden nicht in die Details von MicroProfile eintauchen, sondern versuchen, Spring-Entwicklern zu helfen, zu verstehen, wie im Quarkus die APIs von Spring zusammen mit den APIs von MicroProfile verwendet werden können.

Container und Kubernetes

Um diesen Artikel nicht zu überladen, betrachten wir hier nur die hochgradigen Aspekte der Unterstützung Kubernetes, da es wichtig ist, dies zu verstehen. Quarkus wird als Java-Stack für Kubernetes positioniert, um den Speicherverbrauch und die Startzeit von Java-Anwendungen und -Diensten zu minimieren, wodurch die Dichte ihrer Bereitstellung auf dem Host erhöht und die Gesamtkosten gesenkt werden.

Quarkus unterstützt auch die automatische Generierung von Kubernetes-Ressourcen und bietet Leitfäden für das Deployment auf Kubernetes- und Red Hat OpenShift-Plattformen. Darüber hinaus generiert Quarkus automatisch die Dockerfile.jvm (JVM-Paketierung) und Dockerfile.native (native Binärverpackung) Dateien, die erforderlich sind, um Container zu erstellen.

Und schließlich, da Kubernetes als Zielumgebung für das Deployment verwendet wird, nutzt Quarkus keine Java-Frameworks, wenn eine ähnliche Funktionalität bereits auf der Ebene der Kubernetes-Plattform implementiert ist. In Tabelle 1 wird eine Map der funktionalen Übereinstimmung zwischen Kubernetes und den typischen Java-Frameworks vorgestellt, die von Spring-Entwicklern verwendet werden.

Tabelle 1. Map der funktionalen Übereinstimmung zwischen Java-Frameworks und Kubernetes.

Funktionalität
Traditionelles Spring Boot
Kubernetes

Service Entdeckung
Eureka
DNS

Konfiguration
Spring Cloud Config
Config Maps / Secrets

Lastenverteilung
Ribbon (clientseitig)
Service, Replication Controller (serverseitig)

Kompilierung und Ausführung des Beispielcodes

In diesem Artikel verweisen wir auf ein Beispielprojekt, in dem die APIs von Spring und MicroProfile gemeinsam genutzt werden, sowie die besagte Java-Klasse. Der Code aus diesem Beispiel kann aus der Kommandozeile kompiliert und ausgeführt werden, detaillierte Informationen finden Sie in der Datei README.md.

APIs des Spring Framework

Dependency Injection

Quarkus unterstützt eine ganze Reihe von APIs für Contexts and Dependency Injection (CDI) und die API-Schnittstellen von Spring Dependency Injection (Spring DI). Wenn Sie mit MicroProfile arbeiten, Java EE und Jakarta EE, dann sind Sie bereits gut mit CDI vertraut. Auf der anderen Seite können Spring-Entwickler die Quarkus-Erweiterung für die Spring DI API nutzen, um die Kompatibilität mit Spring DI sicherzustellen. Beispiele für die Verwendung der unterstützten Spring DI APIs finden Sie in Tabelle 2.

In des Projekts aus unserem Beispiel werden sowohl CDI als auch Spring Dependency Injection verwendet. Weitere Informationen und Beispiele zu diesem Thema finden Sie im Quarkus-Handbuch mit dem Titel Spring DI Anleitung.

Tabelle 2. Beispiele zur Verwendung unterstützter API-Schnittstellen von Spring DI.

Unterstützte Funktionen von Spring DI
Beispiele

Konstruktorinjektion

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

Feldinjektion
Autowired
Value

@Autowired
@RestClient
SalutationRestClient salutationRestClient;

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

Bean
@Configuration

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

Komponente

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

Web-Framework

MicroProfile-Nutzer werden erfreut sein, dass Quarkus JAX-RS, den MicroProfile Rest Client, JSON-P und JSON-B als Hauptmodell für Webprogrammierung unterstützt. Auch Spring-Entwickler werden von der neu hinzugefügten Unterstützung für das Spring Web API in Quarkus begeistert sein, insbesondere von den Schnittstellen, die für REST verantwortlich sind. Analog zur Spring DI zielt die Unterstützung des Spring Web API darauf ab, Spring-Entwicklern die Nutzung der Spring Web-APIs zusammen mit den MicroProfile-APIs zu ermöglichen. Beispiele für die Verwendung der unterstützten Spring Web APIs sind in Tabelle 3 aufgeführt, und weitere Informationen und Beispiele zu diesem Thema finden Sie im Quarkus-Handbuch mit dem Titel Spring Web Guide.

Tabelle 3. Beispiele für die Verwendung unterstützter Spring Web-Schnittstellen.

Unterstützte Funktionen von Spring Web
Beispiele

@RestController
@RequestMapping

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

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

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

Spring Data JPA

MicroProfile-Nutzer werden ebenfalls erfreut sein zu hören, dass Quarkus JPA mit Hibernate ORM unterstützt. Auch für Spring-Entwickler gibt es gute Nachrichten: Quarkus unterstützt gängige Annotations und Typen von Spring Data JPA. Beispiele für die Nutzung der unterstützten Spring Data JPA-APIs sind in Tabelle 4 aufgeführt.
In des Projekts aus unserem Beispiel verwendet die APIs von Spring Data JPA, und zusätzliche Informationen sind im Quarkus-Handbuch mit dem Titel Spring Data JPA Leitfaden.

Tabelle 4. Beispiele für die Nutzung der unterstützten APIs von Spring Data JPA.

Unterstützte Funktionen von Spring Data JPA
Beispiele

CrudRepository

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

Repository
JpaRepository
PagingAndSortingRepository

public class PersonRepository extends 

    Repository {

    Person save(Person entity);

    Optional findById(Person entity);
}

Repository-Fragmente

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

Abgeleitete Abfragemethoden

public interface PersonRepository extends CrudRepository {

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

    Boolean existsBookByYearOfBirthBetween(
            Integer start, Integer end);
}

Benutzerdefinierte Abfragen

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

MicroProfile-APIs

Fehlertoleranz (Fault tolerance)

Fehlerverzeihtheit ist entscheidend, um kaskadierende Ausfälle zu verhindern und zuverlässige Mikroservice-Architekturen zu schaffen. Spring-Entwickler nutzen seit Jahren Circuit Breaker für die Fehlerverzeihung. Hystrix. Hystrix wird jedoch seit langem nicht mehr aktualisiert, während die MicroProfile Fault Tolerance aktiv weiterentwickelt wird und bereits mehrere Jahre in Produktion genutzt wird. Daher wird empfohlen, für die Erhöhung der Zuverlässigkeit von Diensten in Quarkus die MicroProfile Fault Tolerance APIs zu verwenden, deren Anwendungsbeispiele in Tabelle 5 dargestellt sind. Weitere Informationen finden Sie im Quarkus-Handbuch. Fault Tolerance Guide.

Tabelle 5. Beispiele für die Verwendung der unterstützten MicroProfile Fault Tolerance APIs.

Funktionen der MicroProfile Fault Tolerance
Beschreibung
Beispiele

@Asynchronous

Ausführung der Logik in einem separaten Thread

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

@Bulkhead

Begrenzung der Anzahl gleichzeitiger Anfragen

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

@CircuitBreaker

Intelligente Fehlerbehandlung und Wiederherstellung nach Ausfällen

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

@Fallback

Alternative Logik im Fehlerfall aufrufen

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

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

Wiederholen

Wiederholversuch bei Anfragefehler

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

Zeitüberschreitung

Maximale Wartezeit im Fehlerfall

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

Dienstüberprüfung (Service Health)

Kubernetes-Plattformen überwachen die Gesundheit von Containern über spezielle Dienste. Normalerweise verwenden Spring-Entwickler anpassbare HealthIndicator und den Spring Boot Actuator, damit die zugrundeliegende Plattform die Dienste überwachen kann. In Quarkus kann dies mithilfe von MicroProfile Health erfolgen, das standardmäßig eine Lebensprüfungs (liveness check) durchführt, aber auch so konfiguriert werden kann, dass sowohl die Lebensprüfung als auch die Bereitschaftsprüfung gleichzeitig durchgeführt werden. Beispiele für die Nutzung der unterstützten MicroProfile Health API sind in Tabelle 6 aufgeführt, weitere Informationen finden Sie in der Quarkus-Dokumentation. Gesundheitsleitfaden.

Tabelle 6. Beispiele zur Verwendung von unterstützten MicroProfile Health APIs.

Funktionen von MicroProfile Health
Beschreibung
Beispiele

@Liveness

Die Plattform führt einen Neustart fehlerhafter containerisierter Anwendungen durch.
Endpunkt:
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

Die Plattform wird keinen Verkehr an containerisierte Anwendungen senden, wenn diese nicht bereit sind.
Endpunkt:
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();  
}

Metriken

Anwendungen stellen Metriken entweder für operationale Zwecke (zur Überwachung von SLA-Leistungsindikatoren) oder für nicht-operationale Zwecke (Geschäfts-SLA-Indikatoren) bereit. Spring-Entwickler stellen Metriken mit Hilfe von Spring Boot Actuator und Micrometer bereit. Quarkus hingegen verwendet MicroProfile Metrics, um grundlegende Metriken (JVM und Betriebssystem), vendor-spezifische Metriken (Quarkus) und Anwendungsmetriken bereitzustellen. MicroProfile Metrics verlangt, dass die Implementierung die Ausgabeformate JSON und OpenMetrics (Prometheus) unterstützt. Beispiele für die Verwendung der MicroProfile Metrics API finden Sie in Tabelle 7.

In des Projekts aus unserem Beispiel MicroProfile Metrics werden zur Bereitstellung von Anwendungsmetriken verwendet. Weitere Informationen finden Sie im Quarkus-Handbuch. Metrik-Leitfaden.

Tabelle 7. Beispiele für die Nutzung der MicroProfile Metrics APIs.

Funktionen der MicroProfile Metrics
Beschreibung
Beispiele

@Counted

Kennzeichnet einen Zähler, der die Anzahl der Aufrufe des annotierten Objekts zählt.

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

@ConcurrentGauge

Kennzeichnet einen Gaugesensor, der die Anzahl der parallelen Aufrufe des annotierten Objekts zählt.

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

@Gauge

Kennzeichnet einen Gaugesensor, der den Wert des annotierten Objekts misst.

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

@Metered

Kennzeichnet einen Meter, der die Aufrufhäufigkeit des annotierten Objekts verfolgt.

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

Metric

Annotation, die Informationen über Metadaten enthält, wenn eine Anfrage zur Einführung oder Herstellung einer Metrik eingeht.

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

Timed

Bezeichnet einen Timer, der die Dauer des annotierten Objekts verfolgt

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

Metrik-Endpunkte (Metrics Endpoints)

Anwendungsmetriken localhost:8080/metrics/application
Basismetriken localhost:8080/metrics/base
Vendor-Metriken localhost:8080/metrics/vendor
Alle Metriken localhost:8080/metrics

Rest-Client MicroProfile

Mikroservices bieten oft RESTful-Endpunkte an, für die entsprechende Client-APIs benötigt werden. Um mit RESTful-Endpunkten zu arbeiten, verwenden Spring-Entwickler normalerweise RestTemplate. Quarkus bietet jedoch für diese Aufgabe die MicroProfile Rest Client-API, deren Anwendungsbeispiele in Tabelle 8 angeführt sind.

In des Projekts aus unserem Beispiel Die Nutzung der RESTful-Endpunkte erfolgt mit dem MicroProfile Rest Client. Weitere Informationen und Beispiele dazu finden Sie im Quarkus-Handbuch. Rest Client Anleitung.

Tabelle 8. Beispiele für die Verwendung der MicroProfile Rest Client-APIs.

Funktionen des MicroProfile Rest Client
Beschreibung
Beispiele

@RegisterRestClient

Registriert einen typisierten Java-Interface als REST-Client

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

@RestClient

Kennzeichnet die Implementierung einer typisierten REST-Client-Schnittstelle

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

Aufruf

Ruft den REST-Endpunkt auf

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

mp-rest/url

Legt den REST-Endpunkt fest

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

Ergebnisse

In diesem Blog, der vor allem für Spring-Entwickler nützlich ist, haben wir kurz vorgestellt, wie man in Quarkus Spring-APIs zusammen mit MicroProfile-APIs verwendet, um Java-Mikroservices zu entwickeln und diese dann in nativen Binärcode zu kompilieren, der Hunderte von Megabyte RAM spart und in wenigen Millisekunden startet.

Wie Sie bereits verstanden haben, finden Sie weitere Informationen zur Unterstützung von Spring- und MicroProfile-APIs sowie viele andere nützliche Informationen in Quarkus-Handbüchern.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster