ืื™ืš Quarkus ืžืฉืœื‘ MicroProfile ื•-Spring

ืฉืœื•ื ืœื›ื•ืœื, ื”ื ื” ื”ืคื•ืกื˜ ื”ืฉืœื™ืฉื™ ื‘ืกื“ืจืช Quarkus!

ืื™ืš Quarkus ืžืฉืœื‘ MicroProfile ื•-Spring

ื›ืืฉืจ ืžืคืชื—ื™ื ืฉื™ืจื•ืชื™ ืžื™ืงืจื• ืฉืœ Java, ืžืืžื™ื ื™ื ื›ื™ Eclipse MicroProfile ะธ ืžื’ืฃ ืื‘ื™ื‘ ื”ื ืžืžืฉืงื™ API ื ืคืจื“ื™ื ื•ืขืฆืžืื™ื™ื. ื›ื‘ืจื™ืจืช ืžื—ื“ืœ, ืžืชื›ื ืชื™ื ื ื•ื˜ื™ื ืœื”ืฉืชืžืฉ ื‘ืžืžืฉืงื™ ื”-API ืฉื”ื ื›ื‘ืจ ืจื’ื™ืœื™ื ืืœื™ื”ื, ืฉื›ืŸ ืœื™ืžื•ื“ ืžืกื’ืจื•ืช ื—ื“ืฉื•ืช ื•ืจื›ื™ื‘ื™ ื–ืžืŸ ืจื™ืฆื” ืœื•ืงื— ื”ืจื‘ื” ื–ืžืŸ. ื”ื™ื•ื ื ื ืกื” ืœืคืฉื˜ ืืช ื”ืคื™ืชื•ื— ืฉืœ ื›ืžื” ืคื•ืคื•ืœืจื™ MicroProfile API ืœืžืคืชื—ื™ Spring ื•ืœื”ืจืื•ืช ืœืš ื›ื™ืฆื“ ืœื”ืฉืชืžืฉ ื‘ื•-ื–ืžื ื™ืช ื‘-Spring API ื•ื‘ืชื›ื•ื ื•ืช ืฉื™ืžื•ืฉื™ื•ืช ื—ื“ืฉื•ืช ืงื•ื•ืจืงื•ืก.

ื‘ืคื™ืจื•ื˜ ืงื˜ืŸ ื™ื•ืชืจ, ืชื—ื™ืœื” ื ื‘ื—ืŸ ืืช ื”ื”ื™ืงืฃ ื•ื”ืคืจื˜ื™ื ืฉืœ ื”ืื•ืคืŸ ืฉื‘ื• Quarkus ืชื•ืžืš ื‘ืžืžืฉืงื™ API ืฉืœ Spring ื›ื“ื™ ืœื”ืจืื•ืช ืœืžืคืชื—ื™ Spring ื›ื™ืฆื“ ืœื”ืฉืชืžืฉ ื‘-MicroProfile API ื‘ืขื‘ื•ื“ื” ื”ื™ื•ืžื™ื•ืžื™ืช ืฉืœื”ื. ืœืื—ืจ ืžื›ืŸ ื ืกืงื•ืจ ืืช ืžืžืฉืงื™ ื”-API ืฉืœ MicroProfile, ืฉื™ืžื•ืฉื™ื™ื ืขื‘ื•ืจ ืžืคืชื—ื™ Spring ื‘ืขืช ื™ืฆื™ืจืช ืžื™ืงืจื•-ืฉื™ืจื•ืชื™ื.

