杭州网站建设设计公司,网站建设用户需求调查,西安网站建设ruiqinet,怎样查看网站的访问量最近又遇到了一次慢查把db#xff08;mariadb10)几乎打挂的案例#xff0c;作为一个核心支付系统的技术负责人#xff0c;真是每日如履薄冰。因为之前支付系统经常出问题#xff0c;现在各个BG对支付系统都盯得很紧。这次要不是我及时让DB给暴力清理数据#xff0c;没准又…最近又遇到了一次慢查把dbmariadb10)几乎打挂的案例作为一个核心支付系统的技术负责人真是每日如履薄冰。因为之前支付系统经常出问题现在各个BG对支付系统都盯得很紧。这次要不是我及时让DB给暴力清理数据没准又提一个P2故障 抱怨归抱怨事后复盘一丝都不能马虎。首先描述一下故障的全过程。起因是我们支付系统有一个异步队列这个队列使用的一张mysql表存储异步回调业务线的任务姑且表名称叫task)都会首先放这里。同时这个task表还有其他的异步任务不同的任务使用task_type字段来进行区分。然后应用系统有一个定时任务扫描这张表是否有待消费的任务如果有则会取出来进行消费典型的生产者消费者模型 这里的task说的再具体一点 1、所有的异步任务都在这张表有支付成功通知业务线消息有给结算系统推送支付信息的任务 2、消费者在任务处理成功后则会把任务从task表删除。所以这张表经常是空的 消费者根据不同的任务调用不同的上游订单系统和结算系统。出故障时是因为推送支付信息的结算系统接口超时出了问题导致任务被积压到了task表。 任务积压之后消费者线程池很快就被积压的任务占满导致应该通知BG订单支付成功的任务也被block住进而影响到订单支付成功率。 当时我已经意识到我们的消费者线程池隔离没有做到位立刻找DBA将推送给结算系统的任务进行了备份并清理。并且嘱咐DBA定时清理推送结算任务的数据。这样才化解支付成功率继续下滑的趋势。 危机解除后我们和DBA配合进一步排查问题找出了事情的根本原因。 原来是推送结算信息的逻辑中有一个对task表的查询而这个查询的sql没有建索引。这样当这类任务数量积压的比较多时查询会越来越慢慢查导致mysql堵塞。堵塞导致消费者无法拉取任务进而影响到其他通知BG的任务的消费我们分析了一下日志其实我们的程序查询数量当时3分钟大概查询了1万多次可以说qps不多。但是问题出现在sql无法命中索引把mysql的worker thread都用完了。给我们研发的感觉mysql是如此的脆弱2w多条数据查询没有索引几千个select,就能把它打挂。 几乎类似的案例一年前我们也碰到过一次。当时支付系统有一个bug用户每支付一次都会把支付客史中一个月之前的数据都清理一下1月1日清12月1日之前的数据2月1清理1月1日之前的数据。这个bug藏的很深这块代码也很少有业务需求一直没有被发现。但是是雷就会有爆炸的一天。3月1日凌晨支付系统突然所有接口都挂了。DBA最终定位是删除支付客史的sql。这个问题我们研发一开始是不承认的毕竟这个sql,在线上跑了2年多一直没有出过问题。DBA说这个delete语句删3000w数据而且在不断的请求,数据库当然扛不住我们反驳说这个客史表一共才3000w数据。事后我们发现DBA的描述有误不是说删除3000w而是这个delete语句没有走索引每次要扫描3000w数据。这样才能解释通也就是说这个delete进行了全表扫描。而实际上这个delete是按照时间删除的并且时间字段是有单列索引的但是为什么这个delete没有走索引呢我们最后猜测可能是因为2月份天数太少导致。以前可能数据比较少每次删一天或者2天的数据mysql可能会走索引。但是3月1日比较特殊因2月28日删的是1月28日一天的数据3月1日却要删除1月29,30,31三天的数据mysql可能认为删除这么多数据没有必要走索引了。 遇到类似问题如何解决 1、读写分离。 2、提前消灭慢查询 3、对异步任务做好线程隔离 关于mysql的线程池我最近也了解了一下收获也不小给大家推荐一篇好文章 https://www.jianshu.com/p/88e606eca2a5 关注我的公众号“猿界汪汪队”,关注大并发架构实战。 转载于:https://www.cnblogs.com/donlianli/p/11068095.html