记一次使用Cobar踩到的坑

起因

起因是因为日志里经常报出锁等待超时的错误,并且这个是环环相扣的,一个锁等待会直接引发另外的锁等待,所以危害非常严重,影响非常深远。寻找原因发现是C3P0报出了DEADLOCK,如下图所示:
记一次使用Cobar踩到的坑_第1张图片

分析

可以看出来ScatteredAcquireTask,也就是获取连接的任务,全部卡在那不动了。那显然是无法获取新的数据库连接了。正好前一天刚刚进行过架构上的调整——从应用直连Mysql变化到中间添加了一层Cobar(关于Cobar,它是一个Mysql代理中间件,用来处理分库)。猜测就是切换到Cobar的问题,但是究竟是什么问题呢?下面我们来一起分析一下:

首先是切换到Cobar前的服务器结构图:

N台应用 –> 1台Mysql

下面是添加Cobar后的:

N台应用 –> 2台Cobar -> N台Mysql

那么两者之间到底有什么区别呢?我在本地做了一个测试,将C3P0的初始连接数设置到5000,也就是模拟在大量的连接请求下数据库的反应,看看是否会出现ScatteredAcquireTask卡住的情况。5000个连接建立完成了,但是出乎意料的是,我用show processlist查看Mysql线程时,居然并没有看到线程的增长,而是和刚才一样。到这里我差不多已经意识到了问题所在,为了证实这一点,我又用直连数据库的方式起了5000个连接,这次数据库连接果断就上去了。恩,看到这里大家应该也都猜到了吧,与Cobar建立连接,并不表示与Mysql建立连接,其实在我们的应用到Mysql这段道路上存在着两个“池”,一个是我们应用和Cobar之间的数据库连接池,还有一个是Cobar和Mysql之间的连接池。应用和Cobar之间的连接数并不存在瓶颈,并且我们也知道它们之间是用NIO通信的。但是CobarMysql之间呢?OH,由于Cobar只实现了一半的NIO,所以和Mysql之间还是走的BIO

这里还需要说明的一点是,我们公司的Cobar服务器是DBA来搭建和维护的。所以对我们后端开发来说所有的配置都是不透明的,我们不熟悉Cobar的配置也不知道有哪些东西可配置。但是凭借刚才的猜想,已经差不多知道瓶颈就是CobarMysql之间。

解决

跟随着自己的猜想,果断百度了一下Cobar的配置参数,发现有一个参数名为PoolSize,用来设置Cobar与后端数据源连接池大小。将其调大,即将问题解决。

并且事后在查看Cobaralarm日志时,发现出问题的时间段内正好打出如下的日志,也更加证实了我的猜想!
记一次使用Cobar踩到的坑_第2张图片

你可能感兴趣的:(mysql,cobar)