问题描述
提示:这里描述项目中遇到的问题:
项目用的GO语言,会启动一个耗时大概十几分钟的扫描任务,会将一个很大的压缩文件,不断地解压,读取。
读取出来的数据会存入缓存中,然后代码中会访问数据库,将数据库数据与缓存数据进行对比,识别出目标数据。
为了提高效率,启用了大量的协程去访问数据库。
然后就出现了奇怪的现象,前端访问后端接口查询数据时,接口返回非常慢,经常会超时。
定位过程:
首先就是看后端日志,发现请求确实很快就到了后端,但后端迟迟没有返回结果。
怀疑是在什么地方阻塞了。
于是在被调用的方法中加日志,很快就发现了是请求数据库那一行的代码卡住了,等待了很长的时间。
这时候就怀疑是别的地方启动的协程太多,去访问数据库,导致数据库连接数不够用。
于是,直接进入数据库,查询连接数使用情况,发现数据库的连接数并没有用光。
数据库连接数有1024个。
接着又想到,我们代码的配置文件中实际配置的是32个,实际最多使用32个,现在就得考虑是不是这32个被用完了。
直接加了下面的打印:
stats:=db.Stats()logutil.Logger().Infof("PrintDbState OpenConnections: %d (活跃: %d, 空闲: %d) WaitCount: %d (总等待次数) WaitDuration: %v (累计等待时间) MaxIdleClosed: %d (因空闲超时关闭) ",stats.OpenConnections,stats.InUse,stats.Idle,stats.WaitCount,stats.WaitDuration,stats.MaxIdleClosed)很快,就从日志里面看出了,活跃数量是32,空闲0,总等待次数不断增加,。
很显然就是数据库连接数被用满了。
解决方案:
找到原因就好处理了,降低并发数,调高数据库连接数上限,很快就把总等待次数降下来了,前端访问也正常了。