Kubernetes 的錯誤訊息與解決方案

本節描述在 Kubernetes 上執行 Keycloak 基準測試套件時,常見的錯誤訊息及其解決方案。

Keycloak 訊息 ERROR: Failed to obtain JDBC connection

情境

當使用關聯式資料庫(例如 PostgreSQL 或 CockroachDB)執行 Keycloak 時,可能會出現此錯誤訊息。

類似的其他錯誤訊息

  • Unable to acquire JDBC Connection

  • Sorry, acquisition timeout!

這可能在啟動期間發生,然後導致啟動失敗。也可能在 Keycloak 建立新的資料庫連線時,在負載測試期間發生。

原因

資料庫未啟動,或是目前設定中的資料庫連線數已耗盡。

解決方案
  • 確保資料庫正在執行。

  • 確保資料庫沒有重新啟動,例如由於記憶體不足的問題。

  • 確保資料庫連線總數未超過資料庫的最大連線數。有關詳細資訊,請參閱 Keycloak 部署組態選項 KC_DB_*

  • 確保 Keycloak 不會嘗試使用超過組態為最大連線數的連線。

警告
  • 在高負載下,資料庫連線數通常是系統的限制。讓 Keycloak 遇到「Sorry, acquisition timeout」並向呼叫者傳回 HTTP 5xx 程式碼是一種合理的負載卸載機制。有關詳細資訊,請參閱 在生產環境中執行

Keycloak 訊息 prepared transactions are disabled

完整訊息
org.postgresql.util.PSQLException: ERROR: prepared transactions are disabled.
Hint: Set max_prepared_transactions to a nonzero value.
情境

當交易管理器或 Quarkus 在請求中處理多個交易,且其中一個交易屬於 PostgreSQL 資料庫時,就會發生這種情況。

原因

一旦 Quarkus 的交易管理器捆綁兩個交易,它會在準備所有交易後傳送 commit 之前,向資料庫傳送 PREPARE TRANSACTION 命令。為了使其正常工作,資料庫需要設定 max_prepared_transactions 參數。

影響

任何針對 PostgreSQL 資料庫的交易都不會成功。

解決方案

將參數 -c max_prepared_transactions=xxx 傳遞給資料庫。對於 Kubernetes 設定中容器化的資料庫,這已在 postgres-deployment.yaml 中設定。

Keycloak 訊息 ARJUNA012225: cannot access root of object store

完整訊息
ARJUNA012225: FileSystemStore::setupStore - cannot access root of object store: ObjectStore/ShadowNoFileLockStore/defaultStore/
情境

當交易管理器或 Quarkus 在請求中處理多個交易,並嘗試在本機持久化交易狀態時,就會發生這種情況。

原因

Keycloak 的工作目錄在 Keycloak 容器中是不可寫的,因此寫入狀態會失敗。

影響

任何參與 JTA 交易的儲存的交易都無法完成,因此 Keycloak 將無法啟動。

解決方案

透過環境變數 QUARKUS_TRANSACTION_MANAGER_OBJECT_STORE_DIRECTORY 傳遞可寫入的資料夾。這已在 keycloak#19384 中針對 Keycloak 21.1 上游修復。

Keycloak 訊息 'org.jgroups.util.ThreadPool: thread pool is full'

完整訊息
org.jgroups.util.ThreadPool`: thread pool is full (max=xx, active=xx); thread dump (dumped once, until thread_dump is reset)
情境

當 JGroups 中的執行緒池執行緒耗盡時,就會發生這種情況。為了使此訊息以預設的 JGroups 組態出現,需要將系統屬性 jgroups.thread_dumps_threshold 設定為 1,否則該訊息僅會在拒絕 10000 個執行緒後才會出現。

原因

每個 Keycloak Pod 都有執行執行 RESTEasy 請求的執行緒。雖然這些執行緒可以直接從本機快取(主要或備份)請求資料,但它們需要透過 JGroups 呼叫遠端快取。雖然其中一些請求可能會被捆綁,但每個遠端呼叫的 Keycloak 請求可能都需要使用一個 JGroups 執行緒。

影響

當 JGroups 在其執行緒池中執行緒耗盡時,它會拒絕並捨棄即將加入佇列的遠端呼叫。這將導致較長的處理時間,並最終導致 Infinispan 的逾時,而 JGroups 是底層傳輸。

解決方案

叢集中所有 Keycloak Pod 的執行緒總數應等於 JGroups 執行緒池的最大大小。

由於 ISPN-14780 已在 Keycloak 22.0.2 中修復,因此 JGroup 執行緒的數量預設為 200,並且可以使用 Java 系統屬性 jgroups.thread_pool.max_threads 來設定。如實驗所示,假設一個包含 4 個 Pod 的 Keycloak 叢集,每個 Pod 的工作執行緒不應超過 50 個,這樣它才不會在 200 個 JGroup 執行緒池中耗盡執行緒。使用 Quarkus 組態選項 quarkus.thread-pool.max-threads 來設定工作執行緒的最大數量。

請參閱 在生產環境中執行 中的詳細資訊。