性能问题排查过程

项目场景:

记录一次性能问题排查


问题描述

前段时间,测试提出了一个性能问题,然后进行分析,这个接口是一个菜单接口,要求性能比较高,测试环境的请求时间是500并发,2.5s左右,但是实际要求是要1s内的,所以就要对这个问题进行分析。


原因分析:

1.代码主要逻辑

第一步我们先分析了该方法的代码,代码逻辑有好几部分,1.在redis获取用户信息 2、对菜单的访问量进行统计功能,并且用到了第一步的用户信息 3.从redis获取菜单信息 4.如果获取到了菜单信息,直接返回,如果获取不到信息,则从数据库查询菜单信息。

2.初步分析

大体看代码逻辑都没啥问题,首先进行了一些初步的日志打印,比如获取用户信息,统计功能,从redis获取菜单信息,都打印了耗时,然后在测试环境测试,发现从redis获取信息基本上都在500ms以上,如果是从数据库查询,时间就更久了基本上要7s左右。

3.初步优化

首先我们进行了能看到的问题进行优化,比如1,在redis获取用户信息,这个必须要做的,就不能省略,2. 访问量的统计,这个和获取菜单功能不是直接相关的,可以放到异步线程池去执行,没有必要也在主线程执行。3.从数据库获取菜单的时候,sql语句关联了一个应用表,有个应用名字需要获取,使用left join的方式,并且在后面有个in操作,in操作有可能是有性能问题的,所以优化了下sql,把where条件查的都是菜单表,所以把这些条件都放到菜单表里面去查,然后再以临时表的方式join应用表,去获取应用表的信息,这样驱动表就是最小集join,可以提高性能,并且检查了索引是否使用正确,是否建立索引。

4.再次测试

做了以上改动后,我们就再次进行测试了,然而结果却不太如意,结果好了一些,但是影响不大,后面我们也分析了,上面的改动能提高一点,但是测试环境本身数据量就不是很大,对于sql的改动是测不出来的,对于异步执行统计倒是节省了一些时间。

5.本地测试

既然环境上测试不出来,然后我们就直接本地测试算了,方便调试问题,本地启动测试500并发,时间是4.5s因为本机电脑是比不上服务器的可以理解,但是不影响调试性能。接着我怀疑是redis的问题,查看日志,发现在请求的过程中多次走了数据库,redis设置过期的时间是3分钟,但是似乎一秒就过期了,为了忽略这个问题的影响,把过期时间设置为不过期,再次测试。

6.再次测试

设置了过期时间后,不再频繁请求数据库了快了1s左右,3.5s,但是还是很慢,

7.分析

看了下载速率是950kb,一个请求的响应大概是2.5kb左右,500并发,也就是1M的数据,950kb是差不多了,带宽不是影响的原因,接着还是继续查看redis,我们用的是jedis,然后我对jedis连接池的参数进行了优化,把try(resource){}改成了使用jedispool.returnResource放回连接池中,连接池参数增加了

        poolConfig.setTimeBetweenEvictionRunsMillis(5000);
        poolConfig.setMinEvictableIdleTimeMillis(60000);
并且把原来只有100个连接改成了500个
    poolConfig.setMaxTotal(500);
    poolConfig.setMaxIdle(500);
    poolConfig.setMinIdle(10);
    poolConfig.setMaxWaitMillis(1000);    

8.测试

再次测试发现减少了1s为2.5s,有了一些优化,后面直接注释掉了获取用户信息,流量统计的代码,测试为1.4s少了1s。

9. 分析

然后怀疑是不是服务器的redis问题,我就本地装了redis去测试,连接我本地的redis,换成我本地的redis后,还是一样,就快到崩溃的边缘了。。。然后看了下redis的版本是3.1.200,怀疑是不是我版本太低了,然后去找了windows 6.0以上的版本安装,调试了一上午,结果windows上找到的安装版本基本都是用不了的,很容易就崩溃退出进程了,后面才发现,redis是不好在windows支持的,然后在本地安装了虚拟机,在虚拟机上安装了redis6.2.5版本,并且开启了多线程支持,了解过redis的应该知道6.0版本后可以开启多线程支持。
在redis.conf文件中把no改为yes,把线程改下,一般和cpu核数一致即可。

# io-threads-do-reads no
# io-threads 4

(后面发现redis版本和多线程的影响几乎为0,不是影响因素)

10.windows参数设置

