记一次自动恢复的支付故障

故障描述

作为一个老牌OTA公司,公司早些年订单主要来源是PC网站和呼叫中心。我在入职公司大约半年后,遇到一次非常诡异的故障。有一天早上,大概也是这个季节,阳光明媚,程序猿刚起床,洗洗涮涮,准备去迎接初恋般的工作日,却突然收到一大堆报警,线上消息队列大量积压;当然,我还是一如既往的非常勤奋地在9点之前就到公司的;但是作为一名新员工,环视四周,组内其他员工都还没到公司,运维也都在路上,故障就这样突然降临了。我赶紧开机登录堡垒机,连接线上机器,tail 错误日志。但是线上10几个系统,我看了好几个系统,都没有发现有什么错误,这就尴尬了。但是统计消息队列,超过好几千的消息待消费。我当时就在想,这些消息都是什么鬼。截图如下:

图一

看到这里,你一定会问数量为604和881个的消息是做什么?知道这些消息的逻辑不就解决问题了么?话说当时我也是这么想的,可是当时我作为一名新人,才开始接触业务不到3个月,还完全没有这么深的业务积累(这个时候知道业务是多么重要)。

既然系统看不到任何错误,我也没有什么办法了,当时因为刚入职没多久,还有点寄希望于领导来解决。转眼间半个小时已经过去,故障仍然没有恢复,从业务反馈来看,微信支付宝等支付方式不受影响。受影响的只是信用卡支付(其实当时信用卡量占比挺高)和分销支付(后来了解到,其实这两种模式都是信用卡支付模式)。领导还在堵车,运维也只是到了几个小兵,我找运维把几个机器的stack打印了一下,也没有发现什么问题;运维也陆续到岗,运维准备出大招,重启系统。但是就在此时,突然系统自动恢复了。所有积压的消息自动被消费,信用卡支付也可以了。好,系统竟然有自我修复功能,佩服;

故障原因分析

后来,经过一番努力,还是找到一点蛛丝马迹,我发现系统的一个消费消息的定时任务,在故障期间一直在报错,因为是高可用的job机制,4台机器,只有抢占到锁的服务器才能获取到访问数据库消息权利,所以报错信息比较分散,4台机器都有。

图二

可以判定,这个sql一直异常导致job根本无法获取到消息,而另外的生产者又不断的往队列放消息,进而导致消息积压。两个系统关系如下:

图三

虽然故障总结了,但是我们心里也不踏实,如何找到系统故障的根本原因,以防止以后再次出现这种故障呢?

方法有两种:

1、去查代码,所有跟这个表相关的sql,都需要仔细review一下,但是你也不一定能查到原因,因为这个场景肯定是不好复现的,要不然早就发现这个问题了。

2、借助外力,从DB层面查导致这个sql无法执行成功的原因;

方法1看似简单,其实非常不可行。首先,虽然跟这个表相关的sql,只有几十个,但是都是正常的sql,没有使用for update锁死表的sql。也没有存在未关闭的事务,因为事务是通过AOP配置的;

所以只能寄希望于方法2了,让DBA去查;

好歹我们的DBA足够给力,只用了1天多的时间就查出来了。

DBA回复如下:

1、有事务没有及时提交,且连接也没有关闭,导致该事务一直处于开启状态并持有锁,后续update操作是全表扫描,因此会有锁等待。

2、最后该连接后续一直没有操作,达到空闲超时3600秒(我们的故障时间正好也是1小时)后被mysql server断开,锁才被释放。(mysql设置:wait_timeout = 3600)

最牛B的是DBA贴出了没有提交事务的SQL;sql我就不贴出来了,我们根据DBA提供的线索,找到了代码的问题;

故障根本原因

后来我们查看代码,如上面DBA所说,消息没有被消费处理,是因为有一个mysql客户端,即我们的支付应用程序,在进行快捷支付的时候,向队列插入一条记录,然后在事务中向第三方发起了调用。使用的是httpclient工具发起的调用,但是设置超时时,只设置了连接超时时间(connectionTimeout)为30秒,没有设置响应超时时间(soTimeout),这样当出现网络问题时,程序就会一直等第三方响应,然后事务也一直没有提交。而在job程序中,需要将这个queue的所有记录给更新,但是又取不到表锁(见图三),就不断的报lock wait timeout的错误;其实对使用spring AOP框架的研发,很容易犯这种错误。我们从 https://tech.meituan.com/2018/04/19/trade-high-availability-in-action.html 这篇总结里面的1.5段也能看出,美团支付也在这块也栽过坑;

图四

到这里,其实故障原因已经很清楚了,我们在代码层面也确实查到了问题。因为DBA提供的sql中,连insert sql的主机名也列了出来,并且现场没有被破坏,我们使用jstack应该还能找到正在等待的线程才对;于是在时隔故障2天后,我们又让运维把那台机器的jvm stack给打印了一下,果然发现等待的线程仍然存在

堆栈如下:

图五

与之对应的代码,我就不贴了;

解决方法

1、临时解决方法,将响应超时时间设置上,但这无法根除问题,只是降低再次出现问题的概率;

2、长久解决方案,修改框架,使用编程式事务,将所有远程调用从事务中剥离出来。

知识点

1、事务,spring AOP

2、httpclient,超时设置

求关注

原文地址:https://www.cnblogs.com/donlianli/p/10837869.html

时间: 2024-10-20 08:16:13

记一次自动恢复的支付故障的相关文章

SCOM 2012 R2_自动恢复服务脚本

