Kubernetes 的错误消息和解决方案
本文档描述了在 Kubernetes 上运行 Keycloak 基准测试套件时遇到的常见错误消息及其解决方案。
Keycloak 消息 ERROR: Failed to obtain JDBC connection
- 上下文
-
当使用关系型数据库(如 PostgreSQL 或 CockroachDB)运行 Keycloak 时,可能会出现此错误消息。
类似的其他错误消息
-
无法获取 JDBC 连接
-
抱歉,获取超时!
这可能在启动过程中发生,然后启动失败。它也可能在负载测试期间发生,此时 Keycloak 创建新的数据库连接。
-
- 原因
-
数据库要么未启动,要么当前设置中已用尽数据库连接数。
- 解决方案
-
-
确保数据库正在运行。
-
确保数据库没有重新启动,例如由于内存不足问题。
-
确保总的数据库连接数不超过数据库的最大连接数。有关详细信息,请参阅 Keycloak 部署配置选项
KC_DB_*
。 -
确保 Keycloak 不会尝试使用超过配置的最大连接数的连接。
-
- 注意
-
-
在高负载下,数据库连接数通常是系统的限制因素。Keycloak 遇到“抱歉,获取超时”并向调用者返回 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 的事务管理器捆绑了两个事务,它就会在准备所有事务后发送
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 个工作线程,这样就不会在 JGroup 线程池中耗尽 200 个线程。使用 Quarkus 配置选项quarkus.thread-pool.max-threads
来配置最大工作线程数。请参阅 在生产环境中运行 中的更多信息。