Як Quarkus аб'ядноўвае MicroProfile і Spring

Усім прывітанне, і з вамі трэці пост з серыі пра Quarkus!

Як Quarkus аб'ядноўвае MicroProfile і Spring

Пры распрацоўцы Java-мікрасэрвісаў часта лічыцца, што Мікрапрафіль Eclipse и Вясновы бот – гэта асобныя і незалежныя сябар ад сябра API. Па змаўчанні, праграмісты, як правіла, выкарыстоўваюць тыя API, да якіх яны ўжо абвыклі, паколькі вывучэнне новых фреймворков і runtime-кампанентаў патрабуе шмат часу. Сёння мы паспрабуем спрасціць засваенне некаторых папулярных MicroProfile API для Spring-распрацоўшчыкаў і пакажам, як адначасова задзейнічаць Spring API і новыя карысныя магчымасці Кваркус.

Калі крыху падрабязней, то спачатку мы разгледзім вобласць ужывання і дэталі таго, як Quarkus падтрымлівае API-інтэрфейсы Spring, каб паказаць Spring-распрацоўнікам, як можна ўжываць MicroProfile API у сваёй паўсядзённай працы. Затым мы раскажам аб MicroProfile API, якія спатрэбяцца Spring-распрацоўшчыкам пры стварэнні мікрасэрвісаў.

Чаму менавіта Quarkus? Па-першае, гэтае кадаваньне ўжывую (live coding), гэта значыць аўтаматычная перазагрузка любых змен у MicroProfile API, Spring API і іншых Java API, якая выконваецца ўсяго адной камандай: mvn quarkus:dev. Па-другое, разгляданы ў нашым прыкладзе сэрвіс Person (ён кампілюецца з API-інтэрфейсаў Spring, MicroProfile і JPA у двайковы файл з выкарыстаннем натыўнай выявы GraalVM) запускаецца ўсяго за 0.055 секунды і займае каля 90 МБ у аператыўнай памяці (RSS) на канчатковай кропцы прыкладання RESTful. Прычым сама яго кампіляцыя выконваецца ўсяго адной камандай: mvn package-Pnative.

Мы не будзем паглыбляцца ў падрабязнасці MicroProfile, а толькі пастараемся дапамагчы Spring-распрацоўнікам зразумець, як у Quarkus можна выкарыстоўваць API-інтэрфейсы Spring разам з API-інтэрфейсамі MicroProfile.

Кантэйнеры і Kubernetes

Каб не перагружаць гэты артыкул, мы разгледзім тут толькі высокаўзроўневыя аспекты падтрымкі. Kubernetes, паколькі гэта важна разумець. Quarkus пазіцыянуецца як Java-стэк для Kubernetes, ён закліканы мінімізаваць выдатак памяці і час запуску Java-прыкладанняў і сэрвісаў, і, як следства, падвысіць шчыльнасць іх месцавання на хасце і зменшыць агульныя выдаткі.

Quarkus таксама падтрымлівае аўтагенерацыю рэсурсаў Kubernetes і прапануе кіраўніцтва па разгортванні на платформах Kubernetes і Red Hat OpenShift. Акрамя таго, Quarkus аўтаматычна генеруе файлы Dockerfile.jvm (JVM packaging) і Dockerfile.native (native binary packaging), неабходныя для стварэння кантэйнераў.

І нарэшце, арыентуючыся на Kubernetes як на мэтавае асяроддзе разгортвання, Quarkus не выкарыстоўвае Java-фрэймворкі ў тых выпадках, калі аналагічны функцыянал рэалізаваны на ўзроўні самай платформы Kubernetes. У табліцы 1 прыводзіцца карта функцыянальнай адпаведнасці Kubernetes і тыпавых Java-фрэймворкаў, якія выкарыстоўваюцца Spring-распрацоўшчыкамі.

Табліца 1. Карта функцыянальнага адпаведнасці Java-фрэймворкаў і Kubernetes.

