響應式基礎設施

本節介紹 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 的現有 Vault 開發者熟悉此 API。例如,您會找到諸如 “write”、“delete” 和 “read” 之類的方法。設計目標是使 Vault API 與 ReactiveVaultOperations 之間的轉換儘可能容易。兩個 API 之間的一個主要區別是,ReactiveVaultOperations 可以傳遞領域物件,而不是 JSON 鍵值對。

引用 ReactiveVaultTemplate 例項上操作的首選方式是透過其介面 ReactiveVaultOperations

對於 ReactiveVaultTemplate 未明確暴露的功能,您可以使用幾種執行回撥方法之一來訪問底層 API。執行回撥將為您提供一個 WebClient 物件的引用。請參閱執行回撥部分了解更多資訊。

現在讓我們看看如何在 Spring 容器的上下文中使用 Vault 的示例。

註冊和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring Context。然而,在託管上下文內註冊的 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);
});