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
來設定工作執行緒的最大數量。請參閱 在生產環境中執行 中的詳細資訊。