ืœืžื” ืงื•ื•ืงื•ืก? ืจืืฉื™ืช, ื–ื”ื• ืงื™ื“ื•ื“ ื—ื™, ื›ืœื•ืžืจ, ื˜ืขื™ื ื” ืžื—ื“ืฉ ืื•ื˜ื•ืžื˜ื™ืช ืฉืœ ื›ืœ ืฉื™ื ื•ื™ ื‘-MicroProfile API, Spring API ื•ืžืžืฉืงื™ API ืื—ืจื™ื ืฉืœ Java, ืฉืžืชื‘ืฆืขืช ื‘ืคืงื•ื“ื” ืื—ืช ื‘ืœื‘ื“: mvn quarkus:dev. ืฉื ื™ืช, ื ื—ืฉื‘ ื‘ ื‘ื“ื•ื’ืžื” ืฉืœื ื• ืฉื™ืจื•ืช Person (ื”ืงื•ืžืคื™ืœืฆื™ื” ืžืžืžืฉืงื™ API ืฉืœ Spring, MicroProfile ื•-JPA ืœื‘ื™ื ืืจื™ ื‘ืืžืฆืขื•ืช ืชืžื•ื ืช GraalVM ื”ืžืงื•ืจื™ืช) ืžืชื—ื™ืœ ืชื•ืš 0.055 ืฉื ื™ื•ืช ื‘ืœื‘ื“ ื•ืชื•ืคืก ื›-90 MB ืฉืœ ื–ื™ื›ืจื•ืŸ RAM (RSS) ื‘ื ืงื•ื“ืช ื”ืงืฆื” ืฉืœ ื”ื™ื™ืฉื•ื RESTful. ื™ืชืจื” ืžื›ืš, ื”ืงื•ืžืคื™ืœืฆื™ื” ืฉืœื• ืขืฆืžื” ืžืชื‘ืฆืขืช ื‘ืคืงื•ื“ื” ืื—ืช ื‘ืœื‘ื“: ื—ื‘ื™ืœืช mvn -Pnative.

ืœื ื ืคืจื˜ ืขืœ MicroProfile, ืžืœื‘ื“ ืœืขื–ื•ืจ ืœืžืคืชื—ื™ Spring ืœื”ื‘ื™ืŸ ื›ื™ืฆื“ ื”ื ื™ื›ื•ืœื™ื ืœื”ืฉืชืžืฉ ื‘ืžืžืฉืงื™ Spring API ืขื ืžืžืฉืงื™ API ืฉืœ MicroProfile ื‘-Quarkus.

ืžื›ื•ืœื•ืช ื•-Kubernetes

ื›ื“ื™ ืœืฉืžื•ืจ ืขืœ ืžืืžืจ ื–ื” ืคืฉื•ื˜, ื ืกืงื•ืจ ื›ืืŸ ืจืง ืืช ื”ื”ื™ื‘ื˜ื™ื ื”ื’ื‘ื•ื”ื™ื ืฉืœ ืชืžื™ื›ื”. ืงื•ื‘ืจื ื˜, ื›ื™ ื—ืฉื•ื‘ ืœื”ื‘ื™ืŸ. Quarkus ืžืžื•ืงืžืช ื›ืžื—ืกื ื™ืช Java ืขื‘ื•ืจ Kubernetes, ื”ื™ื ื ื•ืขื“ื” ืœืžื–ืขืจ ืืช ืฆืจื™ื›ืช ื”ื–ื™ื›ืจื•ืŸ ื•ืืช ื–ืžืŸ ื”ืืชื—ื•ืœ ืฉืœ ื™ื™ืฉื•ืžื™ ื•ืฉื™ืจื•ืชื™ Java, ื•ื›ืชื•ืฆืื” ืžื›ืš ืœื”ื’ื“ื™ืœ ืืช ื”ืฆืคื™ืคื•ืช ืฉืœื”ื ื‘ืžืืจื— ื•ืœื”ืคื—ื™ืช ืืช ื”ืขืœื•ื™ื•ืช ื”ื›ื•ืœืœื•ืช.

ื’ื ืงื•ื•ืงื•ืก ืชื•ืžืš ื‘ื™ื™ืฆื•ืจ ืื•ื˜ื•ืžื˜ื™ ืžืฉืื‘ื™ื ื•ื”ืฆืขื•ืช ืฉืœ Kubernetes ืžึทื ื”ึดื™ื’ื•ึผืช ืœืคืจื™ืกื” ื‘ืคืœื˜ืคื•ืจืžื•ืช Kubernetes ื•-Red Hat OpenShift. ื‘ื ื•ืกืฃ, Quarkus ืžื™ื™ืฆืจ ืื•ื˜ื•ืžื˜ื™ืช ืืช ื”ืงื‘ืฆื™ื Dockerfile.jvm (ืืจื™ื–ื” JVM) ื•- Dockerfile.native (ืืจื™ื–ื” ื‘ื™ื ืืจื™ืช ืžืงื•ืจื™ืช) ื”ื“ืจื•ืฉื™ื ืœื™ืฆื™ืจืช ืงื•ื ื˜ื™ื™ื ืจื™ื.