функцыянал
Традыцыйны Spring Boot
Kubernetes

Service discovery
Эўрыка
DNS

канфігурацыя
Spring Cloud Config
Config Maps / Secrets

Балансаванне нагрузкі
Ribbon (на баку кліента)
Service, Replication Controller(на баку сервера)

Кампіляцыя і запуск кода з прыкладу

У гэтым артыкуле мы спасылаемся на прыклад праекта, дзе сумесна выкарыстоўваюцца API-інтэрфейсы Spring і MicroProfile і нават той самы Java-клас. Код з гэтага прыкладу можна скампіляваць і запусціць з каманднага радка, падрабязней гл. файл README.md.

API-інтэрфейсы Spring Framework

Ін'екцыя залежнасці

Quarkus падтрымлівае цэлы шэраг API-інтэрфейсаў Contexts and Dependency Injection (CDI) і API-інтэрфейсаў Spring Dependency Injection (Spring DI). Калі вы працуеце з MicroProfile, Java EE і Jakarta EE, то ўжо добра знаёмыя з CDI. З іншага боку, Spring-распрацоўнікі могуць выкарыстоўваць Quarkus Extension for Spring DI API для забеспячэння сумяшчальнасці з Spring DI. Прыклады выкарыстання падтрымоўваных Spring DI API прыводзяцца ў табліцы 2.

В праекце з нашага прыкладу выкарыстоўваецца як CDI, так і Spring Dependency Injection. Дадатковыя звесткі і прыклады на гэтую тэму можна знайсці ў кіраўніцтве Quarkus, якое называецца Spring DI Guide.

Табліца 2. Прыклады выкарыстання падтрымліваемых API-інтэрфейсаў Spring DI.

Падтрымліваюцца функцыі Spring DI
прыклады

Constructor Injection

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

Field Injection
Autowired
значэнне

@Autowired
@RestClient
SalutationRestClient salutationRestClient;

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

Фасолю
@ Канфігурацыя

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

Вэб-фрэймворк

Карыстачам MicroProfile спадабаецца, што Quarkus падтрымлівае JAX-RS, MicroProfile Rest Client, JSON-P і JSON-B у якасці асноўнай мадэлі вэб-праграмавання. Spring-распрацоўнікаў прыемна парадуе нядаўна якая з'явілася ў Quarkus падтрымка Spring Web API, у прыватнасці інтэрфейсаў, якія адказваюць за REST. Па аналогіі са Spring DI галоўная мэта падтрымкі Spring Web API складаецца ў тым, каб Spring-распрацоўнікі маглі выкарыстаць API-інтэрфейсы Spring Web разам з API-інтэрфейсамі MicroProfile. Прыклады выкарыстання падтрымоўваных Spring Web API прыводзяцца ў табліцы 3, а дадатковыя звесткі і прыклады на гэтую тэму можна знайсці ў кіраўніцтве Quarkus, якое завецца Spring Web Guide.

Табліца 3. Прыклады выкарыстання падтрымліваемых API-інтэрфейсаў Spring Web.

Падтрымліваюцца функцыі Spring Web
прыклады

@RestController
@RequestMapping

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

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

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

Spring DataJPA

Карыстачам MicroProfile таксама прыйдзецца даспадобы, што Quarkus падтрымлівае JPA з выкарыстаннем Hibernate ORM. Для Spring-распрацоўшчыкаў таксама ёсць добрая навіна: Quarkus падтрымлівае агульнапрынятыя анатацыі і тыпы Spring Data JPA. Прыклады выкарыстання падтрымоўваных Spring Data JPA API прыводзяцца ў табліцы 4.
В праекце з нашага прыкладу выкарыстоўваюцца API-інтэрфейсы Spring Data JPA, а дадатковая інфармацыя даступная ў кіраўніцтве Quarkus пад назовам Spring Data JPA Guide.

Табліца 4. Прыклады выкарыстання падтрымліваемых API-інтэрфейсаў Spring Data JPA.

