{"id":79987,"date":"2020-05-02T01:42:42","date_gmt":"2020-05-01T23:42:42","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring"},"modified":"2020-05-02T01:42:42","modified_gmt":"2020-05-01T23:42:42","slug":"kak-quarkus-obedinyaet-microprofile-i-spring","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","title":{"rendered":"Jak Quarkus \u0142\u0105czy MicroProfile i Spring","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Cze\u015b\u0107 wszystkim, z wami trzeci post z serii o Quarkus!<\/p>\n<p><img decoding=\"async\" alt=\"Jak Quarkus \u0142\u0105czy MicroProfile i Spring\" src=\"\/wp-content\/uploads\/2020\/05\/d98ff470b49f8de1fa488a6818160969.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPodczas rozwoju mikrous\u0142ug w Javie cz\u0119sto uwa\u017ca si\u0119, \u017ce <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2019\/02\/28\/jumpstart-microservices-microprofile-starter-beta\/\">Eclipse MicroProfile<\/a><\/noindex> i <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/spring-boot\/\">Spring Boot<\/a><\/noindex> to oddzielne i niezale\u017cne od siebie API. Domy\u015blnie programi\u015bci zazwyczaj korzystaj\u0105 z tych API, do kt\u00f3rych s\u0105 ju\u017c przyzwyczajeni, poniewa\u017c nauka nowych framework\u00f3w i komponent\u00f3w runtime zajmuje du\u017co czasu. Dzi\u015b spr\u00f3bujemy u\u0142atwi\u0107 opanowanie niekt\u00f3rych popularnych <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/11\/21\/eclipse-microprofile-for-spring-boot-developers\/\">API MicroProfile dla programist\u00f3w Spring<\/a><\/noindex> i poka\u017cemy, jak jednocze\u015bnie wykorzysta\u0107 API Spring oraz nowe, przydatne mo\u017cliwo\u015bci <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/\">Quarkus<\/a><\/noindex>.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nJe\u015bli przejdziemy nieco g\u0142\u0119biej, najpierw om\u00f3wimy obszar zastosowania i szczeg\u00f3\u0142y dotycz\u0105ce tego, jak Quarkus wspiera interfejsy API Spring, aby pokaza\u0107 programistom Spring, jak mog\u0105 stosowa\u0107 API MicroProfile w swojej codziennej pracy. Nast\u0119pnie opowiemy o API MicroProfile, kt\u00f3re b\u0119d\u0105 przydatne programistom Spring w tworzeniu mikrous\u0142ug.<\/p>\n<p>Dlaczego akurat Quarkus? Po pierwsze, to kodowanie na \u017cywo (live coding), czyli automatyczne prze\u0142adowanie wszelkich zmian w API MicroProfile, API Spring i innych API Javy, kt\u00f3re wykonuje si\u0119 jednym poleceniem: mvn quarkus:dev. Po drugie, omawiany w <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">naszym przyk\u0142adzie<\/a><\/noindex> serwis Person (kompilowany z interfejs\u00f3w API Spring, MicroProfile i JPA do pliku binarnego przy u\u017cyciu natywnego obrazu GraalVM) uruchamia si\u0119 w zaledwie 0,055 sekundy i zajmuje oko\u0142o 90 MB pami\u0119ci RAM (RSS) na ko\u0144cowym punkcie aplikacji RESTful. W dodatku jego kompilacja odbywa si\u0119 przy pomocy jednego polecenia: mvn package -Pnative.<\/p>\n<p>Nie b\u0119dziemy zag\u0142\u0119bia\u0107 si\u0119 w szczeg\u00f3\u0142y MicroProfile, a jedynie postaramy si\u0119 pom\u00f3c programistom Spring zrozumie\u0107, jak w Quarkus mo\u017cna u\u017cywa\u0107 interfejs\u00f3w API Spring razem z interfejsami API MicroProfile.<\/p>\n<h3>Kontenery i Kubernetes<\/h3>\n<p>\nAby nie przeci\u0105\u017ca\u0107 tego artyku\u0142u, om\u00f3wimy tutaj jedynie og\u00f3lne aspekty wsparcia <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/developer-tools\/kubernetes\">Kubernetes<\/a><\/noindex>, co jest wa\u017cne do zrozumienia. Quarkus pozycjonuje si\u0119 jako Java stack dla Kubernetes, ma na celu minimalizacj\u0119 zu\u017cycia pami\u0119ci i czasu uruchamiania aplikacji Java i us\u0142ug, co z kolei zwi\u0119ksza g\u0119sto\u015b\u0107 ich rozmieszczenia na ho\u015bcie i obni\u017ca ca\u0142kowite koszty.<\/p>\n<p>Quarkus r\u00f3wnie\u017c <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/kubernetes-resources\">wspiera autogeneracj\u0119<\/a><\/noindex> zasob\u00f3w Kubernetes i oferuje <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/\">przewodniki<\/a><\/noindex> dotycz\u0105ce wdra\u017cania na platformach Kubernetes i Red Hat OpenShift. Ponadto Quarkus automatycznie generuje pliki Dockerfile.jvm (opakowanie JVM) i Dockerfile.native (opakowanie dla binari\u00f3w natywnych), kt\u00f3re s\u0105 niezb\u0119dne do tworzenia kontener\u00f3w.<\/p>\n<p>I wreszcie, bazuj\u0105c na Kubernetes jako docelowym \u015brodowisku wdro\u017ceniowym, Quarkus nie u\u017cywa framework\u00f3w Java w przypadkach, gdy podobna funkcjonalno\u015b\u0107 jest wdro\u017cona na poziomie samej platformy Kubernetes. W tabeli 1 przedstawiona jest mapa zgodno\u015bci funkcjonalnej Kubernetes i typowych framework\u00f3w Java stosowanych przez deweloper\u00f3w Spring.<\/p>\n<p><i>Tabela 1. Mapa zgodno\u015bci framework\u00f3w Java i Kubernetes.<\/i><\/p>\n<p>Funkcjonalno\u015b\u0107<br \/>\nTradycyjny Spring Boot<br \/>\nKubernetes<\/p>\n<p>Odkrywanie us\u0142ug<br \/>\nEureka<br \/>\nDNS<\/p>\n<p>Konfiguracja<br \/>\nSpring Cloud Config<br \/>\nConfig Maps \/ Secrets<\/p>\n<p>Obci\u0105\u017cenie r\u00f3wnowa\u017cenie<br \/>\nRibbon (po stronie klienta)<br \/>\nUs\u0142uga, Replication Controller (po stronie serwera)<\/p>\n<p><\/p>\n<h3>Kompilacja i uruchomienie kodu z przyk\u0142adu<\/h3>\n<p>\nW tym artykule odnosimy si\u0119 do <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">przyk\u0142adu projektu<\/a><\/noindex>, w kt\u00f3rym wsp\u00f3\u0142dzielone s\u0105 interfejsy API Spring i MicroProfile, a nawet ten sam klas Java. Kod z tego przyk\u0142adu mo\u017cna skompilowa\u0107 i uruchomi\u0107 z linii polece\u0144, wi\u0119cej informacji w pliku README.md.<\/p>\n<h3>Interfejsy API Spring Framework<\/h3>\n<p><\/p>\n<h4>Wstrzykiwanie zale\u017cno\u015bci<\/h4>\n<p>\nQuarkus obs\u0142uguje szereg <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/cdi-reference\">interfejs\u00f3w API kontekst\u00f3w i wstrzykiwania zale\u017cno\u015bci (CDI)<\/a><\/noindex> oraz interfejs\u00f3w API Spring Dependency Injection (Spring DI). Je\u015bli pracujesz z MicroProfile, <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2019\/09\/12\/jakarta-ee-8-the-new-era-of-java-ee-explained\/\">Java EE i Jakarta EE<\/a><\/noindex>, to ju\u017c dobrze znasz CDI. Z drugiej strony, deweloperzy Spring mog\u0105 u\u017cywa\u0107 Quarkus Extension for Spring DI API, aby zapewni\u0107 zgodno\u015b\u0107 z Spring DI. Przyk\u0142ady u\u017cycia wspieranych API Spring DI s\u0105 przedstawione w tabeli 2.<\/p>\n<p>W <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">w projekcie z naszego przyk\u0142adu<\/a><\/noindex> zastosowano zar\u00f3wno CDI, jak i Spring Dependency Injection. Dodatkowe informacje i przyk\u0142ady na ten temat mo\u017cna znale\u017a\u0107 w przewodniku Quarkus zatytu\u0142owanym <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-di\">Spring DI Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabela 2. Przyk\u0142ady u\u017cycia wspieranych interfejs\u00f3w API Spring DI.<\/i><\/p>\n<p>Wspierane funkcje Spring DI<br \/>\nPrzyk\u0142ady<\/p>\n<p>Wstrzykiwanie konstruktora<\/p>\n<pre><code class=\"plaintext\">public PersonSpringController(\n   PersonSpringRepository personRepository,  \/\/ wstrzykni\u0119te      \n   PersonSpringMPService personService) {    \/\/ wstrzykni\u0119te\n      this.personRepository = personRepository;\n      this.personService = personService;\n}\n<\/code><\/pre>\n<p>Wstrzykiwanie pola<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/autowired\/\" class=\"user_link\">@Autowired<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/value\/\" class=\"user_link\">@Value<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Autowired\n@RestClient\nSalutationRestClient salutationRestClient;\n\n@Value(\"${fallbackSalutation}\")\nString fallbackSalutation;\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/bean\/\" class=\"user_link\">Ziarno<\/a><\/noindex><br \/>\n@Configuration<\/p>\n<pre><code class=\"plaintext\">@Configuration\npublic class AppConfiguration {\n   @Bean(name = \"capitalizeFunction\")\n   public StringFunction capitalizer() {\n      return String::toUpperCase;\n   }\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/component\/\" class=\"user_link\">Komponent<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Component(\"noopFunction\")\npublic class NoOpSingleStringFunction implements StringFunction {\n   @Override\n   public String apply(String s) {\n      return s;\n   }\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/service\/\" class=\"user_link\">Service<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Service\npublic class MessageProducer {\n   @Value(\"${greeting.message}\")\n   String message;\n\n   public String getPrefix() {\n      return message;\n   }\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Framework webowy<\/h4>\n<p>\nU\u017cytkownikom MicroProfile spodoba si\u0119, \u017ce Quarkus obs\u0142uguje JAX-RS, MicroProfile Rest Client, JSON-P i JSON-B jako g\u0142\u00f3wny model programowania aplikacji webowych. Programi\u015bci Spring b\u0119d\u0105 zadowoleni z nowo wprowadzonego wsparcia dla Spring Web API w Quarkus, w szczeg\u00f3lno\u015bci interfejs\u00f3w odpowiedzialnych za REST. Podobnie jak w przypadku Spring DI, g\u0142\u00f3wnym celem wsparcia dla Spring Web API jest umo\u017cliwienie programistom Spring korzystania z interfejs\u00f3w API Spring Web wraz z interfejsami API MicroProfile. Przyk\u0142ady wykorzystania wspieranych interfejs\u00f3w API Spring Web przedstawione s\u0105 w tabeli 3, a dodatkowe informacje i przyk\u0142ady mo\u017cna znale\u017a\u0107 w przewodniku Quarkus o nazwie <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-web\">Przewodnik po Spring Web<\/a><\/noindex>.<\/p>\n<p><i>Tabela 3. Przyk\u0142ady zastosowania wspieranych interfejs\u00f3w API Spring Web.<\/i><\/p>\n<p>Obs\u0142ugiwane funkcje Spring Web<br \/>\nPrzyk\u0142ady<\/p>\n<p>@RestController<br \/>\n@RequestMapping<\/p>\n<pre><code class=\"plaintext\">@RestController\n@RequestMapping(\"\/person\")\npublic class PersonSpringController {\n   ...\n   ...\n   ...\n}\n<\/code><\/pre>\n<p>@GetMapping<br \/>\n@PostMapping<br \/>\n@PutMapping<br \/>\n@DeleteMapping<br \/>\n@PatchMapping<br \/>\n@RequestParam<br \/>\n@RequestHeader<br \/>\n@MatrixVariable<br \/>\n@PathVariable<br \/>\n@CookieValue<br \/>\n@RequestBody<br \/>\n@ResponseStatus<br \/>\n@ExceptionHandler<br \/>\n@RestControllerAdvice (cz\u0119\u015bciowo)<\/p>\n<pre><code class=\"plaintext\">@GetMapping(path = \"\/greet\/{id}\",\n   produces = \"text\/plain\")\n   public String greetPerson(\n   @PathVariable(name = \"id\") long id) {\n   ...\n   ...\n   ...\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Spring Data JPA<\/h4>\n<p>\nU\u017cytkownikom MicroProfile r\u00f3wnie\u017c przypadnie do gustu, \u017ce Quarkus obs\u0142uguje JPA przy u\u017cyciu Hibernate ORM. Dla programist\u00f3w Spring te\u017c jest dobra wiadomo\u015b\u0107: Quarkus obs\u0142uguje powszechnie stosowane adnotacje i typy Spring Data JPA. Przyk\u0142ady u\u017cycia wspieranych interfejs\u00f3w API Spring Data JPA przedstawione s\u0105 w tabeli 4.<br \/>\nW <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">w projekcie z naszego przyk\u0142adu<\/a><\/noindex> wspierane s\u0105 interfejsy API Spring Data JPA, a dodatkowe informacje dost\u0119pne s\u0105 w przewodniku Quarkus o nazwie <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-data-jpa-guide\">Przewodnik po Spring Data JPA<\/a><\/noindex>.<\/p>\n<p><i>Tabela 4. Przyk\u0142ady zastosowania wspieranych interfejs\u00f3w API Spring Data JPA.<\/i><\/p>\n<p>Obs\u0142ugiwane funkcje Spring Data JPA<br \/>\nPrzyk\u0142ady<\/p>\n<p>CrudRepository<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository\n         extends JpaRepository,\n                 PersonFragment {\n   ...\n}\n<\/code><\/pre>\n<p>Repozytorium<br \/>\nJpaRepository<br \/>\nPagingAndSortingRepository<\/p>\n<pre><code class=\"plaintext\">public class PersonRepository extends \n\n    Repository {\n\n    Person save(Person entity);\n\n    Optional findById(Person entity);\n}\n<\/code><\/pre>\n<p>Fragmenty repozytori\u00f3w<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository\n         extends JpaRepository,\n                 PersonFragment {\n   ...\n}\n<\/code><\/pre>\n<p>Metody zapyta\u0144 pochodnych<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository extends CrudRepository {\n\n    List findByName(String name);\n    \n    Person findByNameBySsn(String ssn);\n    \n    Optional \n       findByNameBySsnIgnoreCase(String ssn);\n\n    Boolean existsBookByYearOfBirthBetween(\n            Integer start, Integer end);\n}\n<\/code><\/pre>\n<p>Zapytania zdefiniowane przez u\u017cytkownika<\/p>\n<pre><code class=\"plaintext\">public interface MovieRepository\n         extends CrudRepository {\n\n    Movie findFirstByOrderByDurationDesc();\n\n    @Query(\"select m from Movie m where m.rating = ?1\")\n    Iterator findByRating(String rating);\n\n    @Query(\"from Movie where title = ?1\")\n    Movie findByTitle(String title);\n}\n<\/code><\/pre>\n<p><\/p>\n<h3>Interfejsy API MicroProfile<\/h3>\n<p><\/p>\n<h4>Tolerancja na b\u0142\u0119dy (Fault tolerance)<\/h4>\n<p>\nKonstrukcje wysokiej dost\u0119pno\u015bci s\u0105 bardzo wa\u017cne, aby zapobiega\u0107 awariom kaskadowym i tworzy\u0107 niezawodne architektury mikroserwisowe. Programi\u015bci Spring od lat korzystaj\u0105 z circuit-breaker'\u00f3w w celu zapewnienia odporno\u015bci na awarie. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Netflix\/Hystrix\">Hystrix<\/a><\/noindex>. Jednak Hystrix od d\u0142u\u017cszego czasu nie by\u0142 aktualizowany, a API MicroProfile Fault Tolerance jest aktywnie rozwijane i ma ju\u017c za sob\u0105 kilka lat u\u017cytkowania w produkcji. Dlatego w celu zwi\u0119kszenia niezawodno\u015bci us\u0142ug w Quarkus zaleca si\u0119 korzystanie z interfejs\u00f3w API MicroProfile Fault Tolerance, a przyk\u0142ady ich u\u017cycia s\u0105 przedstawione w tabeli 5. Dodatkowe informacje mo\u017cna znale\u017a\u0107 w przewodniku Quarkus. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-fault-tolerance\">Przewodnik po wysokiej dost\u0119pno\u015bci<\/a><\/noindex>.<\/p>\n<p><i>Tabela 5. Przyk\u0142ady u\u017cycia obs\u0142ugiwanych interfejs\u00f3w API MicroProfile Fault Tolerance.<\/i><\/p>\n<p>Funkcje MicroProfile Fault Tolerance<br \/>\nOpis<br \/>\nPrzyk\u0142ady<\/p>\n<p>@Asynchronous<\/p>\n<p>Wykonywanie logiki w osobnym w\u0105tku<\/p>\n<pre><code class=\"plaintext\">@Asynchronous\n@Retry\npublic Future getSalutation() {\n   ...\n   return future;\n}\n<\/code><\/pre>\n<p>@Bulkhead<\/p>\n<p>Ograniczenie liczby jednoczesnych \u017c\u0105da\u0144<\/p>\n<pre><code class=\"plaintext\">@Bulkhead(5)\npublic void fiveConcurrent() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p>@CircuitBreaker<\/p>\n<p>Inteligentne przetwarzanie b\u0142\u0119d\u00f3w i odzyskiwanie po awariach<\/p>\n<pre><code class=\"plaintext\">@CircuitBreaker(delay=500   \/\/ milliseconds\n   failureRatio = .75,\n   requestVolumeThreshold = 20,\n   successThreshold = 5)\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p>@Fallback<\/p>\n<p>Wywo\u0142anie alternatywnej logiki w przypadku awarii<\/p>\n<pre><code class=\"plaintext\">@Timeout(500) \/\/ milliseconds\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n\npublic String fallback() {\n   return \"hello\";\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/retry\/\" class=\"user_link\">Retry<\/a><\/noindex><\/p>\n<p>Powt\u00f3rzenie w przypadku awarii \u017c\u0105dania<\/p>\n<pre><code class=\"plaintext\">@Retry(maxRetries=3)\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/timeout\/\" class=\"user_link\">Timeout<\/a><\/noindex><\/p>\n<p>Czas oczekiwania w przypadku awarii<\/p>\n<pre><code class=\"plaintext\">@Timeout(value = 500 )   \/\/ milliseconds\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Sprawdzanie stanu us\u0142ug (Service Health)<\/h4>\n<p>\nPlatformy Kubernetes monitoruj\u0105 stan kontener\u00f3w za pomoc\u0105 specjalnych us\u0142ug. Aby dolna platforma mog\u0142a monitorowa\u0107 us\u0142ugi, programi\u015bci Spring zazwyczaj korzystaj\u0105 z konfigurowalnych HealthIndicator i Spring Boot Actuator. W Quarkus mo\u017cna to zrealizowa\u0107 za pomoc\u0105 MicroProfile Health, kt\u00f3re domy\u015blnie wykonuj\u0105 sprawdzenie stanu (liveness check), ale mog\u0105 by\u0107 tak\u017ce skonfigurowane do jednoczesnego sprawdzania liveness i readiness (gotowo\u015bci). Przyk\u0142ady u\u017cycia obs\u0142ugiwanych interfejs\u00f3w API MicroProfile Health przedstawione s\u0105 w tabeli 6, a dodatkowe informacje zawarte s\u0105 w przewodniku Quarkus. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-health\">Przewodnik po zdrowiu<\/a><\/noindex>.<\/p>\n<p><i>Tabela 6. Przyk\u0142ady u\u017cycia obs\u0142ugiwanych interfejs\u00f3w API MicroProfile Health.<\/i><\/p>\n<p>Funkcje MicroProfile Health<br \/>\nOpis<br \/>\nPrzyk\u0142ady<\/p>\n<p>@Liveness<\/p>\n<p>Platforma przeprowadza ponowne uruchomienie uszkodzonych aplikacji kontenerowych<br \/>\nEndpoint:<br \/>\nhost:8080\/health\/live<\/p>\n<pre><code class=\"plaintext\">@Liveness\npublic class MyHC implements HealthCheck {\n  public HealthCheckResponse call() {\n\n   ...\n   return HealthCheckResponse\n     .named(\"myHCProbe\")\n     .status(ready ? true:false)\n     .withData(\"mydata\", data)\n     .build();  \n}\n<\/code><\/pre>\n<p>@Readiness<\/p>\n<p>Platforma nie b\u0119dzie kierowa\u0107 ruchu do kontenerizowanej aplikacji, je\u015bli b\u0119dzie ona niegotowa<br \/>\nEndpoint:<br \/>\nhost:8080\/health\/ready<\/p>\n<pre><code class=\"plaintext\">@Readiness\npublic class MyHC implements HealthCheck {\n  public HealthCheckResponse call() {\n\n   ...\n   return HealthCheckResponse\n     .named(\"myHCProbe\")\n     .status(live ? true:false)\n     .withData(\"mydata\", data)\n     .build();  \n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Metryki<\/h4>\n<p>\nAplikacje dostarczaj\u0105 metryki zar\u00f3wno w celach operacyjnych (do monitorowania wska\u017anik\u00f3w wydajno\u015bci SLA), jak i nieoperacyjnych (wska\u017aniki biznesowe SLA). Programi\u015bci Spring dostarczaj\u0105 metryki za pomoc\u0105 Spring Boot Actuator i Micrometer. Z kolei Quarkus wykorzystuje MicroProfile Metrics do dostarczania podstawowych metryk (JVM i system operacyjny), metryk dostawc\u00f3w (Quarkus) i metryk aplikacji. MicroProfile Metrics wymaga, aby implementacja wspiera\u0142a formaty wyj\u015bciowe JSON i OpenMetrics (Prometheus). Przyk\u0142ady u\u017cycia API MicroProfile Metrics s\u0105 podane w tabeli 7.<\/p>\n<p>W <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">w projekcie z naszego przyk\u0142adu<\/a><\/noindex> MicroProfile Metrics s\u0105 u\u017cywane do dostarczania metryk aplikacji. Dalsze informacje mo\u017cna znale\u017a\u0107 w przewodniku Quarkus <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-metrics\">Przewodnik po metrykach<\/a><\/noindex>.<\/p>\n<p><i>Tabela 7. Przyk\u0142ady u\u017cycia interfejs\u00f3w API MicroProfile Metrics.<\/i><\/p>\n<p>Funkcje MicroProfile Metrics<br \/>\nOpis<br \/>\nPrzyk\u0142ady<\/p>\n<p>@Counted<\/p>\n<p>Oznacza licznik, kt\u00f3ry zlicza liczb\u0119 wywo\u0142a\u0144 oznaczonego obiektu<\/p>\n<pre><code class=\"plaintext\">@Counted(name = \"fallbackCounter\", \n  displayName = \"Fallback Counter\", \n  description = \"Fallback Counter\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@ConcurrentGauge<\/p>\n<p>Oznacza wska\u017anik, kt\u00f3ry zlicza liczb\u0119 r\u00f3wnoleg\u0142ych wywo\u0142a\u0144 oznaczonego obiektu<\/p>\n<pre><code class=\"plaintext\">@ConcurrentGuage(\n  name = \"fallbackConcurrentGauge\", \n  displayName=\"Fallback Concurrent\", \n  description=\"Fallback Concurrent\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@Gauge<\/p>\n<p>Oznacza wska\u017anik, kt\u00f3ry mierzy warto\u015b\u0107 oznaczonego obiektu<\/p>\n<pre><code class=\"plaintext\">@Metered(name = \"FallbackGauge\",\n   displayName=\"Fallback Gauge\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@Metered<\/p>\n<p>Oznacza wska\u017anik, kt\u00f3ry \u015bledzi cz\u0119stotliwo\u015b\u0107 wywo\u0142a\u0144 oznaczonego obiektu<\/p>\n<pre><code class=\"plaintext\">@Metered(name = \"MeteredFallback\",\n   displayName=\"Metered Fallback\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/metric\/\" class=\"user_link\">Metryka<\/a><\/noindex><\/p>\n<p>Adnotacja zawieraj\u0105ca informacje o metadanych, w momencie zapytania o utworzenie lub produkcj\u0119 metryki<\/p>\n<pre><code class=\"plaintext\">@Metric\n@Metered(name = \"MeteredFallback\",\n   displayName=\"Metered Fallback\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/timed\/\" class=\"user_link\">Czasowany<\/a><\/noindex><\/p>\n<p>Oznacza timer, kt\u00f3ry \u015bledzi czas trwania oznaczonego obiektu<\/p>\n<pre><code class=\"plaintext\">@Timed(name = \"TimedFallback\",\n   displayName=\"Timed Fallback\",\n   description=\"Fallback delay\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>\n<b>Punkty ko\u0144cowe metryk<\/b><\/p>\n<p>Metryki aplikacji <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/application<br \/>\nPodstawowe metryki <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/base<br \/>\nMetryki dostawcy <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/vendor<br \/>\nWszystkie metryki <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics<\/p>\n<h4>Klient REST MicroProfile<\/h4>\n<p>\nMikroserwisy cz\u0119sto udost\u0119pniaj\u0105 punkty ko\u0144cowe RESTful, do kt\u00f3rych ob\u0142ugi wymagane s\u0105 odpowiednie API klient\u00f3w. Aby korzysta\u0107 z punkt\u00f3w ko\u0144cowych RESTful, deweloperzy Springa zazwyczaj u\u017cywaj\u0105 RestTemplate. Quarkus oferuje jednak API MicroProfile Rest Client do tego celu, a przyk\u0142ady jego u\u017cycia podano w tabeli 8.<\/p>\n<p>W <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">w projekcie z naszego przyk\u0142adu<\/a><\/noindex> U\u017cycie punkt\u00f3w ko\u0144cowych RESTful jest realizowane za pomoc\u0105 MicroProfile Rest Client. Dodatkowe informacje i przyk\u0142ady na ten temat mo\u017cna znale\u017a\u0107 w przewodniku Quarkus. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/rest-client\">Przewodnik klienta REST<\/a><\/noindex>.<\/p>\n<p><i>Tabela 8. Przyk\u0142ady u\u017cycia API MicroProfile Rest Client.<\/i><\/p>\n<p>Funkcje MicroProfile Rest Client<br \/>\nOpis<br \/>\nPrzyk\u0142ady<\/p>\n<p>@RegisterRestClient<\/p>\n<p>Rejestruje typizowany interfejs Java jako klienta REST<\/p>\n<pre><code class=\"plaintext\">@RegisterRestClient\n@Path(\"\/\")\npublic interface MyRestClient {\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    public String getSalutation();\n}\n<\/code><\/pre>\n<p>@RestClient<\/p>\n<p>Oznacza wstrzykni\u0119cie instancji typizowanego interfejsu klienta REST<\/p>\n<pre><code class=\"plaintext\">@Autowired \/\/ or @Inject\n@RestClient\nMyRestClient restClient;\n<\/code><\/pre>\n<p>Wywo\u0142anie<\/p>\n<p>Wywo\u0142uje punkt ko\u0144cowy REST<\/p>\n<pre><code class=\"plaintext\">System.out.println(\n   restClient.getSalutation());\n<\/code><\/pre>\n<p>mp-rest\/url<\/p>\n<p>Ustala punkt ko\u0144cowy REST<\/p>\n<pre><code class=\"plaintext\">application.properties:\norg.example.MyRestClient\/mp-rest\/url=\n   http:\/\/localhost:8081\/myendpoint\n<\/code><\/pre>\n<p><\/p>\n<h3>Podsumowanie<\/h3>\n<p>\nW tym blogu, kt\u00f3ry przede wszystkim b\u0119dzie przydatny dla deweloper\u00f3w Springa, kr\u00f3tko om\u00f3wili\u015bmy, jak w Quarkus u\u017cywa\u0107 interfejs\u00f3w API Springa razem z API MicroProfile do tworzenia mikroserwis\u00f3w Java, a nast\u0119pnie kompilowa\u0107 je do natywnego kodu binarnego, co oszcz\u0119dza setki megabajt\u00f3w pami\u0119ci RAM i uruchamia si\u0119 w kilka milisekund.<\/p>\n<p>Jak ju\u017c zrozumieli\u015bcie, dodatkowe informacje o wsparciu dla interfejs\u00f3w API Spring i MicroProfile oraz wiele innych przydatnych informacji mo\u017cna znale\u017a\u0107 w <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/\">przewodnikach Quarkus<\/a><\/noindex>.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/497504\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus! \u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Java-\u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0447\u0430\u0441\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e Eclipse MicroProfile \u0438 Spring Boot \u2013 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430 API. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0442\u0435 API, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d\u0438 \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 runtime-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79988,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79987","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a Quarkus \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 MicroProfile \u0438 Spring | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-01T23:42:42+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-01T23:42:42+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Jak Quarkus \u0142\u0105czy MicroProfile i Spring | ProHoster","description":"Cze\u015b\u0107 wszystkim, z wami trzeci post z serii o Quarkus!","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a Quarkus \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 MicroProfile \u0438 Spring | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-01T23:42:42+00:00","article:modified_time":"2020-05-01T23:42:42+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79987","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:27:13","updated":"2022-09-30 14:08:43","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/79987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=79987"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/79987\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/79988"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=79987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=79987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=79987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}