ืœื‘ืกื•ืฃ, ืขืœ ื™ื“ื™ ื”ืชืžืงื“ื•ืช ื‘-Kubernetes ื›ืกื‘ื™ื‘ืช ืคืจื™ืกืช ื”ื™ืขื“, Quarkus ืื™ื ื• ืžืฉืชืžืฉ ื‘ืžืกื’ืจื•ืช Java ื‘ืžืงืจื™ื ื‘ื”ื ืžื™ื•ืฉืžืช ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ื“ื•ืžื” ื‘ืจืžืช ืคืœื˜ืคื•ืจืžืช Kubernetes ืขืฆืžื”. ื˜ื‘ืœื” 1 ืžืกืคืงืช ืžืคื” ืฉืœ ื”ื”ืชืืžื” ื”ืคื•ื ืงืฆื™ื•ื ืœื™ืช ื‘ื™ืŸ Kubernetes ืœื‘ื™ืŸ ืžืกื’ืจื•ืช Java ื˜ื™ืคื•ืกื™ื•ืช ื”ืžืฉืžืฉื•ืช ืžืคืชื—ื™ Spring.

ื˜ื‘ืœื” 1. ืžืคื” ืฉืœ ื”ืชืืžื” ืคื•ื ืงืฆื™ื•ื ืœื™ืช ื‘ื™ืŸ ืžืกื’ืจื•ืช Java ื•-Kubernetes.

ืคื•ื ืงืฆื™ื•ื ืœื™
ืžื’ืฃ ืื‘ื™ื‘ ืžืกื•ืจืชื™
ืงื•ื‘ืจื ื˜

ื’ื™ืœื•ื™ ืฉื™ืจื•ืช
ื™ื•ืจื™ืงื”
DNS

ืชึฐืฆื•ึผืจึธื”
ืชืฆื•ืจืช ืขื ืŸ ืื‘ื™ื‘
ื”ื’ื“ืจืช ืžืคื•ืช/ืกื•ื“ื•ืช

ืื™ื–ื•ืŸ ืขื•ืžืกื™ื
ืกืจื˜ (ืฆื“ ื”ืœืงื•ื—)
ืฉื™ืจื•ืช, ื‘ืงืจ ืฉื›ืคื•ืœ (ืฆื“ ื”ืฉืจืช)

ืงื•ืžืคื™ืœืฆื™ื” ื•ื”ืจืฆื” ืฉืœ ื”ืงื•ื“ ืžื”ื“ื•ื’ืžื”

ื‘ืžืืžืจ ื–ื” ืื ื• ืžืชื™ื™ื—ืกื™ื ืคืจื•ื™ืงื˜ ืœื“ื•ื’ืžื”, ืฉื‘ื• ืžืฉืชืžืฉื™ื ื‘ืžืžืฉืงื™ ื”-API ืฉืœ Spring ื•-MicroProfile ื•ืืคื™ืœื• ื‘ืื•ืชื” ืžื—ืœืงืช Java ื‘ื™ื—ื“. ื”ืงื•ื“ ื‘ื“ื•ื’ืžื” ื–ื• ื ื™ืชืŸ ืœื”ื™ื“ื•ืจ ื•ืœื”ืคืขื™ืœ ืžืฉื•ืจืช ื”ืคืงื•ื“ื”, ืขื™ื™ืŸ ื‘ืงื•ื‘ืฅ README.md ืœืคืจื˜ื™ื.

ืžืžืฉืงื™ API ืฉืœ Spring Framework

ื”ื–ืจืงืช ืชืœื•ืช

