跳到主要内容

响应式基础设施

DeepSeek V3 中英对照 Reactive Infrastructure

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

什么是响应式编程?

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

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

响应式 Vault 客户端

Spring Vault 的响应式客户端支持建立在可组合的认证步骤和 Spring 的功能性 WebClient 之上,通过 Reactor Netty 或 Jetty 实现,这些组件都具备完全非阻塞、事件驱动的 HTTP 客户端特性。

它暴露了 VaultTokenSupplier 作为 VaultToken 的供应者,用于认证 HTTP 请求,并将 ReactiveVaultOperations 作为主要入口点。VaultEndpointClientOptionsSSL 的核心配置在各种客户端实现中被复用。

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

备注

一旦配置完成,ReactiveVaultTemplate 是线程安全的,并且可以在多个实例中重复使用。

Vault 文档与领域类之间的映射是通过委托给 WebClient 及其编解码器来完成的。

ReactiveVaultTemplate 类实现了 ReactiveVaultOperations 接口。在尽可能的情况下,ReactiveVaultOperations 上的方法命名与 Vault API 上的方法保持一致,以便让熟悉 Vault API 和 CLI 的开发者能够轻松上手。例如,你会找到诸如 "write"、"delete" 和 "read" 这样的方法。设计目标是尽可能简化从使用 Vault API 到 ReactiveVaultOperations 的过渡。这两个 API 之间的一个主要区别是,ReactiveVaultOperations 可以传递领域对象,而不是 JSON 键值对。

备注

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

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

现在让我们来看一些在 Spring 容器中使用 Vault 的示例。

注册和配置 Spring Vault beans

使用 Spring Vault 并不需要 Spring 上下文。然而,在托管上下文中注册的 ReactiveVaultTemplateVaultTokenSupplier 实例将参与由 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
}
}
java

会话管理

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

执行回调

所有 Spring 模板类的一个常见设计特性是,所有功能都被路由到模板的 execute 回调方法之一。这有助于确保异常和任何可能需要的资源管理以一致的方式执行。虽然这在 JDBC 和 JMS 的情况下比在 Vault 中更为必要,但它仍然为访问和日志记录提供了一个单一的位置。因此,使用 execute 回调是访问 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);
});
java