响应式基础设施

本节涵盖使用 Spring Vault 实现响应式编程支持的基本信息。

什么是响应式编程?

简单来说,响应式编程是指非阻塞应用程序,它们是异步的、事件驱动的,并且需要少量线程才能垂直(即在 JVM 内)而不是水平(即通过集群)扩展。

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

响应式 Vault 客户端

Spring Vault 的响应式客户端支持构建在可组合身份验证步骤和 Spring 的函数式 WebClient(通过 Reactor Netty 或 Jetty)之上,它们都具有完全非阻塞、事件驱动的 HTTP 客户端。

它公开了 VaultTokenSupplier 作为 VaultToken 的提供者以进行 HTTP 请求身份验证,以及 ReactiveVaultOperations 作为主要入口点。VaultEndpointClientOptionsSSL 的核心配置在各种客户端实现中重用。

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

配置完成后,ReactiveVaultTemplate 是线程安全的,可以在多个实例之间重用。

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

ReactiveVaultTemplate 类实现了 ReactiveVaultOperations 接口。尽可能地,ReactiveVaultOperations 上的方法名称与 Vault API 上可用的方法名称一致,以便熟悉 API 和 CLI 的现有 Vault 开发人员熟悉该 API。例如,您会找到“write”、“delete”和“read”等方法。设计目标是尽可能简化 Vault API 和 ReactiveVaultOperations 之间的转换。这两个 API 之间的主要区别在于 ReactiveVaultOperations 可以传递领域对象而不是 JSON 键值对。

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

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

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

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

注册和配置 Spring Vault bean

使用 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)
    }
}
1 创建一个新的 VaultEndpoint,它默认指向 https://:8200
2 此示例使用 TokenAuthentication 以快速入门。有关支持的身份验证方法的详细信息,请参阅 [vault.core.authentication]

会话管理

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);
});
© . This site is unofficial and not affiliated with VMware.