Quarkus ืชื•ืžืš ื‘ืžื’ื•ื•ืŸ ืฉืœ ืžืžืฉืงื™ API ืฉืœ ื”ืงืฉืจื™ื ื•ื”ื–ืจืงืช ืชืœื•ืช (CDI). ื•-Spring Dependency Injection (Spring DI) APIs. ืื ืืชื” ืขื•ื‘ื“ ืขื MicroProfile, Java EE ื•ื’'ืงืจื˜ื” EE, ืื– ืืชื” ื›ื‘ืจ ืžื›ื™ืจ ื”ื™ื˜ื‘ ืืช CDI. ืžืฆื“ ืฉื ื™, ืžืคืชื—ื™ Spring ื™ื›ื•ืœื™ื ืœื”ืฉืชืžืฉ ื‘-Quarkus Extension for Spring DI API ื›ื“ื™ ืœื”ืฉื™ื’ ืชืื™ืžื•ืช ืขื Spring DI. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ ื”-API ืฉืœ Spring DI ื ืชืžื›ื™ื ื‘ื˜ื‘ืœื” 2.

ะ’ ืคืจื•ื™ืงื˜ ืžื”ื“ื•ื’ืžื” ืฉืœื ื• ืžืฉืชืžืฉ ื’ื ื‘-CDI ื•ื’ื ื‘ื”ื–ืจืงืช ืงืคื™ืฆื™ื. ืœืžื™ื“ืข ื ื•ืกืฃ ื•ื“ื•ื’ืžืื•ืช ื‘ื ื•ืฉื ื–ื”, ืขื™ื™ืŸ ื‘ืžื“ืจื™ืš Quarkus ื”ื ืงืจื ืžื“ืจื™ืš ืื‘ื™ื‘ DI.

ื˜ื‘ืœื” 2. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ื ืชืžื›ื™ื ืฉืœ Spring DI.

ืชื›ื•ื ื•ืช Spring DI ื ืชืžื›ื•ืช
ื“ื•ื’ืžืื•ืช

ื”ื–ืจืงืช ืงื•ื ืกื˜ืจื•ืงื˜ื•ืจ

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

ื”ื–ืจืงืช ืฉื“ื”
ื—ื•ื˜ื™ ืื•ื˜ื•ืžื˜ื™
ืขืจืš

@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 ืœื”ืฉืชืžืฉ ื‘ืžืžืฉืงื™ Spring Web ื‘ืฉื™ืœื•ื‘ ืขื ืžืžืฉืงื™ API ืฉืœ MicroProfile. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ ื”-API ื”ื ืชืžื›ื™ื ืฉืœ Spring Web ืžืกื•ืคืงื•ืช ื‘ื˜ื‘ืœื” 3, ื•ื ื™ืชืŸ ืœืžืฆื•ื ืžื™ื“ืข ื•ื“ื•ื’ืžืื•ืช ื ื•ืกืคื•ืช ื‘ื ื•ืฉื ื–ื” ื‘ืžื“ืจื™ืš ืฉืœ Quarkus ื”ื ืงืจื ืžื“ืจื™ืš ืื™ื ื˜ืจื ื˜ ืฉืœ ืื‘ื™ื‘.

ื˜ื‘ืœื” 3. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘-Spring Web APIs ื”ื ืชืžื›ื™ื.

ืชื›ื•ื ื•ืช ืื™ื ื˜ืจื ื˜ ื ืชืžื›ื•ืช ืฉืœ ืื‘ื™ื‘
ื“ื•ื’ืžืื•ืช

@ RestController
@ื‘ืงืฉืช ืžื™ืคื•ื™

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

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@RequestParam
@RequestHeader
@MatrixVariable
@ PathVariable
@CookieValue
@ ื‘ืงืฉืช ื’ื•ืฃ
@ ืชื’ื•ื‘ื” ืกื˜ื˜ื•ืก
@ExceptionHandler
@RestControllerAdvice (ื—ืœืงื™)

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

ืื‘ื™ื‘ ื ืชื•ื ื™ื JPA

ืžืฉืชืžืฉื™ MicroProfile ื™ืขืจื™ื›ื• ื’ื ืฉ-Quarkus ืชื•ืžืš ื‘-JPA ื‘ืืžืฆืขื•ืช ORM Hibernate. ื™ืฉ ื’ื ื—ื“ืฉื•ืช ื˜ื•ื‘ื•ืช ืœืžืคืชื—ื™ Spring: Quarkus ืชื•ืžืš ื‘ื”ืขืจื•ืช ื•ื‘ืกื•ื’ื™ื ื ืคื•ืฆื™ื ืฉืœ Spring Data JPA. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ืฉืœ Spring Data JPA ื ืชืžื›ื™ื ื‘ื˜ื‘ืœื” 4.
ะ’ ืคืจื•ื™ืงื˜ ืžื”ื“ื•ื’ืžื” ืฉืœื ื• ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ืฉืœ Spring Data JPA ื•ืžื™ื“ืข ื ื•ืกืฃ ื–ืžื™ืŸ ื‘ืžื“ืจื™ืš Quarkus ืฉื ืงืจื Spring Data JPA Guide.

