Reactive Infrastructure
本部分涵盖使用 Spring Vault 的响应式编程支持的基本信息。
What is Reactive Programming?
简单地说,响应式编程是关于非阻塞应用程序的,这些应用程序是异步的、事件驱动的,并且需要少量的线程才能垂直扩展(例如在 JVM 内),而不是水平扩展(例如通过集群)。
反应式应用程序的一个关键方面是背压的概念,这是一个机制,以确保生产者不会压垮消费者。例如,当 HTTP 连接太慢时,从数据库延伸到 HTTP 响应的反应式组件管道中的数据仓库也可以减慢速度或完全停止,直到网络容量释放出来。
Reactive Vault Client
Spring Vault 的反应式客户端支持构建在 composable authentication steps 和 Spring 的函数式 WebClient
之上,通过 Reactor Netty 或 Jetty,它们都具有完全非阻塞的事件驱动的 HTTP 客户端。
它公开 VaultTokenSupplier
作为 VaultToken
的供应商以验证 HTTP 请求,并公开 ReactiveVaultOperations
作为主要入口点。VaultEndpoint
、ClientOptions
和 SSL 的核心配置在各种客户端实现中重复使用。
类 ReactiveVaultTemplate
,位于包 org.springframework.vault.core
中,是 Spring 反应式 Vault 支持的中心类,提供了一组丰富特性来与 Vault 交互。模板提供了读取、写入和删除 Vault 中数据的便利操作,并在域对象和 Vault 数据之间提供映射。
配置后, |
Vault 文档和域类之间的映射是通过委派到 WebClient
及其编解码器来完成的。
ReactiveVaultTemplate
类实现了 ReactiveVaultOperations
接口。尽可能地,ReactiveVaultOperations
上的方法以 Vault API 上的方法命名,使得 API 对习惯于使用 API 和 CLI 的现有 Vault 开发者来说很熟悉。例如,你会找到诸如“write”、“delete”和“read”这样的方法。设计目标是尽可能轻松地在 Vault API 和 ReactiveVaultOperations
之间进行转换。两个 API 之间的一个主要区别是 ReactiveVaultOperations
可以传递域对象而不是 JSON 键值对。
引用 |
ReactiveVaultTemplate
中明确未公开的功能,你可以使用几个 execute 回调方法之一来访问底层 API。execute 回调将为你提供对 WebClient
对象的引用。请参阅 Execution Callbacks 部分以了解更多信息。
现在,让我们来看一个示例,了解如何在 Spring 容器的上下文中使用 Vault。
Registering and configuring Spring Vault beans
使用 Spring Vault 不需要 Spring 上下文。但是,在受管上下文中注册的 ReactiveVaultTemplate
和 VaultTokenSupplier
的实例将参与 Spring IoC 容器提供的 {spring-framework-docs}core.html#beans-factory-nature[生命周期事件]。这有助于在应用程序关闭时释放活动 Vault 会话。您还可以受益于在整个应用程序中重复使用相同的 ReactiveVaultTemplate
实例。
Spring Vault 带有一个支持配置类,该类提供了在 Spring 上下文中使用的 bean 定义。应用程序配置类通常从 AbstractVaultConfiguration
扩展,并且需要提供特定于环境的附加详细信息。
从 AbstractVaultConfiguration
扩展需要实现` VaultEndpoint vaultEndpoint()` 和 ClientAuthentication clientAuthentication()
方法。
@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://localhost:8200 。 |
2 | 此示例使用 TokenAuthentication 快速入门。请参阅 [vault.core.authentication] 了解受支持的身份验证方法的详细信息。 |
Session Management
Spring Vault 需要一个令牌来验证 Vault 请求。请参阅 [vault.core.authentication] 中关于验证的详细信息。反应式客户端需要一个非阻塞的令牌供应商,其协定在 VaultTokenSupplier
中定义。令牌可以是静态的,也可以通过 declared authentication flow 获得。Vault 登录不应该发生在每次验证的 Vault 交互中,但会话令牌应该在会话中保持。这个方面是由实现 ReactiveSessionManager
(如 ReactiveLifecycleAwareSessionManager
)的会话管理器处理的。
Execution callbacks
所有 Spring 模板类的一个共同设计特性是,所有功能都被路由到其中一个模板 execute 回调方法。这有助于确保执行所需的异常和任何资源管理都保持一致。虽然在 JDBC 和 JMS 的情况下比在 Vault 中更需要这样,但它仍然提供了一个访问和记录发生的地方。因此,使用 execute 回调是访问 Vault API 以执行我们尚未 ReactiveVaultTemplate
上的方法公开的非常用操作的首选方法。
这里列出了一些 execute 回调方法。
-
<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);
});