Hvordan Quarkus kombinerer MicroProfile og Spring

Hej alle sammen, og velkommen til det tredje indlæg i serien om Quarkus!

Hvordan Quarkus kombinerer MicroProfile og Spring

Når man udvikler Java-mikrotjenester, betragtes det ofte, at Eclipse MicroProfile og Spring Boot – er separate og uafhængige API'er. Som standard bruger programmører ofte de API'er, de allerede er vant til, da det kræver meget tid at lære nye rammer og runtime-komponenter. I dag vil vi forsøge at forenkle indlæringen af nogle populære MicroProfile API'er til Spring-udviklere og vise, hvordan man samtidig kan aktivere Spring API og nye nyttige funktioner. Quarkus.

For at være lidt mere specifik vil vi først se på anvendelsesområdet og detaljerne i, hvordan Quarkus understøtter Spring API'er for at vise Spring-udviklere, hvordan de kan anvende MicroProfile API'er i deres daglige arbejde. Derefter vil vi tale om MicroProfile API'er, der vil være nyttige for Spring-udviklere ved oprettelse af mikrotjenester.

Hvorfor netop Quarkus? For det første er det live coding, hvilket betyder automatisk genindlæsning af alle ændringer i MicroProfile API, Spring API og andre Java API'er, som udføres med en enkelt kommando: mvn quarkus:dev. For det andet ser vi på vores eksempel tjenesten Person (den kompileres fra API-grænsefladerne Spring, MicroProfile og JPA til en binær fil ved hjælp af den native GraalVM- image) starter på kun 0.055 sekunder og bruger omkring 90 MB i RAM (RSS) på RESTful-applikationens endpoint. Og selve kompileringen udføres med en enkelt kommando: mvn package -Pnative.

Vi vil ikke dykke ned i detaljerne omkring MicroProfile, men blot forsøge at hjælpe Spring-udviklere med at forstå, hvordan man kan bruge Spring API'er sammen med MicroProfile API'er i Quarkus.

Containere og Kubernetes

For ikke at overbelaste denne artikel, vil vi her kun overveje de højniveaus aspekter af støtten Kubernetes, da dette er vigtigt at forstå. Quarkus præsenteres som Java-stakken til Kubernetes, den har til formål at minimere hukommelsesforbruget og opstartstiden for Java-applikationer og tjenester, hvilket i sidste ende øger deres tæthed på værten og reducerer de samlede omkostninger.

Quarkus understøtter også autogenerering af Kubernetes-ressourcer og tilbyder manualen for implementering på Kubernetes- og Red Hat OpenShift-platforme. Desuden genererer Quarkus automatisk Dockerfile.jvm (JVM-pakning) og Dockerfile.native (native binary pakning), som er nødvendige for at oprette containere.

Og endelig, med Kubernetes som målmiljøet, anvender Quarkus ikke Java-rammer i de tilfælde, hvor tilsvarende funktionalitet er implementeret på niveauet for selve Kubernetes-platformen. Tabel 1 viser kortet med funktionel overensstemmelse mellem Kubernetes og de typiske Java-rammer, der anvendes af Spring-udviklere.

Tabel 1. Kort over funktionel overensstemmelse mellem Java-rammer og Kubernetes.

Funktionalitet
Traditionel Spring Boot
Kubernetes

Serviceopdagelse
Eureka
DNS

Konfiguration
Spring Cloud Config
Config Maps / Secrets

Lastbalancering
Ribbon (på klientsiden)
Service, Replication Controller (på serversiden)

Kompilering og kørsel af koden fra eksemplet

I denne artikel refererer vi til eksemplet på projektet, hvor API-grænsefladerne fra Spring og MicroProfile bruges sammen, og selv den samme Java-klasse. Koden fra dette eksempel kan kompileres og køres fra kommandolinjen, se nærmere i README.md-filen.

API-grænsefladerne fra Spring Framework

Dependency Injection

Quarkus understøtter en række API-grænseflader for Contexts and Dependency Injection (CDI) og API-grænseflader for Spring Dependency Injection (Spring DI). Hvis du arbejder med MicroProfile, Java EE og Jakarta EE, så er du allerede godt bekendt med CDI. På den anden side kan Spring-udviklere bruge Quarkus Extension for Spring DI API for at sikre kompatibilitet med Spring DI. Eksempler på brug af de understøttede Spring DI API'er findes i tabel 2.

