1 背景

最近石墨文档线上业务出现了一些性能问题,在突发流量情况下,有个业务性能急剧下降。该服务是依赖于数据库的业务,会批量获取数据库里的数据。在经过一系列的排查过程后,发现该服务到数据库的连接数经常超过MaxIdleConns,因此怀疑是数据库的配置导致的性能问题,所以以下针对数据库的代码进行了剖析,并做了相关实验。

2 配置解读

maxIdleCountint//zeromeansdefaultMaxIdleConns;negativemeans0maxOpen      int          // <= 0 means unlimitedmaxLifetime    time.Duration     // maximum amount of time a connection may be reusedmaxIdleTimetime.Duration//maximumamountoftimeaconnectionmaybeidlebeforebeingclosed

maxIdleCount 最大空闲连接数,默认不配置,是2个最大空闲连接

maxOpen 最大连接数,默认不配置,是不限制最大连接数

maxLifetime 连接最大存活时间

maxIdleTime 空闲连接最大存活时间

3 源码解析

我们的场景是客户端与MySQL建立的连接数经常大于最大空闲连接数,这会导致什么问题?我们看下下图中的源码。

我们可以看到,当最大空闲连接数小于客户端与数据库建立的连接数的时候,那么就会返回false,并且最大连接数关闭计数器加1。

然后上图中,我们就可以看到,连接被关闭了(MySQL源码里也不留点缓冲时间再关闭)。Go的MySQL客户端这个操作,就会导致当突发流量情况下,由于请求量级过大,超过了最大空闲连接数的负载,那么新的连接在放入连接池的时候,会被无情的关闭,变成短连接,导致你的服务性能进一步恶化。

4 实验

4.1 模拟线上并发数大于MaxIdConns情况

测试代码 , 为了检测以上逻辑,假设了以下场景,设置最大连接数为100,最大空闲连接数为1,并发数为10的goroutine来请求数据库。我们通过MySQL的stats的maxIdleClosed的统计,可以看到下图,我们的连接不停的被关闭。

4.2 模拟线上并发数小于MaxIdConns情况

测试代码 ,假设了以下场景,设置最大连接数为100,最大空闲连接数为20,并发数为10的goroutine来请求数据库,可以看到下图中,无MaxIdleClosed的关闭统计。

4.3 抓包验证线上并发数大于MaxIdConns情况

测试代码 ,为了验证没有理解错代码,抓个包最稳妥。我们将main函数里放个select{},程序执行完mysql的语句后,看下tcp状态和抓包数据。

可以发现确实是tcp的状态统计与MySQL客户端的统计是一致的,并且存在fin包。

5 总结

当突发流量情况下,由于请求量级过大,超过了最大空闲连接数的负载,那么新的连接在放入连接池的时候,会被关闭,将连接变成短连接,导致服务性能进一步恶化。为了避免这种情况,下面列举了,可以优化的措施。

提前将maxIdleConns设大,避免出现短连接

做好mysql读写分离

提升mysql的吞吐量:精简返回字段,没必要的字段不要返回,能够够快复用连接

吞吐量的包尽量不要太大,避免分包

优化连接池,当客户端到MySQL的连接数大于最大空闲连接的时候,关闭能够做一下延迟(官方不支持,估计只能自己实现)

读请求的最好不要放MySQL里,尽量放redis里

6 测试代码

https://github.com/gotomicro/test/tree/main/gorm

更多相关文章

  1. JNI 无法确定Bitmap的签名
  2. android webview 中网页数据与js交互
  3. Android(安卓)3.0之后开机无法接收系统广播权限原因
  4. Android(安卓)Studio编译报Default interface methods are only
  5. ListView setOnItemClickListener无效原因详细分析
  6. ListView setOnItemClickListener无效原因分析
  7. ListView setOnItemClickListener无效原因详细分析
  8. Android常见错误处理
  9. Android(安卓)错误信息集锦(持续更新)

随机推荐

  1. android 应用移植到ophone 平台需注意
  2. 设置TextView文字居中
  3. Android 音视频汇总
  4. Android内嵌H5(1)
  5. Android学习笔记(2)---android字体风格设置
  6. 关于linearLayout的中 android:layout_we
  7. Android中Activity启动模式详解
  8. listview android:cacheColorHint,androi
  9. android的一些常用属性的说明
  10. gravity 和 layout_grativy 区别