上面第九步就花了半天多的时间,然后也对wiindows的参数进行了调整
一个是句柄数的设置,一个是tcp连接数的设置,调大些,不要因为这些影响到并发数,具体的参数我发调试连接出来,大家也可以自己找。
句柄数限制

  1. https://www.lmlphp.com/user/16721/article/item/460591/
    tcp连接数限制
  2. https://blog.imdst.com/windows-xia-dan-ji-zui-da-tcplian-jie-shu/
    (这个也不是问题原因,但是写出来也给大家一个思考的方向)

11. 测试

然后启动项目的时候使用java -jar的方式去启动,排查idea可能的影响,结果还是有优化的最终的结果是1.3s左右,看日志,redis请求花费时间是500ms,这个结果相对于刚开始是优化了很多,但是还是不对劲,才500并发,怎么可能从redis获取的时间这么长,redis不是这么差的,而且也不是bigkey,数据才2.5kb不是大key

12.分析

然后我就继续看日志了,请求一次,然后看完整的请求日志,然后发现日志中有去获取用户信息多次,然后我在代码中搜索该日志,发现之前多租户的代码,对redis连接池进行了一个aop拦截,也就是会拦截redis,对redis的key加上用户的信息,拦截了两次,两个方法都是@around,并且在@around里面又从redis获取了租户信息(redis操作),
也就是每次对redis进行操作,都会执行四次*2,8次操作,因为在切面方法里面又对redis进行了操作,around是前后都执行,这次找到了影响最大的问题了。我直接把这个类注释掉了,再测试

13.测试

再次测试快了非常多,500并发的情况下,redis请求耗时很短,有时候是0ms,可能是真的很快,机器都觉得不耗时了,总耗时100ms的时间,也就是从1.3s到100ms,这个切面花了1s多的时间。


解决方案:

最终的解决方案,就是删除掉了redis的切面操作,用其他方式实现了,找到了最终的根因就是对redispool的切面操作导致的,所以各位对切面操作的时候要谨慎啊,特别是对频繁使用的工具类切面。

总结

本次性能优化花费了近一周的时间,最终找到了问题的所在,总结就是性能优化需要对很多东西有了解,包括在测试过程中会对机器的性能进行查看,看看cpu,内存,带宽,磁盘的性能,是不是机器问题限制了并发,还是说是网络问题,还是说是代码问题,代码问题又涉及了刚刚的是否要全部同步操作,sql优化,索引优化,redis连接池优化等,要一个个去分析,看结果当然是很简单,找出来就不容易了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排查 MySQL 主从延迟问题过程通常如下: 1. 检查主服务器状态:连接到主服务器,并使用以下命令检查主服务器的状态信息: ```sql SHOW MASTER STATUS; ``` 确保主服务器的日志文件名称和位置。 2. 检查从服务器状态:连接到从服务器,并使用以下命令检查从服务器的状态信息: ```sql SHOW SLAVE STATUS; ``` 确保从服务器的主日志文件名称和位置与主服务器一致。 3. 检查复制线程状态:在从服务器上执行 `SHOW SLAVE STATUS;` 命令后,查看以下字段: - `Slave_IO_Running`:确保该值为 "Yes",表示复制 IO 线程正在运行。 - `Slave_SQL_Running`:确保该值为 "Yes",表示复制 SQL 线程正在运行。 - `Seconds_Behind_Master`:表示当前从服务器相对于主服务器的延迟时间(以秒为单位)。确保该值不断减小,或为0。 4. 检查网络连接:确保主服务器和从服务器之间的网络连接良好,没有丢包或延迟。可以使用 ping 命令测试网络连接。 ```bash ping <主服务器IP> ping <从服务器IP> ``` 5. 检查主服务器负载:如果主服务器负载过高,可能会导致主从延迟。使用以下命令检查主服务器的负载情况: ```sql SHOW PROCESSLIST; ``` 确认是否有大量的写入操作正在进行,如果有,请考虑优化数据库或增加硬件资源来减轻负载。 6. 检查从服务器负载:如果从服务器负载过高,也可能导致主从延迟。使用以下命令检查从服务器的负载情况: ```sql SHOW PROCESSLIST; ``` 确认是否有大量的读取操作正在进行,并考虑优化查询或增加硬件资源来减轻负载。 7. 检查复制延迟原因:如果上述步骤都没有找到延迟的原因,可以尝试以下方法: - 检查从服务器的错误日志,查看是否有错误信息或警告。 - 使用 Percona Toolkit 工具集中的 pt-heartbeat 或 pt-slave-delay 工具来监控主从延迟情况。 - 分析慢查询日志,查看是否有影响复制性能的查询。 通过以上步骤逐一排查,可以帮助您找出 MySQL 主从延迟的原因。根据具体情况可能需要结合实际的复制配置和数据库负载情况来进行排查

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值