接口异步调用导致的一个低概率问题引发的思考。

最近5个月接触到的异步调用占工作以来接触到的一半以上,这些异步调用都是消费消息的方式。

应用A在处理完业务后,需要调用应用B的接口做信息同步(记录数据或者更新数据),有两种方式:

一般情况是采用同步方式,等待应用B的接口处理完后,拿到返回值,继续后续处理。这样的好处是可以根据应用B的接口返回值来做接下来的数据处理:如果B失败了,可以数据回滚;或者使用应用B的接口返回数据继续业务处理。

还有一种比较少的方式是异步:有发消息的,也有往系统插入一条定时任务数据的。这种方式的好处时不用等待调用方处理,节省响应时间。缺点是,不知道调用方处理结果,如果调用方不通过发邮件,或者反调原系统接口,这次调用方处理结果都可能不被感知。

我这次遇到的问题其实不是异步调用失败,专门测试功能是会发现异步调用失败的。我这次遇到的问题是消息在消息队列排队太久了:运营角色在订单端处理订单后,将消息发出来,进入了消息队列,结果15秒后运营角色处理第二个订单时,这个消息还在消息队列,没有被活动端处理,而第二个订单就因为这个原因失败。 消息不是同步,所以生产者和消费者之间数据会有时间差。一般测试环境因为请求不频繁消息中心几乎没压力,所以异步看起来像同步,而这次是运气好,发现了这个问题。也因此发现了系统其实还存在可以完善的地方,数据时间差可能导致的问题没有做邮件通知,异步任务失败(上线后基本不会存在)后没有邮件通知。

我遇到的这个问题,如果用异步,是解决不了问题的,只能通过代码改进,来减少问题发生的概率;改用同步才能解决这个问题,然而同步存在响应时间长的问题。我们唯一能做的就是,在异常情况发生时,第一时间邮件通知大家,不要等到几天后才被用户发现。

原文地址:https://www.cnblogs.com/jefzha/p/10657661.html

时间: 2024-08-30 03:07:36

接口异步调用导致的一个低概率问题引发的思考。的相关文章

一个截取字符串函数引发的思考

背景 前些天,遇到这样一个问题,问题的内容如下: 要求编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串.但是要保证汉字不被截半个,如"我ABC", 4,截取后的效果应该为"我AB",输入"我ABC汉DEF", 6,应该输出为"我ABC",而不是"我ABC+汉的半个". 问题 刚看到这个问题的时候,以为还是很简单的,但写出来之后,发现并不是想要的效果.回想一下当时的思路,就发现刚开

异步调用导致的不同步问题

业务场景:点击一个按钮的时候保存数据,同时打开一个弹窗带出保存的数据 基于这样的业务场景,最近遇到一个问题,是在ie11才发现的,点击按钮时候,后台打断点加数据库查询都验证数据是保存正确的,不过已经保存的数据是带不到弹窗页面的,问题比较奇怪,排查了挺长时间,最开始因为在ie才能重现的问题,在极速模式的360浏览器是没问题的,而且第一次点击时候没带出数据,第二次点击时候才可以带出数据,然后很容易让人联想到ie的缓存问题,不过调了大半天 加上ajax不缓存的代码,已经改成post请求,或者get请求

一次慢日志撑爆磁盘导致的业务主库宕机引发的思考

在MySQL的日常维护中,我们总会遇到这样或那样的问题,对于那些经常发生且有处理经验的事故,不论是新手还是老司机都能在故障规定的容错时间内解决.而对于那些不常见.比较棘手的问题,新手上路可能就显得举足无措了,这个时候新手和老司机的差距就体现出来了.从知识储备还是工作经验,可能老司机比新手强一点,但如果一个新司机没有日志排错的意识,不具备日志排错的经验,那怎么能学会弯道超车.漂移的快感.我们知道数据库中有很多重要的日志,如错误日志error log.慢日志slow log.二进制日志binary

一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)

首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自己平时学习中不会发现的问题,所以想写下这个博客,主要是便于自己对算法的理解. 来,上题. DNA Sorting Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 91599   Accepted: 36781 Descript

一个数据交换函数引发的思考

近日,在书中看到一个关于数据交换函数的源代码,发现挺有意思,具体代码如下: 1 void swap(int* a, int* b) 2 { 3 *a ^= *b ^= *a ^= *b; 4 } 根据 C 语言异或赋值操作符(^=)的计算规则和异或运算符(^)的运算法则,应按照从右到左的顺序进行计算,具体计算过程演示如下: 1 *a = *a ^ *b; 2 *b = *b ^ *a = *b ^ ( *a ^ *b ) = *a; //将式1代入 3 *a = *a ^ *b = ( *a ^

0.28+0.34=? 一个简单小数加法引发的思考

0.28+0.34=? 我相信这个简单的加法,谁都会,肯定等于0.62嘛. 这是两个特别简单的加法,那如果我在其整数位置上加上其他的数字,或者多加几个和项,你是否还能快速算过来? 我想这时候,我们又得借助计算器了!而这,有时可能就是电脑!尤其是如果咱们借助简单程序语言来算的时候,嘿嘿,可能就不是那么回事了~ 不信你看,用javascript算的结果: 用python算的结果: 当然了,我尝试着用其他语言来试一下,结果好像并不都是这样. 其中,java只会在类型转换的时候出现奇怪的值:(当然这在我

一位牛人的多线程和异步调用文章

转自小顾问原文 一位牛人的多线程和异步调用文章 首先申明:这篇文章不是我写的,我看到的一位牛人的,自己慢慢的消化了…… 摘要:本章讨论与智能客户端应用程序中多线程的使用有关的问题.为了最大限度地提高智能客户端应用程序的响应能力,需要仔细考虑如何和何时使用多线程.线程可以大大提高应用程序的可用性和性能,但是当您确定它们将如何与用户界面交互时,需要对其进行非常仔细的考虑. 线程是基本执行单元.单线程执行一系列应用程序指令,并且在应用程序中从头到尾都经由单一的逻辑路径.所有的应用程序都至少有一个线程,

客户端的异步调用

C#客户端的异步操作 阅读目录 开始 示例项目介绍 同步调用服务 异步接口介绍 1. 委托异步调用 2. 使用IAsyncResult接口实现异步调用 3. 基于事件的异步调用模式 4. 创建新线程的异步方式 5. 使用线程池的异步方式 6. 使用BackgroundWorker实现异步调用 客户端的其它代码 各种异步方式的优缺点 异步文件I/O操作 数据库的异步操作 异步设计的使用总结 在Asp.net中使用异步 上篇博客[用Asp.net写自己的服务框架] 我讲述了如何实现自己的服务框架,但

C#同步和异步调用

这篇文章仅当总结之用,参考了很多前辈们的文章,加上了点点自己的理解 C#的同步和异步线程是依靠委托来完成,主要需要用到委托的Invoke方法,BeginInvoke和EndInvoke方法 所谓同步线就是阻塞当前线程来完成调用的方法,然后才继续调用当前线程的后面的操作,实际上都是在同一个线程中执行,效率不高.需要用到Invoke方法 异步线程不阻塞当前线程,而是把需要调用的方法加入线程池中,来同步执行,即同一时间两个及其以上的线程共同都在执行,效率很高.需要用到BeginInvoke和EndIn