Падтрымліваюцца функцыі Spring Data JPA
прыклады

CrudRepository

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

ёмішча
JpaRepository
PagingAndSortingRepository

public class PersonRepository extends 

    Repository {

    Person save(Person entity);

    Optional findById(Person entity);
}

Repository Fragments

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

Derived query methods

public interface PersonRepository extends CrudRepository {

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

    Boolean existsBookByYearOfBirthBetween(
            Integer start, Integer end);
}

User-defined queries

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

адмоваўстойлівасць (Fault tolerance)

Канструкцыі Fault tolerance вельмі важныя для прадухілення каскадных адмоў і стварэнні надзейных мікрасэрвісных архітэктур. Spring-распрацоўшчыкі ўжо шмат гадоў выкарыстоўваюць для адмоваўстойлівасці circuit-breaker'ы Гістрыкс. Аднак Hystrix даўно не абнаўляўся, а вось MicroProfile'еўскі Fault Tolerance зараз актыўна развіваецца і мае за плячыма ўжо некалькі гадоў прадакшн-выкарыстання. Таму для павышэння надзейнасці сэрвісаў у Quarkus рэкамендуецца прымяняць API-інтэрфейсы MicroProfile Fault Tolerance, прыклады выкарыстання якіх прыводзяцца ў табліцы 5. Дадатковыя звесткі пра гэта можна знайсці ў кіраўніцтве Quarkus Fault Tolerance Guide.

Табліца 5. Прыклады выкарыстання падтрымліваемых API-інтэрфейсаў MicroProfile Fault Tolerance.

Функцыі MicroProfile Fault Tolerance
Апісанне
прыклады

@Asynchronous

Выкананне логікі ў асобным патоку

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

@Bulkhead

Абмежаванне колькасці адначасовых запытаў

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

@CircuitBreaker

Разумная апрацоўка збояў і аднаўленне пасля збояў

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

@Fallback

Выклік альтэрнатыўнай логікі ў выпадку збою

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

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

Паўтарыце

Паўтор пры збоі запыту

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

Тайм-аўт

Кантрольны час чакання пры збоі

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

Праверка сэрвісаў (Service Health)

Kubernetes-платформы адсочваюць спраўнасць кантэйнераў з дапамогай спецыяльных сэрвісаў. Каб ніжэйлеглая платформа магла маніторыць сэрвісы, Spring-распрацоўшчыкі звычайна выкарыстоўваюць наладжвальныя HealthIndicator і Spring Boot Actuator. У Quarkus гэта можна зрабіць з дапамогай MicroProfile Health, якія па змаўчанні выконваюць праверку працаздольнасці (liveness check), але могуць быць наладжаны і на адначасовую праверку liveness і readiness (гатоўнасці). Прыклады выкарыстання падтрымліваемых MicroProfile Health API прыводзяцца ў табліцы 6, а дадатковая інфармацыя прадстаўлена ў кіраўніцтве Quarkus Health Guide.

Табліца 6. Прыклады выкарыстання падтрымліваемых API-інтэрфейсаў MicroProfile Health.

Функцыі MicroProfile Health
Апісанне
прыклады

@Liveness

Платформа выконвае перазагрузку няспраўных кантэйнерызаваных прыкладанняў
Канчатковы пункт:
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

Платформа не будзе адпраўляць трафік на кантэйнерызаванае прыкладанняў у выпадку яго негатоўнасці
Канчатковы пункт:
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();  
}

Метрыкі

Прыкладанні падаюць метрыкі або ў аперацыйных мэтах (для кантролю SLA-паказчыкаў прадукцыйнасці), або ў неаперацыйных (бізнэс-паказчыкі SLA). Spring-распрацоўшчыкі падаюць метрыкі з дапамогай Spring Boot Actuator і Micrometer. У сваю чаргу, Quarkus выкарыстоўвае MicroProfile Metrics для прадастаўлення базавых метрык (JVM і аперацыйная сістэма), вендар-метрык (Quarkus) і метрык прыкладанняў. MicroProfile Metrics патрабуе, каб рэалізацыя падтрымлівала выходныя фарматы JSON і OpenMetrics (Prometheus). Прыклады выкарыстання MicroProfile Metrics API прыводзяцца ў табліцы 7.