ื˜ื‘ืœื” 4. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ื ืชืžื›ื™ื ืฉืœ Spring Data JPA.

ืชื›ื•ื ื•ืช Spring Data JPA ื ืชืžื›ื•ืช
ื“ื•ื’ืžืื•ืช

CrudRository

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

Repository
ืžืื’ืจ Jpa
PagingAndSortingRepository

public class PersonRepository extends 

    Repository {

    Person save(Person entity);

    Optional findById(Person entity);
}

ืฉื‘ืจื™ ืžืื’ืจ

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

ืฉื™ื˜ื•ืช ืฉืื™ืœืชื•ืช ื ื’ื–ืจื•ืช

public interface PersonRepository extends CrudRepository {

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

    Boolean existsBookByYearOfBirthBetween(
            Integer start, Integer end);
}

ืฉืื™ืœืชื•ืช ื‘ื”ื’ื“ืจืช ืžืฉืชืžืฉ

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

ืกื•ื‘ืœื ื•ืช ืœืชืงืœื•ืช

ืžื‘ื ื™ื ืœืกื•ื‘ืœื ื•ืช ืชืงืœื•ืช ื—ืฉื•ื‘ื™ื ืžืื•ื“ ืœืžื ื™ืขืช ื›ืฉืœื™ื ืžื“ื•ืจื’ื™ื ื•ืœื™ืฆื™ืจืช ืืจื›ื™ื˜ืงื˜ื•ืจื•ืช ืžื™ืงืจื•-ืฉื™ืจื•ืช ืืžื™ื ื•ืช. ืžืคืชื—ื™ ืงืคื™ืฆื™ื ืžืฉืชืžืฉื™ื ื‘ืžืคืกืงื™ื ืœืกื‘ื™ืœื•ืช ืชืงืœื•ืช ื›ื‘ืจ ืฉื ื™ื ืจื‘ื•ืช. ื”ื™ืกื˜ืจื™ืงืก. ืขื ื–ืืช, Hystrix ืœื ืขื•ื“ื›ื ื” ื‘ืžืฉืš ื–ืžืŸ ืจื‘, ืืš ื”-Fault Tolerance ืฉืœ MicroProfile ืžืชืคืชื—ืช ื›ืขืช ื‘ืื•ืคืŸ ืคืขื™ืœ ื•ืžืื—ื•ืจื™ื” ืžืกืคืจ ืฉื ื™ื ืฉืœ ืฉื™ืžื•ืฉ ื‘ื™ื™ืฆื•ืจ. ืœื›ืŸ, ื›ื“ื™ ืœืฉืคืจ ืืช ืžื”ื™ืžื ื•ืช ื”ืฉื™ืจื•ืชื™ื ื‘-Quarkus, ืžื•ืžืœืฅ ืœื”ืฉืชืžืฉ ื‘ืžืžืฉืงื™ ื”-API ืฉืœ MicroProfile Fault Tolerance, ืฉื“ื•ื’ืžืื•ืช ืฉืœื”ื ื ืžืฆืื•ืช ื‘ืฉื™ืžื•ืฉ ื‘ื˜ื‘ืœื” 5. ืœืžื™ื“ืข ื ื•ืกืฃ ืขืœ ื›ืš, ืขื™ื™ืŸ ื‘ืžื“ืจื™ืš ืฉืœ Quarkus ืžื“ืจื™ืš ืกื•ื‘ืœื ื•ืช ืชืงืœื•ืช.

ื˜ื‘ืœื” 5. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ื ืชืžื›ื™ื ืฉืœ MicroProfile Fault Tolerance.

ืชื›ื•ื ื•ืช ืกื•ื‘ืœื ื•ืช ืชืงืœื•ืช ืฉืœ MicroProfile
ืชื™ืื•ืจ
ื“ื•ื’ืžืื•ืช

@ืืกื™ื ื›ืจื•ื ื™