I projektet fra vores eksempel anvender både CDI og Spring Dependency Injection. Yderligere oplysninger og eksempler om dette kan findes i Quarkus-guiden, der hedder Spring DI Guide.

Tabel 2. Eksempler på brug af de understøttede API-grænseflader for Spring DI.

Understøttede funktioner i Spring DI
Eksempler

Constructor Injection

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

Field Injection
Autowired
Værdi

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

Web-ramme

MicroProfile-brugere vil sætte pris på, at Quarkus understøtter JAX-RS, MicroProfile Rest Client, JSON-P og JSON-B som den grundlæggende model for webprogrammering. Spring-udviklere vil også værdsætte den nyligt tilføjede støtte til Spring Web API i Quarkus, især de interfaces der beskæftiger sig med REST. På samme måde som med Spring DI er hovedmålet med understøttelsen af Spring Web API, at Spring-udviklere kan bruge Spring Web API sammen med MicroProfile API-interfaces. Eksempler på brug af de understøttede Spring Web API findes i tabel 3, og yderligere information og eksempler kan findes i Quarkus-guiden, der hedder Spring Web Guide.

Tabel 3. Eksempler på brug af understøttede Spring Web API-interfaces.

Understøttede funktioner i Spring Web
Eksempler

@RestController
@RequestMapping

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

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

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

Spring Data JPA

MicroProfile-brugere vil også sætte pris på, at Quarkus understøtter JPA med Hibernate ORM. Der er også gode nyheder for Spring-udviklere: Quarkus understøtter de almindeligt anerkendte annotationer og typer inden for Spring Data JPA. Eksempler på brug af de understøttede Spring Data JPA API findes i tabel 4.
I projektet fra vores eksempel bruger API-interfaces fra Spring Data JPA, og yderligere information er tilgængelig i Quarkus-guiden med titlen Spring Data JPA Guide.

Tabel 4. Eksempler på brug af understøttede Spring Data JPA API-interfaces.

Understøttede funktioner i Spring Data JPA
Eksempler

CrudRepository

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

Repository
JpaRepository
PagingAndSortingRepository

public class PersonRepository extends 

    Repository {

    Person save(Person entity);

    Optional findById(Person entity);
}

Repository Fragments

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

Arv af forespørgselsmetoder

public interface PersonRepository extends CrudRepository {

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

    Boolean existsBookByYearOfBirthBetween(
            Integer start, Integer end);
}

Brugerdefinerede forespørgsler

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-interfaces fra MicroProfile

Fejltolerance

Fejltolerante konstruktioner er meget vigtige for at forhindre kaskadefejl og skabe pålidelige mikroservicearkitekturer. Spring-udviklere har i mange år brugt circuit-breakers til fejltolerance. Hystrix. Dog har Hystrix ikke været opdateret i lang tid, mens MicroProfile's fejltolerance nu aktivt udvikles og har flere års produktionsbrug bag sig. Derfor anbefales det at anvende MicroProfile Fault Tolerance API'er i Quarkus for at øge pålideligheden af tjenester. Eksempler på anvendelse er vist i tabel 5. Yderligere oplysninger kan findes i Quarkus-håndbogen. Fault Tolerance Guide.

Tabel 5. Eksempler på anvendelse af understøttede MicroProfile Fault Tolerance API'er.

Funktioner i MicroProfile Fault Tolerance
Description
Eksempler

@Asynchronous

Udførelse af logik i en separat tråd

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

@Bulkhead

Begrænsning af antallet af samtidige anmodninger

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

@CircuitBreaker

Intelligent fejlhåndtering og genopretning fra fejl

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

@Fallback

Kald alternativ logik ved fejl

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

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

Retry

Gentag ved forespørgselsfejl

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

Timeout

Tidskontrol ved fejl

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

Kontrol af tjenester (Service Health)

