使用 Keycloak 25 保持使用者登入狀態

2024 年 6 月 12 日,作者:Alexander Schwartz

先前版本的 Keycloak 僅將一般使用者工作階段(也稱為線上使用者工作階段)儲存在記憶體中。因此,當您關閉或重新啟動 Keycloak 叢集時,所有使用者都會被登出。

在 Keycloak 25 中,有一個預覽功能「持久使用者工作階段」,它將使用者工作階段儲存在資料庫中。如果記憶體中找不到工作階段,則會從資料庫載入,使用者可以繼續使用他們的工作階段,而無需重新驗證。

預覽功能預設為停用,您需要使用 `persistent-user-sessions` 功能標誌啟用它才能試用。

您可以透過在此 GitHub 討論串中提供回饋來協助使此功能獲得全面支援。我們計畫在 6 月 24 日舉辦一個關於持久工作階段的問我任何事 (AMA) 會議

Keycloak 和資料庫的執行時行為變更

啟用此功能後,Keycloak 的記憶體使用量可能會減少,而資料庫使用量可能會增加。

  • 如果在 Keycloak 的快取組態 XML 檔案中未設定其他最大大小,Keycloak 預設會為每個快取工作階段、clientSessions、offlineSessions 和 offlineClientSessions 設定最多 10,000 個項目。如果您想在記憶體中保留更多工作階段,請參閱設定分散式快取以了解如何設定不同的大小。

  • 選項 `spi-user-sessions-infinispan-offline-session-cache-entry-lifespan-override` 和 `spi-user-sessions-infinispan-offline-client-session-cache-entry-lifespan-override` 會被忽略,而是使用最大項目大小。

  • 外部 Infinispan 實例支援 Keycloak 的多站點設定。如果您使用此類設定並已啟用持久使用者工作階段,您可以(且應該)設定要保留在外部 Infinispan 中的最大工作階段數,以限制外部 Infinispan 的記憶體消耗。請參閱Infinispan 的文件,了解如何在 Infinispan 快取中設定驅逐

  • 如果並行使用者工作階段數超過 Keycloak 中的最大快取大小,當例如重新整理權杖或呼叫使用者資訊端點時,您會看到資料庫活動增加,以便從資料庫載入工作階段。這些請求還會因資料庫針對這些讀取語句的回應時間而導致延遲增加。監控快取命中率,以查看您的設定是否需要最佳化。

  • 對於每次登入、重新整理權杖和登出,資料庫中的工作階段表格都會更新,並且會顯示為資料庫活動增加。Keycloak 會嘗試將並行工作階段更新捆綁到單個交易中,但您資料庫的 CPU 和 IOPS 利用率仍將顯著增加。這些請求還會因資料庫針對這些寫入語句的回應時間而導致延遲增加。

對您環境的影響將取決於您的基礎架構和使用模式。作為指標,我們使用以下設定進行了測試

  • 每秒 150 次登入和 150 次登出

  • Aurora PostgreSQL 區域資料庫 15.5

  • 類型 db.t4g.large 伺服器(2 個 ARM vCPU 核心,8 GB RAM)

我們發現執行時指標出現以下變化

  • 在資料庫上

    • 每秒額外 300 次提交

    • CPU 使用率根據並行工作階段數增加了 1 到 1.5 個 CPU 核心

    • 大約 2500 個額外的 WriteIOPS

  • 在 Keycloak 上

    • Keycloak 上的 CPU 使用率保持不變

    • 建立 10,000 個工作階段後,記憶體使用率保持不變

    • 對於單個可用區域資料庫,登入和登出的第 50 個百分位回應時間分別增加了 20 和 10 毫秒,對於兩個可用區域資料庫,分別增加了 30 和 20 毫秒。

我們建議您為您的環境運行基準測試。使用我們在Keycloak 基準測試專案中提供的工具作為工具箱。

請參閱啟用 Keycloak 指標,了解如何啟用 Keycloak 的指標,以監控有關您的快取和 HTTP 回應時間的資訊。

從先前的社群解決方案遷移

社群過去一直在評估不同的組態,其中一些組態有缺點,並且未獲得 Keycloak 的官方支援。啟用持久工作階段後,現在可以簡化這些設定。

使用具有非常大的 JVM 堆積大小的部署:過去,需要大量的 JVM 記憶體才能將所有工作階段保留在記憶體中,並避免記憶體不足的情況。由於持久工作階段儲存在資料庫中,並且僅將子集保留在記憶體中進行快取,因此您現在可以減少分配給 Keycloak 實例的記憶體。

