Keycloak部署于Azure容器实例时无法获取JDBC连接异常求助
Keycloak定期数据库连接超时问题排查建议
问题场景
在Azure容器实例(1核CPU、1.5GB内存,Standard SKU)部署Keycloak 20.0.5,关联Azure SQL数据库(Standard S0,10 DTUs)。多数时候连接正常,但会定期出现数据库连接超时,日志如下:
2024-06-26 10:20:36,971 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (Timer-0) SQL Error: 0, SQLState: null 2024-06-26 10:20:36,971 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (Timer-0) Acquisition timeout while waiting for new connection 2024-06-26 10:20:36,972 ERROR [org.keycloak.services.scheduled.ScheduledTaskRunner] (Timer-0) Failed to run scheduled task ClearExpiredUserSessions: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
异常每30分钟或1小时出现一次,持续约2分钟后恢复。针对你提出的疑问,给出以下排查方向:
1. 定价层组合是否不合适?
Standard S0的10 DTUs资源储备有限,尽管已从Basic升级,但Keycloak的定时任务(如清理过期会话)会集中触发批量数据库操作,可能瞬间打满DTU,导致连接请求超时。
- 查看Azure SQL的DTU使用率趋势,若异常时段DTU接近100%,说明资源不足,建议升级至S1(20 DTUs)或更高规格。
- 监控ACI的CPU/内存使用率,若任务执行时资源占满,会影响连接池的正常操作,必要时提升ACI的资源配置。
2. 连接池大小问题?
Keycloak默认HikariCP连接池的最大连接数为10,在定时任务集中触发时,连接可能被耗尽,导致新请求无法获取连接。建议调整以下参数:
- 设置
KC_DB_POOL_MAX_SIZE为15-20(根据业务负载灵活调整) - 延长
KC_DB_POOL_CONNECTION_TIMEOUT至60秒(默认30秒),避免快速超时 - 配置
KC_DB_POOL_IDLE_TIMEOUT和KC_DB_POOL_MAX_LIFETIME,防止闲置连接失效占用资源
3. SQL数据库连接/会话是否超出限制?
Standard S0的最大并发连接数为1000,从你提供的监控图看当前连接数远低于阈值,但需关注异常时段的连接数峰值。此外,需排查是否存在连接泄漏:
- 启用HikariCP连接泄漏检测,设置
KC_DB_POOL_LEAK_DETECTION_THRESHOLD=2000,日志会输出泄漏连接的栈信息,定位未正确关闭连接的代码或插件。
4. Keycloak容器配置错误?
- 优化数据库连接URL,添加超时参数避免网络波动导致连接挂起:
jdbc:sqlserver://<server>.database.windows.net:1433;databaseName=<db>;connectTimeout=30;socketTimeout=60;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30; - 调整定时任务
ClearExpiredUserSessions的执行频率,或配置分批次清理逻辑,降低单次数据库操作的压力。 - 检查是否启用了不必要的功能(如过多事件监听、自动导入导出任务),这些会额外消耗数据库连接资源。
5. Azure容器实例是否适合运行Keycloak?
ACI适合轻量负载的Keycloak部署,但资源隔离和网络稳定性不如AKS(Azure Kubernetes Service)。若ACI存在间歇性网络抖动,可能导致数据库连接中断。
- 迁移到AKS可获得更好的资源弹性和网络可靠性,但迁移本身无法直接解决连接超时问题,需配合前面的资源、连接池、配置排查。AKS的自动扩缩容能力可更好应对突发负载,减少资源瓶颈。

内容的提问来源于stack exchange,提问作者bianconero
相关产品推荐
相关产品推荐