ื‘ื™ืฆื•ืข ื”ื™ื’ื™ื•ืŸ ื‘ืฉืจืฉื•ืจ ื ืคืจื“

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

@ืžื—ื™ืฆื”

ื”ื’ื‘ืœ ืืช ืžืกืคืจ ื”ื‘ืงืฉื•ืช ื‘ื•-ื–ืžื ื™ืช

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

@CircuitBreaker

ื˜ื™ืคื•ืœ ื—ื›ื ื‘ื›ืฉืœื™ื ื•ื”ืชืื•ืฉืฉื•ืช ืžืชืงืœื•ืช

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

@ืœืกื’ืช

ืงืจื™ืื” ืœื”ื™ื’ื™ื•ืŸ ื—ืœื•ืคื™ ื‘ืžืงืจื” ืฉืœ ื›ืฉืœ

@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(); //...
}

ืฉื™ืจื•ืชื™ ื‘ื“ื™ืงื” (ืฉื™ืจื•ืช ื‘ืจื™ืื•ืช)

ืคืœื˜ืคื•ืจืžื•ืช Kubernetes ืขื•ืงื‘ื•ืช ืื—ืจ ืชืงื™ื ื•ืช ื”ืžื›ื•ืœื•ืช ื‘ืืžืฆืขื•ืช ืฉื™ืจื•ืชื™ื ืžื™ื•ื—ื“ื™ื. ื›ื“ื™ ืœืืคืฉืจ ืœืคืœื˜ืคื•ืจืžื” ื”ื‘ืกื™ืกื™ืช ืœื ื˜ืจ ืฉื™ืจื•ืชื™ื, ืžืคืชื—ื™ Spring ืžืฉืชืžืฉื™ื ื‘ื“ืจืš ื›ืœืœ ื‘-HealthIndicator ืžื•ืชืื ืื™ืฉื™ืช ื•ื‘-Spring Boot Actuator. ื‘-Quarkus, ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช ื‘ืืžืฆืขื•ืช MicroProfile Health, ืืฉืจ ื›ื‘ืจื™ืจืช ืžื—ื“ืœ ืžื‘ืฆืขืช ื‘ื“ื™ืงืช ื—ื™ื•ื ื™ื•ืช, ืืš ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ื–ืืช ื›ืš ืฉืชื‘ื“ื•ืง ื‘ื•-ื–ืžื ื™ืช ืืช ื”ืคืขื™ืœื•ืช ื•ื”ืžื•ื›ื ื•ืช. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ ื”-API ื”ื ืชืžื›ื™ื ืฉืœ MicroProfile Health ืžืกื•ืคืงื•ืช ื‘ื˜ื‘ืœื” 6, ื•ืžื™ื“ืข ื ื•ืกืฃ ืžืกื•ืคืง ื‘ืžื“ืจื™ืš ืฉืœ Quarkus ืžื“ืจื™ืš ื‘ืจื™ืื•ืช.

ื˜ื‘ืœื” 6: ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ื ืชืžื›ื™ื ืฉืœ MicroProfile Health.

ืชื›ื•ื ื•ืช MicroProfile Health
ืชื™ืื•ืจ
ื“ื•ื’ืžืื•ืช

@ื—ื™ื•ืช

ืืชื—ื•ืœ ืžื—ื“ืฉ ืฉืœ ื”ืคืœื˜ืคื•ืจืžื” ื ื›ืฉืœ ื™ื™ืฉื•ืžื™ ืžื›ื•ืœื•ืช
ื ืงื•ื“ืช ืกื™ื•ื:
ืžืืจื—:8080/health/live