使用離線工作階段來保持使用者登入狀態

一種流行的做法是使用離線工作階段來保持使用者登入狀態,因為這些工作階段甚至在此之前就已持久保存在資料庫中。儘管如此,離線工作階段的目的是用於不同的用途:預期的用途是允許應用程式代表使用者存取資源,即使該使用者已登出,並且常規的線上工作階段登出也不會登出這些工作階段。啟用持久使用者工作階段後,您應該開始使用線上工作階段。現有的離線工作階段仍然可以使用,並且最終會過期。

將 JDBC 儲存區連接到 Keycloak 的內嵌 Infinispan

在此設定中,內嵌的 Infinispan 將工作階段儲存到資料庫和自訂建立的表格中。雖然這是登入和登出的預設設定,但只有在啟動時載入所有工作階段時才會執行此操作,因為非持久使用者工作階段的程式碼假設所有工作階段都在記憶體中。所有工作階段都需要在啟動時載入,否則用戶端或領域的工作階段清單將不完整,並且無法保證例如針對給定使用者僅有一個工作階段的限制。使用 Keycloak 25 中的持久工作階段作為預覽功能,這種新方法可降低設定的複雜性,並減少 Keycloak 和 Infinispan 的記憶體佔用量。請參閱下文,了解如何遷移現有的工作階段。

將 Keycloak 連接到單站點設定的外部 Infinispan

在此設定中,Keycloak 會將工作階段讀取和寫入到外部 Infinispan。與上述類似,所有工作階段都需要在啟動時載入,包括內嵌的 Infinispan 和外部 Infinispan,否則用戶端或領域的工作階段清單將不完整,並且無法保證例如針對給定使用者僅有一個工作階段的限制。此類設定僅支援從 Keycloak 24 開始的多站點設定。使用 Keycloak 25 中的持久工作階段作為預覽功能,這種新方法可降低設定的複雜性,並減少 Keycloak 的記憶體佔用量,並且無需執行外部 Infinispan。請參閱下文,了解如何遷移現有的工作階段。

遷移現有的工作階段

如果您一直在使用連接到內嵌 Infinispan 的 JDBC 儲存區,或者使用外部 Infinispan 在 Keycloak 24 中儲存 Keycloak 線上工作階段,則您可以在第一次啟動 Keycloak 25 時啟用持久使用者工作階段(且僅在啟用時)遷移這些工作階段。

遷移完成後,您應該移除針對內嵌工作階段快取的任何 JDBC 持久性設定。如果您在單站點設定中使用過,也應該移除與外部 Infinispan 的連接。

啟用持久使用者工作階段

由於這是一項預覽功能,因此預設為停用。一旦我們認為此功能已完全支援,我們計劃在未來的版本中預設啟用它。

如果您已遷移到 Keycloak 25,我們建議您清除設定中的所有現有線上使用者工作階段。

根據您是在開發環境中使用它、建立 Keycloak 發行版本,還是在啟動時依賴 Keycloak 的自動重建,您的命令如下所示

bin/kc.[sh|bat] [start-dev|build|start] --features="persistent-user-sessions"

如果您使用環境變數來設定選項,請設定以下環境變數,或者如果環境變數已存在,請新增該值。

KC_FEATURES=persistent-user-sessions

如果您使用 Keycloak Operator,請將其新增到 Keycloak CR 中已啟用的功能中

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: example-kc
spec:
  features:
    enabled:
      - persistent-user-sessions
...

請參閱啟用和停用功能,以了解有關如何啟用功能的更多資訊。

展望

在我們努力使此功能獲得全面支援的同時,我們也在開發類似的功能。有些功能會簡化 Keycloak 的部署,而另一些功能最終會啟用 Keycloak 多站點主動/主動設定。

加入這些功能的討論並給予讚許,以便我們了解您有興趣。

致謝、提供回饋和提問

感謝 Keycloak 團隊成員 Kamesh Akella、Michal Hajas、Pedro Ruivo、Anna Manukyan 和 Ryan Emerson,他們討論了想法和邊緣案例、貢獻了程式碼並執行了中間提取請求和版本的測試。特別感謝社群成員 Tristan971、daviddelannoy 和 Thomas Darimont 加入 GitHub 討論並提供回饋。

您可以透過試用預覽功能並在此 GitHub 討論串中提供回饋來協助使此功能獲得全面支援。

也可以使用此討論串來詢問有關持久使用者工作階段的問題。我們計畫在 6 月 24 日舉辦一個關於持久工作階段的問我任何事 (AMA) 會議