最近做了几个SCOM的项目,也碰少不少情况,以后会陆续将一些项目的部署实施发布出来.今天就简单介绍如何在SCOM服务器监控Windows服务的同时,当SCOM检测到Agent客户端的服务Down掉的时候,Agent会自动恢复服务,而减少故障的滞后性,实现IT管理的自动化的过程. 1. 在SCOM控制面板,点击"创作-管理包对象-监视器": 2. 右击监视器,选择"新建监视器-单元监视器": 3. 在监视器类型,点击"windows服务-基本服务监控器&qu

[办公自动化]计算机突然死机后asd自动恢复文档未能恢复,如何使用

今天计算机突然死机,但是word未能提示自动恢复窗格.所以无法自动恢复word文档.但是在文档所在的文件夹看到了一个“自动恢复”开头的asd恢复文档. 该如何使用这个文档呢? 安装以前的惯例,尝试了如下方法: 1)直接双击无法打开. 2)修改后缀为docx也无法使用. 最后经查阅word帮助文档,可以在word中,单击“打开”文档界面,直接选中打开自动恢复文档“asd”文件,另存为docx文档,就一切恢复正常了. [读书时间] 1.Excel Home出版的系列书籍 2.刘万祥<Excel图表之

什么是oracle自动恢复操作

这是由系统进行的恢复.无需人的管理和操作.一般当系统由于突然掉电而出现故障时用这种方法.当再次启动数据库就会进行自动恢复.    不像简单的DOS系统,oracle系统在运行时有许多事务要处理,并且存在许多进程.无论此时人是否对系统进行了操作,这些事务和进程都是存在并运行着的.因此,oracle系统非常复杂,绝不允许中途突然关电源,那样会使系统受到损害.    但是有时并非人自愿的,电源不好而突然掉电,或是未通知的突然停电,而又没有使用不间断电源UPS,则此时数据库系统将难免受到损害.由于掉电,

新一代-亚马逊自动恢复EC2系统

构造高可用性和高可靠性系统的一项重要原则是假定失效(Design forfailure).换言之,你的设计模型应具有正如亚马逊的首席技术官(CTO)沃纳?威格尔(Werner Vogels)曾说的"一切事物随时有可能失效"的特性.幸运的是,现代数据中心.网络和服务器具有高可靠性,且很少发生故障.然而,若你把偶尔的故障当成是既定的,并简单建立一个在发生故障后能恢复且保持运行的系统,则你能建立一个强大的系统. 新一代自动恢复 今天我想告诉你一个新的EC2功能,当某项EC2实例遭受损害时,该

htc M8 无法自动恢复数据连接(4g)的问题解决

情况如下:htc m8 tdd-lte的双待手机,4g.2g同时在线. 本月出现,在短时间没有信号的情况后,无法恢复数据连接,哪怕是edge,更不论4g了. 尝试各种方法无解.最后咨询10086解决此问题. 这个应该不是手机的问题,貌似是移动端的2g edge数据流量被关闭/错误设置导致的.   我感觉像是2g-3g-4g之间切换需要依次回落或者升级.因为双待,4g信号开机是有的,可以上网,但是电梯等4g消失的情况发生后,需要借助于2g/3g的数据连接再恢复到4g,没有2g/3g的数据连接就恢复

vs生成配置release自动恢复成debug无法配置的问题

软件为visual studio 2015,右键单个项目选属性,设置“生成配置”release,保存后,再次右键属性,却发现又自动恢复成debug,怎么回事?是无法配置吗?点击生成试试,果然2b了. 解决方法: 在整个解决方案上右键属性,然后选配置属性-->配置--> 一一配置需要设置release的项目,然后保存即可.

HDFS中datanode节点block损坏后的自动恢复过程

相关参数说明 dfs.blockreport.intervalMsec :datanode向namenode报告块信息的时间间隔,默认6小时 datanode日志中记录如下: dfs.datanode.directoryscan.interval:datanode进行内存和磁盘数据集块校验,更新内存中的信息和磁盘中信息的不一致情况,默认6小时 datanode日志中记录如下: 测试机器: 10.0.50.144  master  (namenode,datanode) 10.0.50.145  

支持宕机自动恢复触发一次性或周期性任务执行的组件包-easyTask

easyTask 一个方便触发一次性或周期性任务执行的工具包,支持海量,高并发,高可用,宕机自动恢复任务 开源项目地址:https://github.com/liuche51/easyTask   请多多关注 Usage scenarios 需要精确到秒的某一时刻触发任务执行.比如订单交易完成24小时后如果客户未评价,则系统自动给出评价. 需要周期性的执行某个任务.比如每天下午6点,提醒员工下班关机. Features 使用简单 秒级精度任务执行计划 支持海量任务提交执行 支持高并发执行任务 支

CentOS 7MBR引导扇区与grub恢复(小故障不求人)

一.MBR引导扇区故障恢复MBR引导扇区位于物理硬盘的第一个扇区,该扇区又称为主引导扇区,除了包含系统引导程序的部分数据外,还包含了整个硬盘的分区表记录.所以当主引导扇区发生故障时,可能导致的的故障就是主机开机时进入黑屏状态从而无法正常开机.下面将带领大家一起学习如何在MBR扇区故障时进行恢复.通常情况下解决该故障的步骤分别是:提前对MBR扇区进行备份→以安装光盘引导进入急救模式→从备份文件中恢复.下面将详细演示MBR扇区恢复的详细过程.1.备份MBR扇区数据到其他磁盘1).创建一块新的磁盘并进