西区域AKS集群连接东区域Azure SQL DB间歇性超时求助
问题场景
西部区域Azure Kubernetes Service(AKS)集群中的多个Pod,连接东部区域Azure SQL Database时出现间歇性连接超时;但西部AKS连接同区域的Azure SQL时无任何异常。
通过tcpdump抓包发现:超时期间Pod没有发起任何连接DB的请求痕迹,而正常运行时可以捕获到Pod与DB的通信流量。
相关错误日志
2024-04-28 16:56:30,420 [Async-128] DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Timeout failure stats (total=0, active=0, idle=0, waiting=47)
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:48) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:109) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:136) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:254) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:262) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:236) at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:86) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:183) at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:401) ... 25 common frames omitted Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms. at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:676) at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:190) at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:155) at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128) at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106) ... 32 common frames omitted
排查与解决方案
从日志和抓包结果来看,问题核心并非网络层的连接失败,而是Hikari连接池彻底耗尽且无法补充新连接(日志中total=0, active=0, idle=0说明池内无任何可用连接,也没有正在创建的连接)。以下是针对性的排查方向和解决措施:
1. 调整Hikari连接池核心配置
跨区域网络延迟会拉长连接创建、验证和使用的时间,默认配置可能不适用:
- 增大
maximumPoolSize(最大连接数):如果业务请求量较大,跨区域场景下连接周转变慢,需要更大的连接池容纳等待请求。 - 调大
connectionTimeout(连接超时时间):默认30秒,跨区域创建连接的耗时可能超过这个值,导致池无法成功创建新连接,建议调整为60秒。 - 优化连接回收策略:检查
idleTimeout(空闲连接超时时间)和maxLifetime(连接最大生命周期),避免连接被过早回收;同时确保validationTimeout(连接验证超时时间)足够大(比如10秒),避免因跨区域延迟误判连接失效。
2. 排查连接泄漏问题
连接泄漏是导致池耗尽的常见原因,可通过Hikari的泄漏检测功能定位:
- 在Hikari配置中添加
leakDetectionThreshold=2000(单位毫秒),当连接占用超过2秒时,日志会打印完整的调用栈,找到未正确释放连接的代码位置。 - 检查应用代码:确保所有获取连接的操作都使用
try-with-resources语法,事务操作正确提交或回滚,避免连接长期占用。
3. 优化跨区域网络稳定性
虽然抓包未发现连接尝试,但网络异常可能间接导致连接池无法正常工作:
- 使用Azure SQL服务端点:将AKS所在VNet与Azure SQL配置服务端点,通过私有网络而非公网传输数据,降低延迟和波动。
- 配置VNet对等连接:如果AKS和Azure SQL分别在不同区域的VNet中,建立跨区域VNet对等,优化网络路径。
4. 应用侧性能优化
- 缩短长事务时长:跨区域延迟会放大长事务的影响,尽量拆分大事务,减少连接占用时间。
- 优化查询性能:通过索引优化、减少数据传输量等方式,降低单次查询的连接占用时长,提升连接池的周转效率。
内容的提问来源于stack exchange,提问作者user3817206
相关产品推荐
相关产品推荐