@Liveness
public class MyHC implements HealthCheck {
  public HealthCheckResponse call() {

   ...
   return HealthCheckResponse
     .named("myHCProbe")
     .status(ready ? true:false)
     .withData("mydata", data)
     .build();  
}

@ื ึฐื›ื•ึนื ื•ึผืช

ื”ืคืœื˜ืคื•ืจืžื” ืœื ืชืฉืœื— ืชืขื‘ื•ืจื” ืœื™ื™ืฉื•ืžื™ื ื”ืžื›ื™ืœื™ื ืื ื”ื™ื ืœื ืžื•ื›ื ื”
ื ืงื•ื“ืช ืกื™ื•ื:
ืžืืจื—:8080/health/ready

@Readiness
public class MyHC implements HealthCheck {
  public HealthCheckResponse call() {

   ...
   return HealthCheckResponse
     .named("myHCProbe")
     .status(live ? true:false)
     .withData("mydata", data)
     .build();  
}

ืžื“ื“ื™ื

ื™ื™ืฉื•ืžื™ื ืžืกืคืงื™ื ืžื“ื“ื™ื ืœืžื˜ืจื•ืช ืชืคืขื•ืœื™ื•ืช (ื›ื“ื™ ืœืคืงื— ืขืœ SLAs ื‘ื™ืฆื•ืขื™ื) ืื• ืœืžื˜ืจื•ืช ืœื ืชืคืขื•ืœื™ื•ืช (SLAs ืขืกืงื™ื•ืช). ืžืคืชื—ื™ Spring ืžืกืคืงื™ื ืžื“ื“ื™ื ื‘ืืžืฆืขื•ืช Spring Boot Actuator ื•ืžื™ืงืจื•ืžื˜ืจ. ื‘ืชื•ืจื•, Quarkus ืžืฉืชืžืฉ ื‘-MicroProfile Metrics ื›ื“ื™ ืœืกืคืง ืžื“ื“ื™ ื‘ืกื™ืก (JVM ื•ืžืขืจื›ืช ื”ืคืขืœื”), ืžื“ื“ื™ ืกืคืงื™ื (Quarkus) ื•ืžื“ื“ื™ ื™ื™ืฉื•ืžื™ื. MicroProfile Metrics ื“ื•ืจืฉ ืฉื”ื™ื™ืฉื•ื ืชื•ืžืš ื‘ืชื‘ื ื™ื•ืช ืคืœื˜ ืฉืœ JSON ื•-OpenMetrics (Prometheus). ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘-MicroProfile Metrics API ื ื™ืชื ื•ืช ื‘ื˜ื‘ืœื” 7.

ะ’ ืคืจื•ื™ืงื˜ ืžื”ื“ื•ื’ืžื” ืฉืœื ื• ืžื“ื“ื™ MicroProfile ืžืฉืžืฉื™ื ื›ื“ื™ ืœืกืคืง ืžื“ื“ื™ ื™ื™ืฉื•ืžื™ื. ืœืžื™ื“ืข ื ื•ืกืฃ, ืขื™ื™ืŸ ื‘ืžื“ืจื™ืš ืฉืœ Quarkus ืžื“ืจื™ืš ืžื“ื“ื™ื.

ื˜ื‘ืœื” 7. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ืฉืœ MicroProfile Metrics.

ืชื›ื•ื ื•ืช ืžื“ื“ื™ MicroProfile
ืชื™ืื•ืจ
ื“ื•ื’ืžืื•ืช

@ื ืกืคื•ืจ

ืžืฆื™ื™ืŸ ืžื•ื ื” ืžื•ื ื” ืฉืกื•ืคืจ ืืช ืžืกืคืจ ื”ืคืขืžื™ื ืฉื ืงืจื ืื•ื‘ื™ื™ืงื˜ ืžื•ืขืจ

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

@ConcurrentGauge

ืžืฆื™ื™ืŸ ืžื“ ืฉืกื•ืคืจ ืืช ืžืกืคืจ ื”ืงืจื™ืื•ืช ื‘ืžืงื‘ื™ืœ ืœืื•ื‘ื™ื™ืงื˜ ืžื•ืขืจ

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

@ืžึทื“

ืžืฆื™ื™ืŸ ื—ื™ื™ืฉืŸ ืžื“ ืฉืžื•ื“ื“ ืืช ื”ืขืจืš ืฉืœ ืื•ื‘ื™ื™ืงื˜ ืžื•ืขืจ

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

@ืžื“ื•ื“

ืžืฆื™ื™ืŸ ื—ื™ื™ืฉืŸ ืžื“ ื”ืžื ื˜ืจ ืืช ืชื“ื™ืจื•ืช ื”ืฉื™ื—ื” ืฉืœ ืื•ื‘ื™ื™ืงื˜ ืžื•ืขืจ

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

ืžื“ื“ื™ื ื ืงื•ื“ื•ืช ืงืฆื”

ืžื“ื“ื™ ืืคืœื™ืงืฆื™ื” localhost:8080/ืžื˜ืจื™ื/ืืคืœื™ืงืฆื™ื”
ืžื“ื“ื™ื ื‘ืกื™ืกื™ื™ื localhost:8080/metrics/base
ืžื“ื“ื™ ืกืคืงื™ื localhost:8080/ืžื˜ืจื™ื/ืกืคืง
ื›ืœ ื”ืžื“ื“ื™ื localhost:8080/ืžื˜ืจื™ื

MicroProfile Rest Client

ืฉื™ืจื•ืชื™ ืžื™ืงืจื• ืžืกืคืงื™ื ืœืขืชื™ื ืงืจื•ื‘ื•ืช ื ืงื•ื“ื•ืช ืงืฆื” RESTful ืฉื“ื•ืจืฉื•ืช ืžืžืฉืงื™ API ืชื•ืืžื™ื ืฉืœ ืœืงื•ื— ืœืขื‘ื•ื“ ืื™ืชื. ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ื ืงื•ื“ื•ืช ืงืฆื” ืฉืœ RESTful, ืžืคืชื—ื™ Spring ืžืฉืชืžืฉื™ื ื‘ื“ืจืš ื›ืœืœ ื‘-RestTemplate. Quarkus ืžืฆื™ืขื” ืžืžืฉืงื™ API ืฉืœ MicroProfile Rest Client ื›ื“ื™ ืœืคืชื•ืจ ื‘ืขื™ื” ื–ื•, ื•ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ื”ืŸ ื ื™ืชื ื•ืช ื‘ื˜ื‘ืœื” 8.

ะ’ ืคืจื•ื™ืงื˜ ืžื”ื“ื•ื’ืžื” ืฉืœื ื• ื”ืฉื™ืžื•ืฉ ื‘ื ืงื•ื“ื•ืช ืงืฆื” RESTful ื ืขืฉื” ื‘ืืžืฆืขื•ืช MicroProfile Rest Client. ืžื™ื“ืข ื ื•ืกืฃ ื•ื“ื•ื’ืžืื•ืช ื‘ื ื•ืฉื ื–ื” ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืžื“ืจื™ืš ืฉืœ Quarkus ืžื“ืจื™ืš ืœืงื•ื— ืžื ื•ื—ื”.

ื˜ื‘ืœื” 8. ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืžืžืฉืงื™ API ืฉืœ MicroProfile Rest Client.

ืชื›ื•ื ื•ืช ืœืงื•ื— MicroProfile Rest
ืชื™ืื•ืจ
ื“ื•ื’ืžืื•ืช

@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, ื‘ื“ืงื ื• ื›ื™ืฆื“ ืœื”ืฉืชืžืฉ ื‘ืžืžืฉืงื™ Spring API ืขื ืžืžืฉืงื™ API ืฉืœ MicroProfile ื‘-Quarkus ื›ื“ื™ ืœืคืชื— ืฉื™ืจื•ืชื™ ืžื™ืงืจื• ืฉืœ Java ื•ืœืื—ืจ ืžื›ืŸ ืœืงืžืคืœ ืื•ืชื ืœืงื•ื“ ื‘ื™ื ืืจื™ ืžืงื•ืจื™ ืฉื—ื•ืกืš ืžืื•ืช ืžื’ื”-ื‘ื™ื™ื˜ ืฉืœ ื–ื™ื›ืจื•ืŸ RAM ื•ืžืฉื™ืง ื‘- ืขื ื™ื™ืŸ ืฉืœ ืืœืคื™ื•ืช ืฉื ื™ื•ืช.

ื›ืคื™ ืฉื›ื‘ืจ ื”ื‘ื ืช, ืžื™ื“ืข ื ื•ืกืฃ ืขืœ ืชืžื™ื›ื” ื‘ืžืžืฉืงื™ ื”-Spring ื•-MicroProfile, ื›ืžื• ื’ื ืžื™ื“ืข ืฉื™ืžื•ืฉื™ ืจื‘ ืื—ืจ, ื ื™ืชืŸ ืœืžืฆื•ื ื‘- ืžื“ืจื™ื›ื™ื ืฉืœ Quarkus.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”