Hello everyone, and here is the third post from the series about Quarkus!
When developing Java microservices, it is often assumed that
In a little more detail, we will first look at the scope and details of how Quarkus supports the Spring APIs to show Spring developers how to use the MicroProfile API in their daily work. Then we'll talk about the MicroProfile API, which will be useful for Spring developers when creating microservices.
Why Quarkus? Firstly, this is live coding, that is, automatic reloading of any changes in the MicroProfile API, Spring API and other Java APIs, which is performed with just one command: mvn quarkus:dev. Second, considered in
We will not delve into the details of MicroProfile, but will only try to help Spring developers understand how Quarkus can use the Spring APIs along with the MicroProfile APIs.
Containers and Kubernetes
In order not to overload this article, we will only cover the high-level aspects of support here.
Quarkus also
And finally, focusing on Kubernetes as a target deployment environment, Quarkus does not use Java frameworks in cases where similar functionality is implemented at the level of the Kubernetes platform itself. Table 1 provides a functional mapping between Kubernetes and typical Java frameworks used by Spring developers.
Table 1. Functional map of Java frameworks and Kubernetes.
Functional
Traditional Spring Boot
Kubernetes
Service discovery
Eureka
DNS
Configuration
Spring Cloud Configuration
Config Maps/Secrets
load balancing
Ribbon (client side)
Service, Replication Controller(server side)
Compiling and running the code from the example
In this article we refer to
Spring Framework APIs
Dependency Injection
Quarkus supports a range of
Π
Table 2. Examples of using the supported Spring DI APIs.
Supported features of Spring DI
Examples
Constructor Injection
public PersonSpringController(
PersonSpringRepository personRepository, // injected
PersonSpringMPService personService) { // injected
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 framework
MicroProfile users will love that Quarkus supports JAX-RS, MicroProfile Rest Client, JSON-P, and JSON-B as the core web programming model. Spring developers will be pleased with the recent support for the Spring Web API in Quarkus, in particular the interfaces responsible for REST. Similar to Spring DI, the main goal of supporting the Spring Web API is to allow Spring developers to use the Spring Web APIs along with the MicroProfile APIs. Examples of using the supported Spring Web APIs are shown in Table 3, and more information and examples on this topic can be found in the Quarkus guide called
Table 3. Examples of using the supported Spring Web APIs.
Supported features of Spring Web
Examples
@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 users will also appreciate that Quarkus supports JPA using the Hibernate ORM. There is good news for Spring developers too: Quarkus supports common Spring Data JPA annotations and types. Examples of using the supported Spring Data JPA APIs are shown in Table 4.
Π
Table 4. Examples of using the supported Spring Data JPA APIs.
Supported features of Spring Data JPA
Examples
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 {
...
}
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);
}
MicroProfile APIs
Fault tolerance
Fault tolerance constructs are very important for preventing cascading failures and building robust microservice architectures. Spring developers have been using circuit-breakers for fault tolerance for many years.
Table 5. MicroProfile Fault Tolerance supported API usage examples.
MicroProfile Fault Tolerance Features
Description
Examples
@Asynchronous
Running logic on a separate thread
@Asynchronous
@Retry
public Future<String> getSalutation() {
...
return future;
}
@Bulkhead
Limiting the number of concurrent requests
@Bulkhead(5)
public void fiveConcurrent() {
makeRemoteCall(); //...
}
@CircuitBreaker
Smart failover and failover
@CircuitBreaker(delay=500 // milliseconds
failureRatio = .75,
requestVolumeThreshold = 20,
successThreshold = 5)
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
@fallback
Calling alternative logic in case of failure
@Timeout(500) // milliseconds
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
public String fallback() {
return "hello";
}
Retry on request failure
@Retry(maxRetries=3)
public String getSalutation() {
makeRemoteCall(); //...
}
Control timeout on failure
@Timeout(value = 500 ) // milliseconds
@Fallback(fallbackMethod = "fallback")
public String getSalutation() {
makeRemoteCall(); //...
}
Checking services (Service Health)
Kubernetes platforms monitor the health of containers using special services. In order for the underlying platform to monitor services, Spring developers typically use a custom HealthIndicator and Spring Boot Actuator. In Quarkus, this can be done using MicroProfile Health, which by default perform a liveness check, but can also be configured to simultaneously check liveness and readiness (readiness). Examples of how to use the supported MicroProfile Health APIs are shown in Table 6, and more information is provided in the Quarkus manual.
Table 6. Usage examples for supported MicroProfile Health APIs.
MicroProfile Health Features
Description
Examples
@liveness
The platform reloads failed containerized applications
end point:
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
The platform will not send traffic to containerized applications if it is not ready
end point:
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();
}
Metrics
Applications provide metrics for either operational purposes (to monitor performance SLAs) or non-operational purposes (business SLAs). Spring developers provide metrics using the Spring Boot Actuator and Micrometer. In turn, Quarkus uses MicroProfile Metrics to provide base metrics (JVM and operating system), vendor metrics (Quarkus), and application metrics. MicroProfile Metrics requires the implementation to support JSON and OpenMetrics (Prometheus) output formats. Examples of using the MicroProfile Metrics API are shown in Table 7.
Π
Table 7. Examples of using the MicroProfile Metrics APIs.
Functions of MicroProfile Metrics
Description
Examples
@Counted
Indicates a counter that counts the number of calls to the annotated object
@Counted(name = "fallbackCounter",
displayName = "Fallback Counter",
description = "Fallback Counter")
public String salutationFallback() {
return fallbackSalutation;
}
@ConcurrentGauge
Indicates a gauge that counts the number of concurrent calls to the annotated object
@ConcurrentGuage(
name = "fallbackConcurrentGauge",
displayName="Fallback Concurrent",
description="Fallback Concurrent")
public String salutationFallback() {
return fallbackSalutation;
}
@Gauge
Indicates a gauge that measures the value of an annotated object.
@Metered(name = "FallbackGauge",
displayName="Fallback Gauge",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
@metered
Indicates a meter that monitors the call frequency of the annotated object
@Metered(name = "MeteredFallback",
displayName="Metered Fallback",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
An annotation containing information about metadata when a request is received to contribute or produce a metric
@Metric
@Metered(name = "MeteredFallback",
displayName="Metered Fallback",
description="Fallback frequency")
public String salutationFallback() {
return fallbackSalutation;
}
Denotes a timer that keeps track of the duration of the annotated object
@Timed(name = "TimedFallback",
displayName="Timed Fallback",
description="Fallback delay")
public String salutationFallback() {
return fallbackSalutation;
}
Metrics Endpoints
Application Metrics
Basic Metrics
Vendor metrics
All metrics
MicroProfile Rest Client
Microservices often provide RESTful endpoints that require appropriate client APIs to work with. To use RESTful endpoints, Spring developers typically use RestTemplate. Quarkus offers MicroProfile Rest Client APIs for this task, examples of which are given in Table 8.
Π
Table 8. MicroProfile Rest Client API usage examples.
MicroProfile Rest Client Features
Description
Examples
@RegisterRestClient
Registers a typed Java interface as a REST client
@RegisterRestClient
@Path("/")
public interface MyRestClient {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getSalutation();
}
@RestClient
Marks the injection of an instance of a typed REST client interface
@Autowired // or @Inject
@RestClient
MyRestClient restClient;
Summoner
Calls a REST endpoint
System.out.println(
restClient.getSalutation());
mp-rest/url
Specifies a REST endpoint
application.properties:
org.example.MyRestClient/mp-rest/url=
http://localhost:8081/myendpoint
Results
In this blog, primarily for Spring developers, we briefly looked at how to use the Spring APIs in Quarkus along with the MicroProfile APIs to develop Java microservices and then compile them into native binary that saves hundreds of megabytes of RAM. and starts in milliseconds.
As you already understood, additional information about support for the Spring and MicroProfile APIs, as well as a lot of other useful information, can be found in
Source: habr.com