然后为了更好的演示这个问题,将数据库连接池(本篇用的是Druid)的参数做了以下设置
1//初始连接数
2spring.datasource.initialSize=1
3//最大连接数
4spring.datasource.maxActive=5
由于最大连接数是5.所以当1000个线程并发进来的时候,你可以想象是一个队伍有1000个人排队,最前面的5个,拿到了连接,并且执行业务时间为1秒.那么队伍中剩下的995个人,就在门外等候.等这5个执行完的时候.释放了5个连接,依次向后的5个人又进来,又执行1秒的业务操作.通过简单的小学数学,都可以计算出最后5个执行完,需要多长时间.通过这里分析,你就知道,为什么上面的日志输出,是5秒为一组了,并且每组间隔为1s了.
怎么解决
看过肥朝源码实战的粉丝都知道,肥朝从来不耍流氓,凡是抛出问题,都会相应给出其中一种解决方案.当然方案没有最优只有更优!
比如看到这里有的朋友可能会说,你最大连接数设置得就像平时赞赏肥朝的金额一样小,如果设置大一点,自然就不会有问题了.当然这里为了方便向大家演示问题,设置了最大连接数是5.正常生产的连接数是要根据业务特点和不断压测才能得出合理的值,当然肥朝也了解到,部分同学公司机器的配置,竟然比不过市面上的千元手机!!!
但是其实当时压测的时候,数据库的最大连接数设置的是200,并且当时的压测压力并不大.那为什么还会有这个问题呢?那么仔细看前面的代码
其中这个校验的代码是RPC调用,该接口的同事并没有像肥朝一样值得托付终身般的高度可靠,导致耗时时间较长,从而导致后续线程获取数据库连接等待的时间过长.你再根据前面说的小学数学来算一下就很容易明白该压测问题出现的原因.
敲黑板划重点
之前肥朝就反复说过,遇到问题,要经过深度思考.比如这个问题,我们能得到什么拓展性的思考呢?我们来看一下之前一位粉丝的面试经历
其实他面试遇到的这个问题,和我们这个压测问题基本是同一个问题,只不过面试官的结论其实并不够准确.我们来一起看一下阿里巴巴的开发手册
通过这个经历我们又有什么拓展性的思考呢?因为问题是永远解决不完的,但是我们可以通过不断的思考,把这个问题压榨出更多的价值!我们再来看一下阿里规范手册
用大白话概括就是,尽量减少锁的粒度.并且尽量避免在锁中调用RPC方法,因为RPC方法涉及网络因素,他的调用时间存在很大的不可控,很容易就造成了占用锁的时间过长.
其实这个和我们这个压测问题是一样的.首先你本地事务中调用RPC既不能起到事务作用(RPC需要分布式事务保证),但是又会因为RPC不可控因素导致数据库连接占用时间过长.从而引起接口超时.当然我们也可以通过APM工具来梳理接口的耗时拓扑,将此类问题在压测前就暴露.
写在最后
声明:本站部分文章内容及图片转载于互联网、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站删除。