我一直以来, 对性能测试中, 连接池的大小要如何配置, 不是太清楚;
就我所知道的, 就 DB 自带对连接数的限制, 在 sqlserver 中用 select @@connection 可以查到,
在代码中, 可以配置 DB 的连接池,
在中间件中, 可以配置最大的线程数等等.
在性能测试中, 这些配置显然很重要, 要不然, 木桶原理, 哪一个低了, 都是个性能瓶颈, 在其他地方再怎么费力, 也无能为力.
今天做了一个实验, 不考虑中间件, 不去考虑代码逻辑啊, 接口调用什么的, 只考虑数据库连接池, 和实际并发数的影响.
工具也很简单, 就用 Jmeter 中元件 JDBC Connection Configuration 配置 DB 连接数, 再在 JDBC 请求中向表中新增一条记录. 新增不像查询的, 不会因为数据量的多少受影响.
因为线程数是受系统的用户数决定的, 所以要分析受众数量,
可以通过以往的日志分析, 一般系统中都会记录用户在何时, 何种渠道, 登录了, 退出了, 修改了, 等等, 总之是这样的交互表
通过分解, 高峰时间段, 以半小时, 或每小时计算, 每秒钟的最大用户数
也可以通过社会工程学, 并叫上算法分析师, 分析和计算出高峰期用户数量
还有一些是活动 Campaign, 一段时间内的大促活动, 比如双十一支付宝支付接口, 比如商场活动促销, 抢拍, 秒杀, 等等,
看看每秒钟的用户数量, 能否大概掌握和预估一定的值;
比如我们这边, 大促之前会通过短信或者微信的方式, 通知我们的会员, 在 xxx 链接领取优惠券, xxx 时间可以积分兑换更多好礼, 在 xxx 时候购买充值会员卡等等
分析有无裂变的方式, 会引来更多会员, 一般不太好控制, 或者会故意将通知会员的速度调节慢些;
不可裂变, 即用户即使转发链接给好友, 好友不支持参与活动, 这个时候, 单位时间内能预估的会员就比较清楚.
分析活动短信或微信的转化率, 即有百分之多少的会员, 能够在收到通知后, 立即点击链接来参与活动.
通常会有一个比例, 但也有可能因为活动力度问题, 比例不太一致.
总之, 为了系统能文件运营, 要用预估的峰值去跑.
而数据库的线程池: 可以根据预估的峰值, 参考之后进行设置.
线程池的原理:
其实线程池的原理很简单, 类似于操作系统中的缓冲区的概念, 它的流程如下:
先启动若干数量的线程, 并让这些线程都处于睡眠状态, 当客户端有一个新请求时, 就会唤醒线程池中的某一个睡眠线程, 让它来处理客户端的这个请求,
当处理完这个请求后, 线程又处于睡眠状态.
可能你也许会问: 为什么要搞得这么麻烦, 如果每当客户端有新的请求时, 我就创建一个新的线程不就完了?
这也许是个不错的方法, 因为它能使得你编写代码相对容易一些, 但你却忽略了一个重要的问题?
那就是性能!
就拿我所在的单位来说, 我的单位是一个省级数据大集中的银行网络中心, 高峰期每秒的客户端请求并发数超过 100,
如果为每个客户端请求创建一个新线程的话,
那耗费的 CPU 时间和内存将是惊人的,
如果采用一个拥有 200 个线程的线程池,
那将会节约大量的系统资源, 使得更多的 CPU 时间和内存用来处理实际的商业应用,
而不是频繁的线程创建与销毁.
先看以下图:
图中两次压测, 并发数一样, 数据库连接池不一样, 上一个是 10, 下面的一个是 100, 并发数都是 100, 连接池大的时候, 吞吐量要大很多.
并且由于并发数大于连接池, 导致上面的错误率很高, 大多数的错误原因是:
Cannot get a connection, pool error Timeout waiting for idle object
实验的结果
从第一次到第四次结果来看
当 DB 的最大连接数: 当并发数 <= 最大链接数的时候, 且启动时间慢, 相当于请求来了, 就能处理.
此时相等时间内的总请求数相近, 吞吐量彼此相近.
当 DB 的最大链接 > 当前并发数, 且启动时间慢,
此时相等时间内的总请求数相近, 吞吐量彼此相近.
一般来讲, 现在都是前后端分离的系统, 面向的是全网的受众,
我觉得启动时间, 设置为 1, 比较合适;
当然, 我这边没有去监控 MySQL 所在机器的 CPU 和内存情况.
第九次和第十次的结果也可以看出, 并发数如果大于了 DB 连接数,
相同时间内, 第九次的处理的总的请求数明显大于第十次, 吞吐量自然也高;
第十次吞吐量比第九次低了很多, 且错误率达到 7%, 错误原因是:
不需要总是不停的去进行上下文切换,
第 6 次的失败原因:
- Cannot create PoolableConnectionFactory (Communications link failure
- The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.)
来源: https://www.cnblogs.com/qianjinyan/p/10249332.html