Quarkus 如何结合 MicroProfile 和 Spring

大家好,这是 Quarkus 系列的第三篇文章!

Quarkus 如何结合 MicroProfile 和 Spring

在开发Java微服务时,人们常常认为: Eclipse 微配置文件 и 春季靴 是单独且独立的 API。 默认情况下,程序员倾向于使用他们已经习惯的 API,因为学习新框架和运行时组件需要花费大量时间。 今天我们将尝试简化一些流行的开发 面向 Spring 开发人员的 MicroProfile API 并向您展示如何同时使用 Spring API 和新的有用功能 夸库斯.

更详细地说,我们将首先了解 Quarkus 如何支持 Spring API 的范围和细节,以向 Spring 开发人员展示如何在日常工作中使用 MicroProfile API。 然后我们将介绍 MicroProfile API,这对于 Spring 开发人员创建微服务时非常有用。

为什么是夸库斯? 首先,这是实时编码,即自动重新加载 MicroProfile API、Spring API 和其他 Java API 中的任何更改,只需一个命令即可执行:mvn quarkus:dev。 其次,考虑到 在我们的例子中 Person 服务(使用本机 GraalVM 映像从 Spring、MicroProfile 和 JPA API 编译为二进制文件)只需 0.055 秒即可启动,并在 RESTful 应用程序端点上占用约 90 MB RAM (RSS)。 此外,它的编译本身只需一个命令即可执行:mvn package -Pnative。

我们不会详细介绍 MicroProfile,只是帮助 Spring 开发人员了解如何在 Quarkus 中将 Spring API 与 MicroProfile API 结合使用。

容器和 Kubernetes

为了使本文简单明了,我们在这里仅介绍支持的高级方面。 Kubernetes,因为理解很重要。 Quarkus 定位为 Kubernetes 的 Java 堆栈,旨在最大限度地减少 Java 应用程序和服务的内存消耗和启动时间,从而提高其在主机上的密度并降低总体成本。

夸库斯也 支持自动生成 Kubernetes 资源和优惠 导游 用于在 Kubernetes 和 Red Hat OpenShift 平台上部署。 此外,Quarkus 还会自动生成创建容器所需的 Dockerfile.jvm(JVM 打包)和 Dockerfile.native(原生二进制打包)文件。

最后,通过专注于 Kubernetes 作为目标部署环境,Quarkus 在 Kubernetes 平台本身级别实现类似功能的情况下不使用 Java 框架。 表 1 提供了 Kubernetes 与 Spring 开发人员使用的典型 Java 框架之间的功能对应关系图。

表 1. Java 框架和 Kubernetes 之间的功能对应关系图。

实用
传统的 Spring Boot
Kubernetes

服务发现
尤里卡
DNS

配置
春云配置
配置映射/秘密

负载均衡
功能区(客户端)
服务,复制控制器(服务器端)

编译并运行示例中的代码

在这篇文章中我们提到 示例项目,其中 Spring 和 MicroProfile API 甚至相同的 Java 类一起使用。 本示例中的代码可以从命令行编译并运行,详细信息请参阅 README.md 文件。

Spring 框架 API

依赖注入

Quarkus 支持一系列 上下文和依赖注入 (CDI) API 和 Spring 依赖注入 (Spring DI) API。 如果您正在使用 MicroProfile, Java EE 和 Jakarta EE,那么你对CDI已经非常熟悉了。 另一方面,Spring 开发人员可以使用 Quarkus Extension for Spring DI API 来实现与 Spring DI 的兼容。 表 2 中给出了使用受支持的 Spring DI API 的示例。

В 我们的示例中的项目 同时使用 CDI 和 Spring 依赖注入。 有关此主题的更多信息和示例,请参阅 Quarkus 指南,名为 Spring DI 指南.

表 2. 使用受支持的 Spring DI API 的示例。

支持的 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 作为主要 Web 编程模型。 Spring 开发人员将对 Quarkus 最近对 Spring Web API(特别是 REST 接口)的支持感到满意。 与 Spring DI 类似,Spring Web API 支持的主要目标是使 Spring 开发人员能够将 Spring Web API 与 MicroProfile API 结合使用。 表 3 中提供了如何使用受支持的 Spring Web API 的示例,有关此主题的更多信息和示例可以在名为“Quarkus”的 Quarkus 教程中找到。 春季网络指南.

表 3. 使用受支持的 Spring Web API 的示例。

支持的 Spring Web 功能
Примеры

@休息控制器
@RequestMapping

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

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@RequestParam
@RequestHeader
@MatrixVariable
@路径变量
@CookieValue
@RequestBody
@ResponseStatus
@ExceptionHandler
@RestControllerAdvice(部分)

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

弹簧数据 JPA

MicroProfile 用户还会欣赏 Quarkus 使用 Hibernate ORM 支持 JPA。 对于 Spring 开发人员来说还有个好消息:Quarkus 支持常见的 Spring Data JPA 注释和类型。 表 4 中给出了使用受支持的 Spring Data JPA API 的示例。
В 我们的示例中的项目 使用 Spring Data JPA API,更多信息可在 Quarkus 教程中找到,名为 Spring Data JPA 指南.

表 4. 使用受支持的 Spring Data JPA API 的示例。

支持的 Spring Data JPA 功能
Примеры

Crud存储库

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

存储库
存储库
分页和排序存储库

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

MicroProfile API

容错能力

容错构造对于防止级联故障和创建可靠的微服务架构非常重要。 Spring 开发人员多年来一直使用断路器来实现容错。 海斯特里克斯。 不过,Hystrix 已经很久没有更新了,但 MicroProfile 的容错现在正在积极开发,并且已经有几年的生产使用了。 因此,为了提高Quarkus中服务的可靠性,建议使用MicroProfile容错API,其示例如表5所示。更多信息请参见Quarkus手册 容错指南.

表 5. 使用受支持的 MicroProfile 容错 API 的示例。

MicroProfile 容错功能
使用说明
Примеры

@异步

在单独的线程中执行逻辑

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

@舱壁

限制同时请求的数量

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

@断路器

智能故障处理和故障恢复

@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 重试

请求失败重试

@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 来完成,它默认执行活性检查,但可以配置为同时检查活性和就绪性。 表 6 中提供了如何使用受支持的 MicroProfile Health API 的示例,Quarkus 手册中提供了更多信息 健康指南.

表 6:支持的 MicroProfile Health API 的使用示例。

MicroProfile 健康功能
使用说明
Примеры

@活跃度

平台重新启动失败的容器化应用程序
终点:
主持人:8080/健康/直播

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

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

@准备就绪

如果尚未准备好,平台不会向容器化应用程序发送流量
终点:
主机:8080/健康/就绪

@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) 输出格式。 表 7 中给出了使用 MicroProfile Metrics API 的示例。

В 我们的示例中的项目 MicroProfile Metrics 用于提供应用程序指标。 有关更多信息,请参阅 Quarkus 手册 指标指南.

表 7. 使用 MicroProfile Metrics API 的示例。

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

指标端点

应用指标 本地:8080/指标/应用程序
基本指标 本地:8080/指标/基础
供应商指标 本地:8080/指标/供应商
所有指标 本地:8080/指标

MicroProfile Rest 客户端

微服务通常提供需要相应客户端 API 才能使用的 RESTful 端点。 要使用 RESTful 端点,Spring 开发人员通常使用 RestTemplate。 Quarkus 提供了 MicroProfile Rest Client API 来解决这个问题,表 8 中给出了其使用示例。

В 我们的示例中的项目 RESTful 端点的使用是通过 MicroProfile Rest Client 完成的。 有关此主题的更多信息和示例可以在 Quarkus 手册中找到 休息客户指南.

表 8. 使用 MicroProfile Rest Client API 的示例。

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 开发人员,我们快速了解了如何在 Quarkus 中使用 Spring API 和 MicroProfile API 来开发 Java 微服务,然后将它们编译为本机二进制代码,从而节省数百兆的 RAM 并在几毫秒的事情。

正如您已经了解的,有关 Spring 和 MicroProfile API 支持的更多信息,以及许多其他有用的信息,可以在 夸库斯手册.

来源: habr.com

添加评论