跳到主要内容
版本:4.1.0

响应式基础架构

Doubao 中英对照 Reactive Infrastructure

本节介绍使用 Spring Vault 的响应式编程支持的基础信息。

什么是响应式编程?​

通俗地说,响应式编程是关于非阻塞的应用程序,这些应用程序是异步和事件驱动的,并且需要少量线程进行垂直扩展(即在 JVM 内),而不是水平扩展(即通过集群)。

响应式应用程序的一个关键方面是背压的概念,这是一种确保生产者不会压垮消费者的机制。例如,在从数据库延伸到 HTTP 响应的响应式组件管道中,当 HTTP 连接太慢时,数据仓库也可以减慢或完全停止,直到网络容量释放。

响应式 Vault Client​

Spring Vault 的响应式客户端支持构建在可组合的认证步骤和 Spring Vault 的函数式 ReactiveVaultClient 之上,后者具有完全非阻塞、事件驱动的 HTTP 客户端。

它暴露 VaultTokenSupplier 作为 VaultToken 的提供者以认证 HTTP 请求,并将 ReactiveVaultOperations 作为主要入口点。VaultEndpoint、ClientOptions 和 SSL 的核心配置在各种客户端实现之间复用。

类 ReactiveVaultTemplate 位于包 org.springframework.vault.core 中,是 Spring 响应式 Vault 支持的核心类,提供了丰富的功能集来与 Vault 交互。该模板提供了在 Vault 中读取、写入和删除数据的便捷操作,并在你的领域对象和 Vault 数据之间提供映射。

备注

一旦配置完成,ReactiveVaultTemplate 就是线程安全的,可以在多个实例之间复用。

Vault 文档与领域类之间的映射通过委托给 WebClient 及其 codec 完成。

ReactiveVaultTemplate 类实现了接口 ReactiveVaultOperations。在尽可能的范围内,ReactiveVaultOperations 上的方法以 Vault API 上可用的方法命名,以使 API 对熟悉 API 和 CLI 的现有 Vault 开发人员熟悉。例如,你会找到 "write"、"delete" 和 "read" 等方法。设计目标是尽可能轻松地在 Vault API 和 ReactiveVaultOperations 之间切换。两种 API 之间的一个主要区别是,ReactiveVaultOperations 可以传递领域对象而不是 JSON 键值对。

ReactiveVaultTemplate 中使用的路径(以及从那里可访问的接口)被视为相对于 VaultEndpoint。完全限定的 URI 路径可以在已认证的上下文中用于访问 Vault 集群成员。为防止不希望的全 URI 访问,请确保在将路径传递给 ReactiveVaultTemplate 之前对其进行清理。

备注

引用 ReactiveVaultTemplate 实例上的操作的首选方式是通过其接口 ReactiveVaultOperations。

对于 ReactiveVaultTemplate 未明确暴露的功能,你可以使用多个执行回调方法之一来访问底层 API。执行回调将为你提供对 WebClient 对象的引用。有关更多信息,请参阅 执行回调 部分。

现在让我们看看如何在 Spring 容器上下文中使用 Vault 的示例。

注册和配置 Spring Vault beans​

使用 Spring Vault 不需要 Spring Context。但是,在受管上下文中注册的 ReactiveVaultTemplate 和 VaultTokenSupplier 实例将参与 Spring IoC 容器提供的生命周期事件。这对于在应用程序关闭时释放活动的 Vault 会话很有用。你还可以受益于在你的应用程序中复用同一个 ReactiveVaultTemplate 实例。

Spring Vault 附带一个支持配置类,用于在 Spring 上下文中提供 bean 定义。应用程序配置类通常继承自 AbstractVaultConfiguration,并且需要提供特定于环境的额外细节。

继承自 AbstractVaultConfiguration 需要实现 VaultEndpoint vaultEndpoint() 和 ClientAuthentication clientAuthentication() 方法。

示例 1:使用基于 Java 的 bean 元数据注册 Spring Vault 对象

@Configuration
public class AppConfig extends AbstractReactiveVaultConfiguration {

/**
* Specify an endpoint for connecting to Vault.
*/
@Override
public VaultEndpoint vaultEndpoint() {
return new VaultEndpoint(); 1
}

/**
* Configure a client authentication.
* Please consider a more secure authentication method
* for production use.
*/
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication("…"); 2
}
}

会话管理​

Spring Vault 需要一个令牌来认证 Vault 请求。有关认证的详细信息,请参阅 [vault.core.authentication]。响应式客户端需要一个非阻塞的令牌提供者,其契约定义在 VaultTokenSupplier 中。令牌可以是静态的,也可以通过声明的认证流程获得。Vault 登录不应在每次已认证的 Vault 交互时发生,而应将会话令牌保持在会话期间。这一方面由实现 ReactiveSessionManager 的会话管理器处理,例如 ReactiveLifecycleAwareSessionManager。

执行回调​

所有 Spring 模板类的一个常见设计特性是,所有功能都被路由到模板的执行回调方法之一。这有助于确保可能需要的异常和任何资源管理都被一致地执行。虽然这在 JDBC 和 JMS 的情况下比在 Vault 的情况下有更大的需求,但它仍然为访问和日志记录提供了一个单一的位置。因此,使用执行回调是访问 Vault API 以执行我们未在 ReactiveVaultTemplate 上暴露为方法的非常规操作的首选方式。

以下是执行回调方法的列表。

  • <T> T doWithVault (Function<WebClient, ? extends T> clientCallback) 组合给定 WebClient 的响应式序列,允许在没有会话上下文的情况下与 Vault 交互。
  • <T> T doWithSession (Function<WebClient, ? extends T> clientCallback) 组合给定 WebClient 的响应式序列,允许在已认证的会话中与 Vault 交互。

下面是一个使用回调初始化 Vault 的示例:

reactiveVaultOperations.doWithVault(webClient -> {

return webClient.put()
.uri("sys/init")
.syncBody(request)
.retrieve()
.toEntity(VaultInitializationResponse.class);
});