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

Når man udvikler Java-mikrotjenester, betragtes det ofte, at og – 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 og vise, hvordan man samtidig kan aktivere Spring API og nye nyttige funktioner. .
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å 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 , 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å af Kubernetes-ressourcer og tilbyder 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 , 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 og API-grænseflader for Spring Dependency Injection (Spring DI). Hvis du arbejder med MicroProfile, , 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 anvender både CDI og Spring Dependency Injection. Yderligere oplysninger og eksempler om dette kan findes i Quarkus-guiden, der hedder .
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
@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;
}
}
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 .
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 bruger API-interfaces fra Spring Data JPA, og yderligere information er tilgængelig i Quarkus-guiden med titlen .
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. . 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. .
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";
}
Gentag ved forespørgselsfejl
@Retry(maxRetries=3)
public String getSalutation() {
makeRemoteCall(); //...
}
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. .
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 MicroProfile Metrics bruges til at levere applikationsmetrics. Yderligere oplysninger findes i Quarkus-håndbogen. .
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;
}
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;
}
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 :8080/metrics/application
Basismetrikker :8080/metrics/base
Leverandørmetrikker :8080/metrics/vendor
Alle metrikker :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 Brug af RESTful slutpunkter udføres med MicroProfile Rest Client. Yderligere oplysninger og eksempler på dette kan findes i Quarkus-håndbogen. .
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 .
Kilde: habr.com