Kubernetes-platforme overvåger sundheden af containere ved hjælp af specielle tjenester. For at den underliggende platform kan overvåge tjenester, bruger Spring-udviklere typisk tilpassede HealthIndicator og Spring Boot Actuator. I Quarkus kan dette gøres med MicroProfile Health, som som standard udfører livstjek (liveness check), men kan også konfigureres til samtidig at tjekke liv (liveness) og klarhed (readiness). Eksempler på anvendelse af understøttede MicroProfile Health API'er vises i tabel 6, og yderligere information er præsenteret i Quarkus-håndbogen. Health Guide.

Tabel 6. Eksempler på anvendelse af understøttede MicroProfile Health API'er.

Funktioner i MicroProfile Health
Description
Eksempler

@Liveness

Platformen genstarter defekte containere applikationer.
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

Platformen vil ikke sende trafik til containeriserede applikationer, hvis de ikke er klar.
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ålinger

Applikationer giver metrics enten til operationelle formål (for at overvåge SLA-præstationsindikatorer) eller ikke-operationelle formål (forretnings-SLA-metrics). Spring-udviklere leverer metrics via Spring Boot Actuator og Micrometer. På den anden side bruger Quarkus MicroProfile Metrics til at levere grundlæggende metrics (JVM og operativsystem), leverandør-metrics (Quarkus) og applikations-metrics. MicroProfile Metrics kræver, at implementeringen understøtter outputformaterne JSON og OpenMetrics (Prometheus). Eksempler på brug af MicroProfile Metrics API er angivet i Tabel 7.

I projektet fra vores eksempel MicroProfile Metrics bruges til at levere applikationsmetrics. Yderligere oplysninger findes i Quarkus-håndbogen. Metrics Guide.

Tabel 7. Eksempler på brug af MicroProfile Metrics API'er.

Funktioner i MicroProfile Metrics
Description
Eksempler

@Counted

Angiver en counter-variabel, der tæller antallet af kald til den annoterede objekt.

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

@ConcurrentGauge

Angiver en gauge-måler, der tæller antallet af parallelle kald til den annoterede objekt.

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

@Gauge

Angiver en gauge-måler, der måler værdien af den annoterede objekt.

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

@Metered

Angiver en meter-måler, der sporer hyppigheden af kald til den annoterede objekt.

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

Metric

Annotation, der indeholder metadata-information ved modtagelse af anmodning om at indsætte eller generere metric.

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

Timed

Angiver en timer, der sporer varigheden af den annoterede objekt.

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

Metrics Endpoints

Applikationsmetrikker localhost:8080/metrics/application
Basismetrikker localhost:8080/metrics/base
Leverandørmetrikker localhost:8080/metrics/vendor
Alle metrikker localhost:8080/metrics

Rest-client MicroProfile

Mikrotjenester tilbyder ofte RESTful slutpunkter, som kræver de rette klient-API'er for at fungere. For at bruge RESTful slutpunkter anvender Spring-udviklere typisk RestTemplate. Quarkus tilbyder dog MicroProfile Rest Client API'er til dette formål, eksempler på brug kan findes i tabel 8.

I projektet fra vores eksempel Brug af RESTful slutpunkter udføres med MicroProfile Rest Client. Yderligere oplysninger og eksempler på dette kan findes i Quarkus-håndbogen. Rest Client Guide.

Tabel 8. Eksempler på brug af MicroProfile Rest Client API'er.

Funktioner i MicroProfile Rest Client
Description
Eksempler

@RegisterRestClient

Registrerer en typet Java-interface som en REST-klient

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

@RestClient

Markerer injektionen af en instans af det typede REST-klientinterface

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

Invocation

Kalder REST slutpunktet

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

mp-rest/url

Angiver REST slutpunktet

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

Resumé

I denne blog, som især er nyttig for Spring-udviklere, har vi kort gennemgået, hvordan man i Quarkus bruger Spring API'er sammen med MicroProfile API'er til at udvikle Java mikrotjenester og derefter kompilere dem til nativen binærkode, der sparer hundredvis af megabyte RAM og starter på få millisekunder.

Som du allerede ved, kan yderligere oplysninger om understøttelse af Spring og MicroProfile API'er samt en masse anden nyttig information findes i Quarkus-håndbøgerne.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster