博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库连接历险记
阅读量:4499 次
发布时间:2019-06-08

本文共 3039 字,大约阅读时间需要 10 分钟。

  • 项目背景:

  最近公司的一个项目,项目背景大概就是与其他公司合作,该公司提供业务数据,通过socket进行通信传输。在协议封装上,真的是充分利用好每个位的数据,所以一个业务数据包只有20byte左右(为什么说这个?后面会有关系)

  业务数据是分阶段接入的。之前已经接入了业务量为N的数据。

  • 起因:

  在周一决定加大业务数据的接入为2N接入后,发现前置系统出现了数据库连接不够的情况。已经达到了连接最大数的100。这个时候本能将数据库连接变大,设置为200.(后来发现数据库连接可以设置到很大,包括1000以上,但是一般不会这么设置,因为这个1000,并不代表你系统的性能越高。1000个就会出现连接等待的情况,1000个连接,其中很多一部分在等待的状态,并发用于连接调用,反而会更加消耗系统的资源,会更加慢。)

  设置为200之后,总算能支撑过去了。但是为什么会消耗这么多连接呢?当时第一的反应接入的业务数据加大,所以业务处理并发太大,所以会消耗很多的数据库连接。那么怎么解决呢?随着后续业务数据接入的增大,难道数据库的连接一直设置大吗?我印象中,数据库连接不能设置那么大,即使能,也不建议设置这么大。一般100个就已经足以。

 

  • 问题恶化:

  周二早上回去之后,继续查看日志,发现系统的200个线程,在某些时候竟然还不够用,依然爆出了连接数达到最大数,无法创建连接的情况。这个时候产品的人继续施压,要继续加大业务数据量到6N,顶不住压力,最后加大到3N,同时争取时间各处查找连接池的配置与性能。

  这个时候详细查看proxooll的各项配置。查看了proxool的最大连接数,最小空闲数,每次创建数量,最大空闲时间,最大存活时间,最大使用时间等几个重要参数。其实一般都是设置这几个参数的值。

  后来查找资料时发现,是不是我们系统的连接没有释放??,才导致连接不够,不也不可能吧200个连接用光啊。所以查看hibernatereleasemode。默认是onclose,可以设置为after_transation。但是我们的操作都会进行关闭了了,这个会有用吗?

  io分析

  下午编写了压力测试程序,持续不段得上送业务数据(循环发送,这个发送数据应该是很快的了)。很奇怪,我的本机顶住了压力。这个时候想起压力测试的时候,当业务系统和数据库不是不熟在同一台交换机下的时候,由于更多的io转换,加上发送数据包的大小(系统与数据库交互的数据要比一个业务数据报文大多了)和数量,会导致网卡负荷过重,传输和执行缓慢。这样的话,会导致连接不能很快释放、但是在查看了部署结构后,排出了这个可能。

  mysql分析

  这个时候,就把方向转到了mysql的参数和状态上。使用SHOW valiuableshow status观察相关的参数。这里里面有较为重connectionmaz_connectionmax_use_connectionThread_connectthread_create等四个参数。其中Thread_connect最为重要。其他的什么缓存大小,查询缓存大小,打开表数量,mysiam优化等参数都没有太大的关系。

  花了一天去研究这些参数,在下午升级完之后,悲剧的由于那边搬家了,断电了,升完日志什么都没看到。那么只有明天再搞。(明天,也就是今天就出现了十分难以置信的linux奔溃事件,还在查找之中,才是令我头疼之处。请看另外的一片,linux崩溃倒霉的噩梦文章)

  proxool分析

  今天早上将idc的连接池配置拿来,跑压力测试程序,同时观察mysqlstatus,进行把脉观察分析。

  这里面有两个现象,当将每次创建数缩小之后,系统连接池出现了异常,为(忘记了,在公司有记,明天部署)。查找问题分析到为,当当前连接池不够连接时,就创建连接,创建的数量为配置的每次创建数。但是由于创建了之后,依然不够用,就会出现这个错。在高并发系统中,一般在每个时间段需要的连接数较多,所以需要将这个值设大。这个问题消失了。

  在观察mysql的连接数情况,发现生产机的连接池配置下,数据库max_use_connection137,但是thread_count最多为90,在不停的调整压测程序的发送间隔和连接池配置下,发现最差的情况就是刚才说的情况,其他情况数据库一般thread_count67十左右,max_use_connection不会超过100。这个时候在想,是不是每次创建连接数simultaneous-build-throttle的参数设置(网上的资料很多都是扯淡,一大片都是抄来的,都是同样的内存)为100,是不是之前有了一些连接,在创建100之后就会连接不够用呢,测试之后否定了这个猜想。连接池会动态适应的。(其实分析就是在不停的假设,猜想和验证,否决的过程,痛苦但有那么一点点快乐)

 

  •  惊喜的问题复现

  经过上述的不停调节测试之后,还是没有发现到问题所在。这个是回归到问题的本身。

  为什么会出现连接不够用,是因为需要获取连接的地方太多,导致连接不够用。当时当初压力测试接入7000台车都没有问题,那个时候数据库连接数才不过设置为200,瓶颈在于网卡的传输,并不在连接上啊。

  那么分析程序,在收到数据之后,在连接池获取线程进行处理,那么每个处理线程就需要连接数了。也就是说需要获取连接的线程数(也就是并发线程数)超过200。但是现在为什么我持续发送,其实是不idc的压力更大,问题却不会重现呢?是不是idc的处理速度更快,所以受到数据后,开启的处理线程更多?

  那么就需要使得我们的程序更快了。这个时候想起前两天和老郑讨论的日志效率的问题,日志是单线程写的,以为文件要同步,虽然log4j使用了缓存技术,但是日志还是会耗不少性能,实际上也发现了日志不停刷新。所以就提高日志级别,把日志都禁掉了大部分。这个时候,一启动压测程序,问题重现了,连接大量不够用。

 

  这里真有点激动啊,终于重现了。这个时候再来观察我的线程池,使用的是老郑框架注入的(一个炸弹,自己竟然这么傻,业务线程数没有限制!!!!,哎),没有配置就默认为无线伸缩的池。也就是说,这个吃可以一直创建线程,达到系统上限,能创建4000以上,(和xss,虚拟机内存大小有关)。所以导致索取数据库连接的线程太多了。我靠,又一次被坑了,上一次是http连接的问题。囧!!!!!!!!

  重新配置连接池,设置为50大小的可重用连接池,减少数据库连接池最大连接数为100,运行压测程序,完全没有问题,坑爹啊,终于解决了,尼玛,默认的东西有时候小心用啊。重要的东西还是需要问清楚啊有木有,不然很坑爹的说。线程池和连接池必须要设置大小啊,有木有啊。。。。。(说不定今天linux崩溃的问题,也有点点和这个有点关系,因为还是使用了无线的线程池,应该要设置小啊,必须要设置啊。不用怕设置小了netty无法处理连接啊,因为netty的长连接连接处理线程和业务处理线程是分开的有木有!!!!!!!!!!!!!)

  • 可以睡一觉了

  写了这么多,累死俺了,小MM还在等我睡觉呢,不写了,也吐槽完了,明天继续写今天坑爹的linux系统崩溃之倒霉至极。

转载于:https://www.cnblogs.com/evermaze/p/proxoolerror.html

你可能感兴趣的文章
解决电脑复选框图标不正确方法
查看>>
伪数组怎么转为真正的数组呢~
查看>>
WebGL笔记(六):简单灯光
查看>>
XCode: duplicate symbol 解决方案
查看>>
iOS状态栏设置详解!
查看>>
编程习惯1
查看>>
【读书笔记】iOS-给模拟器相册增加图片
查看>>
ActionMapping、ActionForward笔记
查看>>
Linux:xargs命令详解
查看>>
明天你好
查看>>
float浮点数的四舍五入
查看>>
QQ消息记录、接收文件、图片、拍照照片等保存位置
查看>>
IOC与AOP介绍
查看>>
关于求最大公约数
查看>>
Git常用命令学习总结
查看>>
【转载】C#通过Rows.Count属性获取总行数
查看>>
【转载】通过百度站长平台查看网站搜索流量及关键字
查看>>
【转载】Visual Studio2017如何打包发布Winform窗体程序
查看>>
【转载】通过搜狗站长平台手动向搜狗搜索提交死链
查看>>
【转载】通过搜狗站长平台手动向搜狗搜索提交文章加快收录
查看>>