KingbaseES+SqlSugar 为医疗用户排忧解难

在 2024 年的初春,某大型三甲医院的 CT 预约系统上线测试,如同新芽破土,充满了希望与活力。然而,仅仅两天后,一个技术难题如同迷雾中的幽灵,悄然出现:The connection pool has been exhausted……
福尔摩斯 K,如同猎犬般敏锐,迅速投入了这场技术探案。
第一章:迷雾初现
“华生,我们必须首先排除高并发的可能性。”福尔摩斯 K 开始对业务系统进行梳理。他发现,错误是业务系统报出的,业务系统处理第三方消息平台发送的请求,第三方消息平台收集签到机和其它设备发送的请求。业务系统高峰期时,同时请求的请求可以达到 10 条左右。并发量并不大,排除并发量导致的连接池爆池。

第二章:数字的线索
福尔摩斯 K 转而查询 K 家族自主研发的 KingbaseES 系统表 sys_stat_activity,记录了每个连接的信息。他发现,KingbaseES 通过精心设计的查询语句,每隔一秒,如同钟表的滴答声,记录下了对应业务的数据库连接数。在业务量最大时,连接数竟达到了 800 个,大多数连接状态为“Idle in transaction”,如同悬而未决的谜团。

第三章:连接池的秘密
之后,福尔摩斯 K 对 KingbaseES 驱动的 kdbndp 连接池机制进行了深入的分析。在他看来,连接池的三个计数器——空闲连接计数器 Idle、正在使用连接计数器 Busy 和等待获取连接对象计数器 Waiting——如同三重奏,共同维持着连接池的和谐。然而,现场问题中存在大量创建物理连接的现象,将连接池撑爆,这与连接池的设计机制不符,也许这就是破案的关键。
01 连接池中无连接-申请连接流程

02 连接池已经存在连接-申请连接流程

03 连接池释放连接—应用退出

04 连接池释放连接—连接空闲达到设置时间(默认 5 分钟)

05 连接池满-处理流程

06 连接池参数介绍
Pooling 是否开启连接池,true:开发连接池,false:关闭连接池,默认值:trueMinimum Pool Size 连接池保持最小连接数,默认值:0Maximum Pool Size 连接池可以创建连接额最大数,默认值:100Connection Idle Lifetime 空闲连接空闲时间达到的时间值,到达该时间值时,可以回收该连接,默认值:300(秒)Connection Pruning Interval 空闲连接回收之前等待时间,默认值:10(秒)分析后得知,从连接池设计的机制来看,一般连接使用结束之后,是释放回到连接池中;而现场问题中存在大量创建物理连接,将连接池撑爆的现象存在。
大量物理连接的状态为:
Idle in transcation
至此,福尔摩斯 K 找到了导致连接池爆池的原因。
第四章:事务的幽灵
“华生,我们需要关注这些‘Idle in transaction’的连接。”福尔摩斯 K 认为,当数据连接处于此状态时,意味着连接已经开启了事务,但没有任何操作来结束这个事务。他们进一步梳理了 KingbaseES+SqlSugar 框架的结构图,试图定位问题。
KingbaseES+SqlSugar

业务流程访问数据库的数据经过了如下步骤:
定义实体数据模型,实体模型模型是编写程序的依据;
业务系统调用 SqlSugar 接口,创建对象时,业务代码编写人员可以指定使用 SqlSugar 的模式,推荐使用的是单例模式 SqlSugarScope,该模式是线程安全的。在创建对象的时候,通过 DbType 指定访问的数据库是哪一家的。Kdbndp 中有一个参数 DbModeType,指定使用哪种数据库模式,两者有异曲同工之妙;这个时候,我们也指定了我们访问的数据库,访问数据库使用的连接参数等信息;
还是调用 SqlSugar 接口,SqlSugar 会将对应接口的操作,映射、翻译为对应的 sql 语句,调用 Kdbndp 的执行接口,将语句发送到服务器端;
服务器端执行之后,执行结果又通过 Kdbndp 的功能接口,回到 SqlSugar,根据映射关系,将结果存放至模型对象中,业务系统通过获取模型对象中的数据,完成业务数据展示的处理流程。
上述流程步骤二中,创建单例模式的访问对象,引起了福尔摩斯 K 和华生的关注。福尔摩斯 K 对华生说:“我觉得我们需要梳理一下 SqlSugar 创建单例模式时,整个的创建使用流程。”华生立刻给出了流程图:

第五章:单例模式的陷阱
在 SqlSugar 创建单例模式的过程中,福尔摩斯 K 发现了关键的线索。果然是在开启事物之后,调用完成退出时没有做 commit 操作,导致 Kdbndp 连接无法回到连接池,无法循环使用连接池中连接而导致爆池。
第六章:迷雾散去
福尔摩斯 k 说:“调用 BeginTran(),完成业务逻辑退出时,必须调用 CommitTran()来完成连接的释放。”用户在完成业务逻辑退出时,调用了 CommitTran()。经过调整,连接池中的物理连接保持在 20 个左右,爆池的错误不再出现。服务器端相关资源消耗大幅下降,每次任务的提交速度显著提升。这场技术探案,如同解开了一道复杂的密码,终于迎来了曙光。
第七章:搭子的力量
案件水落石出后,华生发现了 KingbaseES+SqlSugar 的方案在实际业务中有不少优点,比如说:
1 屏蔽数据库模式的差异,业务根本不用关心我连接的是金仓的什么数据库模式,因为驱动和框架已经做了屏蔽了差异,让业务编写更容易迁移;
2 业务开发和迁移的高效性,驱动和框架做了兼容开发,只是通过连接串的不同,就能实现不同数据库之间的业务迁移,太方便了;
3 实时的技术支持,可以快速定位问题,并解决问题。
福尔摩斯 k 点点头,表示认可,并补充到:“你忘了说 KingbaseES 较为全面的兼容能力,目前兼容了 PostgreSQL、Oracle、MySQL、SQL Server 等数据库的核心功能。这在业界是极具独创性的。”这一次福尔摩斯 K 更接近 K 家族的核心技术了
版权声明: 本文为 InfoQ 作者【金仓技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/0f10e76f78d4c9e54f2d885fd】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论