Azure虚拟机部署Keycloak连接Azure SQL Server数天后故障求助
我之前在Azure上部署Keycloak+SQL Server的时候也碰到过几乎一模一样的问题,给你分享下我当时排查和解决的思路,应该能帮到你:
从你的异常栈来看,本质是连接池里的连接已经被Azure SQL Server主动关闭,但Keycloak的连接池还认为这些连接可用,当尝试使用时就抛出了The connection is closed错误。调小max-pool-size只是减少了失效连接的数量,所以只能延迟故障,不能解决根本问题。
1. 配置连接池的连接有效性检测(最关键的一步)
Azure SQL Server默认有30分钟的闲置连接超时,如果连接池里的连接长时间没被使用,SQL Server会主动断开。我们需要让Keycloak的连接池在使用连接前先验证有效性:
如果你用的是JBoss风格的standalone.xml配置:
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true"> <!-- 其他原有配置保持不变 --> <validation> <!-- 针对SQL Server的专用连接校验器 --> <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/> <!-- 开启后台定时校验闲置连接 --> <background-validation>true</background-validation> <background-validation-millis>60000</background-validation-millis> <!-- 每分钟校验一次 --> <!-- 每次获取连接时都校验 --> <validate-on-match>true</validate-on-match> </validation> </datasource>
如果你用的是keycloak.conf(Keycloak 17+的Quarkus模式):
db-pool-validation-query=SELECT 1 db-pool-validate-on-match=true db-pool-background-validation=true db-pool-background-validation-millis=60000
2. 对齐连接池与SQL Server的超时参数
确保Keycloak连接池的闲置超时时间小于Azure SQL的默认30分钟,避免连接池还没回收闲置连接,就被SQL Server先断开了:
# keycloak.conf配置示例,设置为25分钟 db-pool-idle-timeout-minutes=25
同时要注意Azure SQL的连接数限制(取决于你的SKU),max-pool-size不要设置得超过SQL Server的最大允许连接数,否则会触发新的连接失败问题。
3. 排查Azure侧的网络/防火墙问题
有时候Azure的网络波动或者防火墙规则变更会强制断开连接:
- 检查Azure SQL Server的防火墙规则,确保你的Azure VM的IP(或VNet服务端点)始终在允许列表中;
- 优先使用Azure SQL服务端点,让VM通过VNet直接连接SQL Server,减少公网波动的影响;
- 去Azure Portal的SQL Server日志里查看有没有连接被强制断开的记录,进一步定位问题。
4. 升级JDBC驱动版本
旧版本的mssql-jdbc驱动可能存在连接状态感知的bug,建议升级到9.4.0及以上的稳定版本。如果是Keycloak的模块驱动,找到modules/system/layers/base/com/microsoft/sqlserver/main目录下的jar包替换即可。
可以开启Keycloak的连接池日志,查看连接的创建、使用和回收细节,帮助定位问题:
# keycloak.conf添加日志配置 log-level=org.jboss.jca=TRACE
内容的提问来源于stack exchange,提问作者mgiammarco

