系统延迟优化的思路(go语言)

299 阅读2分钟

1、分析问题所在

  • 进程内部:网络IO , 磁盘IO , CPU调度达到瓶颈等
  • 第三方系统:MySQL、redis等基础组件调度慢

2、出问题了

使用Postman模拟大量的请求,可以发现,当请求数过高的时候 ,sql的响应会超过两秒,太慢了(对mysql操作添加钩子函数,对执行前后的位置进行计时,可以得到数据库操作所需要的时间)

3、寻找问题所在

3.1 排查sql慢查询问题

针对这个问题,首先查看了后台的慢查询日志,并没有慢查询日志被打印下来,并且单独重新执行该sql语句,其执行时间仍在毫秒级,说明并非是mysql写法本身带来的问题

3.2 排查系统指标

在系统运行期间,查看系统CPU的占用率、网络带宽、系统负载等,均在25%附近,尚未达到瓶颈,仅在高峰期有所波动

3.2.1 程序是否在执行一个cpu使用率不高的动作

(并没有在执行用户代码,比如在调度的时候) 使用一个 go 语言编写的 fg prof工具,可以查看应用程序等待cpu所消耗的时间。 也可以使用 go tool pprof来查看cpu真正执行的时间。在本次应用中,cpu使用率不高,所以,问题大概率出在了等待cpu的时间消耗上。

通过fg prof,可以找到占用off cpu过高的一个方法,该方法是在进行一个sql操作。通过之前的分析,它并不是因为慢查询导致的 ,而是因为cpu在withLock和等待数据库返回数据时耗费了大量的等待时间。但是在这里也只能看出这部分代码等待cpu的时间占等待时间的大部分,无法确定程序真正的等待时间。可以猜测,这个接口在高频地进行阻塞操作,导致这个接口在对外暴漏地时候,有一部分接口响应时间会过长。

3.2.2 用go trace分析系统延迟

基于以上分析,已经大致定位出问题所在的代码 ,但是还没有得到具体的信息。为了拿到具体的信息,可以使用go trace来详细分析程序运行时的动作。

4 根据分析出来的问题进行优化

虽然程序的执行不是因为慢查询导致的 ,但是最终原因,还是数据库操作导致的。所以解决办法可以是,减少数据库的操作,尽可能减少网络阻塞操作。另外也可以将重点数据存储到内存中,通过内存直接查询。