大年三十前夕用户吐槽活动很卡

大年三十前夕,用户反馈线上活动页面访问很慢,体验较差。

要放假了,但我心里没慌,观察活动页面,加载的确很卡,极其不流畅,但Web资源依稀可load出来。

这个场景太熟悉了,毕竟以前遇到过,心里基本有底,直觉告诉我是DB问题,但还是按自己排查习惯来。

记录下整个排查过程:

Ping

首先ping下域名,延迟正常,没有丢包情况,同时页面能访问,证明webserver也是ok的,nginx解析html这一部至少没问题。

结论:nginx没挂,DNS解析正常

php-fpm和nignx排查

检查XHR接口,可以看到有接口耗时20s+,这显然是有问题。xhr接口

此时,假设是否HTTP接口在处理的时候压力过大,但上线前经过多次压力测试,QPS可以承受2000+,查看此刻接口调用QPS在50以内,很低,远远没达到瓶颈。

检查web机器,cpu总占用率不到20%。php-fpm和nginx资源占用率也非常低,php-fpm进程cpu占用率最大不过1%,证明php-fpm处理能力没有问题,而且我特地使用static模式,拉起足够多的php-fpm进程应对。

结论:php-fpm和nginx、web机器也hold得住

代码排查

既然xhr发现接口有执行过长的问题,在程序中埋点,记录每个分支逻辑的执行时长,打印log分析。这一步比较枯燥,不过有收获,在一次次的试探中,发现每次执行和DB相关的逻辑,时间较长。难道DB会hold不住?但即使hold不住,也该有cache层挡着。

结论:DB可能hold不住

Sql排查

既然怀疑DB,那么选取线上一条执行频率最高的语句check一下:

select * from table where user_id = xxx and other1 = 'xxx' and other2 = 'xxx'

分析该sql语句,有很大问题,如下所示:

explain  select * from table where user_id = xxx and other1 = 'xxx' and other2 = 'xxx'

sql分析
它的执行效率贼差,这条sql查询几秒才出结果,而type居然是个ALL,这是不科学的,user_id、other1、other2都加了复合索引,单表数据弄到几百万也测过,是毫秒内拉取。

由上可知复合索引肯定没有生效,再三定位,终于发现原因,请看如下sql:

explain  select * from table where user_id = 'xxx' and other1 = 'xxx' and other2 = 'xxx'

sql分析2

我们可以看见这次的分析,type为const,这就非常优秀了,最多只返回一行数据, const 查询速度非常快, 因为它仅仅读取一次即可。但这两条sql有什么不同呢?!没错!就是一个通过string类型查询,一个是通过int类型查询,整型的时候复合索引是完全没生效的,因为user_id本身是string类型。

于是乎,把代码改了,噼里啪啦发布。一打开网页,瞬间不卡了。

以为事情就此结束?NO,毕竟要过年,没那么简单。

结论:索引没有生效,查询效率低下

DB问题

第二天下午,用户仍然反馈活动很卡,我抽取其中一个接口,获得一个关键信息:页面的nginx报502

php-fpm没问题,但会不会是连接DB后一直没响应呢,造成php-fpm无法返回,nginx不知道怎么办,都说是自己的错。

这一次,决定去MySql服务器上查查,果然还有问题:
请输入图片描述

可以看到MySql磁盘IO很高,就是下午3点多的时候。此时看下慢查询,不查则已,一查惊人。在其他业务下,连接同一个DB server,慢查询达到了20秒以上的sql非常多。其中一个日志文件就有12467条慢查询,并且查询时间在几十秒以上的也有几百条,查询效率可想而知。

慢查询记录数
解决方法把所有慢查询的sql优化掉,该删删,该改改。

结论:慢查询过多问题暴露。初步怀疑慢查询导致Mysql服务器cpu占用率过高和IO负载过高,造成Mysql没有正常返回给php,php-fpm无法返回结果,因此nginx一直等待,无法响应,报502 Bad Gateway。

Cache排查

前面提到,即使DB被穿透,但穿透前理论上cache能hold住,redis的扛并发能力是耳熟能详的,压测QPS也是过万,应对活动高峰时期在可控范围内。

于是乎又在代码中乏味地调试,一行一行地定位。终于,在夜深人静的晚上,我发现业务逻辑存在一个bug:
数据写入cache后,cache会重置,相当于每次写入cache就丢失,所以高峰期一来,用户数据只要变动,redis未生效就会造成缓存雪崩效应,请求全部穿透缓存抵达DB,而DB刚好因为慢查询处理不过来,造成了网页很卡或者接口502。

结论:cache层被穿透,缓存雪崩

优化前和优化后效果对比

优化后,MySql服务器的cpu使用率在高峰期也大大降低,几乎还有空闲的情况(业务逻辑中DB操作很少),而在7号没有优化前使用率最高达到94,这也难怪活动页面会很卡。

总结

解决方式:
1、优化sql,使得索引生效
2、修复业务bug,保证cache命中率
3、去掉多余的索引,保证写入效率

排查后,通过上面三种方式彻底解决问题,整个春节过得相对舒心。

已有 8 条评论
  1. MarkAneta

    cialis vs viagra reddit news
    buy cialis now
    patanol tem generico de cialis
    cialis canada

    MarkAneta 回复
  2. MarkAneta

    5 mg cialis canada
    trust pharmacy cialis
    cialis 20mg in holland kaufen
    buy tadalafil online

    MarkAneta 回复
  3. MarkAneta

    cialis expensive
    buy 20mg cialis
    globalpost cialis
    buy 20 mg cialis

    MarkAneta 回复
  4. MarkAneta

    section chief cialis
    cialis jelly online mail-order pharmacies
    biljni cialis commercial
    cialis on line

    MarkAneta 回复
  5. MarkAneta

    which is best viagra levitra or cialis
    cheap generic cialis
    allina procap bijwerkingen cialis
    cialis coupons

    MarkAneta 回复
  6. MarkAneta

    orelox generico de cialis
    tadalafil
    cialis pills 20 mg picture
    cheap cialis

    MarkAneta 回复
  7. MarkAneta

    dapril 5mg cialis
    cheap cialis
    cialis generic tadalafil india
    purchasing cialis on the internet

    MarkAneta 回复
  8. MarkAneta

    buy cialis cheap us pharmacy
    cialis coupons
    ncelab generic cialis
    cheap cialis

    MarkAneta 回复
发表新评论