В праекце з нашага прыкладу MicroProfile Metrics выкарыстоўваюцца для прадастаўлення метрык прыкладання. Дадатковыя звесткі можна знайсці ў кіраўніцтве Quarkus Metrics Guide.

Табліца 7. Прыклады выкарыстання API-інтэрфейсаў MicroProfile Metrics.

Функцыі MicroProfile Metrics
Апісанне
прыклады

@Counted

Абазначае counter-лічыльнік, які падлічвае колькасць выклікаў анатаванага аб'екта

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

@ConcurrentGauge

Пазначае gauge-датчык, які падлічвае колькасць паралельных выклікаў анатаванага аб'екта

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

@Gauge

Пазначае gauge-датчык, які замярае значэнне анатаванага аб'екта

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

@Metered

Пазначае meter-датчык, які адсочвае частату выкліку анатаванага аб'екта

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

Метрыка

Анатацыя, якая змяшчае інфармацыю аб метададзеных, пры паступленні запыту на ўнясенне або вытворчасць метрыкі

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

Прымеркаваны

Пазначае таймер, які адсочвае працягласць анатаванага аб'екта

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

Канчатковыя кропкі метрык (Metrics Endpoints)

Метрыкі прыкладанняў лакальны:8080/metrics/application
Базавыя метрыкі лакальны:8080/metrics/base
Вендар-метрыкі лакальны:8080/metrics/vendor
Усе метрыкі лакальны:8080/metrics

Rest-кліент MicroProfile

Мікрасэрвісы часта падаюць канчатковыя кропкі RESTful, для працы з якімі патрабуюцца адпаведныя кліенцкія API. Каб выкарыстоўваць канчатковыя кропкі RESTful, Spring-распрацоўшчыкі звычайна ўжываюць RestTemplate. Quarkus жа прапануе для рашэння гэтай задачы API-інтэрфейсы MicroProfile Rest Client, прыклады выкарыстання якіх прыводзяцца ў табліцы 8.

В праекце з нашага прыкладу выкарыстанне канчатковых кропак RESTful выконваецца з дапамогай MicroProfile Rest Client. Дадатковыя звесткі і прыклады на гэтую тэму можна знайсці ў інструкцыі Quarkus Rest Client Guide.

Табліца 8. Прыклады выкарыстання API-інтэрфейсаў MicroProfile Rest Client.

Функцыі MicroProfile Rest Client
Апісанне
прыклады

@RegisterRestClient

Рэгіструе тыпізаваны Java-інтэрфейс у якасці кліента REST

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

@RestClient

Адзначае ўкараненне экзэмпляра тыпізаванага інтэрфейсу REST-кліента

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

маленне

Выклікае канчатковую кропку REST

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

mp-rest/url

Задае канчатковую кропку REST

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

Вынікі

У гэтым блогу, які ў першую чаргу спатрэбіцца Spring-распрацоўнікам, мы коратка разгледзелі, як у Quarkus выкарыстоўваць API-інтэрфейсы Spring разам API-інтэрфейсамі MicroProfile, каб распрацоўваць мікрасэрвісы Java і затым кампіляваць іх у натыўны двайковы код, які эканоміць сотні мегабайт аператыўнай памяці і запускаецца за лічаныя мілісекунды.

Як вы ўжо зразумелі, дадатковыя звесткі аб падтрымцы API-інтэрфейсаў Spring і MicroProfile, а таксама масу іншай карыснай інфармацыі можна знайсці ў кіраўніцтвах Quarkus.

Крыніца: habr.com

Дадаць каментар