翻车了,被读者找出 BUG
大家好呀,我是小楼。
本文是上篇文章《使用增强版 singleflight 合并事件推送,效果炸裂!》的续集,没看过前文必须要先看完才能看本文,实在不想看,拉到文章末尾,给我点个赞再退出吧~Doge
上篇文章发出后,有一位读者朋友给我发私信,写了一大段话:

一开始,没太看懂,于是就细问了一下

在看了解释之后,感觉好像有点懂了,再三思考后,确认了,这里面有 BUG。
理想状态
为了描述简单,这里我用字母本身表示事件发生,如 A,用字母加一撇表示事件开始执行,如 A',用字母加两撇表示事件执行结束后的状态,如 D''。
如下表示我们之前思考的理想状态:A 事件到来便执行,在执行结束前又先后来了 B、C、D 三个事件,先 Hold 住,待 A 执行完成后,B、C、D 同时进入 sigleflight group 中抢执行,最终结果是 D'',感觉非常完美。

对应到代码上是这样:

case 1
但这位读者提出了一个疑问,如果在 B、C、D 执行的时候又来一个 E 事件,那这个 E 事件将会重走 A 事件的路,如果这个 E 事件执行的比较快,先于 B、C、D 事件完成,那不就有问题了?

E 事件最后到,我们期望的结果应该是 E'',但按这个推理,最终结果是 D'',显然不符合预期。
case 2
同理,如果在 E 事件执行期间累积了 F、G 事件,且 F、G 也比较争气,在 B、C、D 完成之前完成了:

期望的是 G'',但最终结果是 D''。
线上有问题吗?
这两个场景确实很难测试到,如果不幸遇到,还是有风险的。我们复盘了自己的系统,发现我们的系统是可以解这个问题的。
我们的系统会针对推送下去不一致的数据会定期补偿,具体怎么做的呢?
在推送之前,针对同一种推送,也就是相同的 key 生成(存在则更新)同一条记录,该记录包含两个时间 t1、t2,推送的开始时间 tn(精确到纳秒)记录到 t1,推送完成后将 tn 记录到 t2,这两次记录在一个方法中,伪代码是这样:
tn := time.Now().UnixNano()
markT1(key, tn)
push(key)
markT2(key, tn)
如果 t1 = t2 则说明推送没有问题,如果 t1 != t2 则说明这条推送需要补偿,每 10s 扫描一次需要补偿的事件进行重新下发推送
我们以 case 1 为例,按照时间顺序
- A 执行完成时,t1= ta,t2 = ta
- D 开始执行,t1 = td
- E 开始执行,t1 = te,E 执行结束 t2 = te
- D 执行结束,t1 = te,t2 = td
- 10s 后发现 t1 != t2,于是触发重新下发逻辑,重新推送最新数据为 E''

最后
还好我们线上系统有一层保护机制,否则可能要出事。如果在 singleflight 层面去解决这个问题,暂时我还没有想到很好的办法,如果读者朋友们有好的方法,欢迎私信我。
不得不说读者朋友们当中还是有不少读了我的文章,而且认真思考了的,在此表示感谢,也欢迎大家指出文章中的错误。
最后感谢能抽空看到这里,如果你能点赞、在看、分享,我会更加感激不尽~
- 搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践
翻车了,被读者找出 BUG的更多相关文章
- python的自省函数, 快速找出BUG的良器
python内置的好多自省函数, 合理使用可快速查找相关提示, 快速找到问题点, 以下开始具体说明 1. dir() 列出对象的所有属性和方法 如: dir(list) 可以列出列表的所有属性 ...
- 找出诡异的Bug:数据怎么存不进去
带着学生做课程设计.程序一大,课程中做过了小项目,练过了分解动作,一到合起来了,难免还是要乱了分寸.事实上,实战的功夫,就是这样出来的.(课程设计指导视频链接(第36课时,3.18 银行系统开发).课 ...
- Linux企业级项目实践之网络爬虫(23)——系统测试:找出系统中的bug
为了验证爬虫的业务流程.性能和健壮性需要进行测试. 软件测试是描述一种用来促进鉴定软件的正确性.完整性.安全性和质量的过程.软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件 ...
- 如何快速定位找出SEGV内存错误的程序Bug
通过查看php日志/usr/local/php/var/log/php-fpm.log,有如下警告信息: [16-Mar-2015 16:03:09] WARNING: [pool www] chil ...
- 找出并解决 JavaScript 和 Dojo 引起的浏览器内存泄露问题
简介: 如果大量使用 JavaScript 和 Ajax 技术开发 Web 2.0 应用程序,您很有可能会遇到浏览器的内存泄漏问题.如果您有一个单页应用程序或者一个页面要处理很多 UI 操作,问题可能 ...
- 如何写出测不出bug的测试用例
我们写测试用例的目的是为了能够整理思路,把要测试的地方列出来,做为知识的积淀,用例可以交给其他测试人员执行,或者是跟需求提出者进行讨论,对用例进行补充和修改. 理论上用例写的越多,越容易发现bug.但 ...
- 快速找出网站中可能存在的XSS漏洞实践
笔者写了一些XSS漏洞的挖掘过程记录下来,方便自己也方便他人. 一.背景 在本篇文章当中会一permeate生态测试系统为例,笔者此前写过一篇文章当中笔者已经讲解如何安装permeate渗透测试系统, ...
- 快速找出网站中可能存在的XSS漏洞实践(一)
一.背景 笔者最近在慕课录制了一套XSS跨站漏洞 加强Web安全视频教程,课程当中有讲到XSS的挖掘方式,所以在录制课程之前需要做大量实践案例,最近视频已经录制完成,准备将这些XSS漏洞的挖掘过程记录 ...
- 利用PHP扩展Taint找出网站的潜在安全漏洞实践
一.背景 笔者从接触计算机后就对网络安全一直比较感兴趣,在做PHP开发后对web安全一直比较关注,2016时无意中发现Taint这个扩展,体验之后发现确实好用:不过当时在查询相关资料时候发现关注此扩展 ...
- 为什么你写的用例测不出Bug来?
我们写测试用例的目的是为了能够整理思路,把要测试的地方列出来,做为知识的积淀,用例可以交给其他测试人员执行,或者是跟需求提出者进行讨论,对用例进行补充和修改.那么为啥你写的用例测不出Bug来呢,真的是 ...
随机推荐
- JS逆向实战12——某店 captchaToken 参数 加密
今天爬取的是网站需要模拟登陆 目标网站 aHR0cHM6Ly9wYXNzcG9ydC55aGQuY29tL3Bhc3Nwb3J0L2xvZ2luX2lucHV0LmRv 浏览器抓包分析 随便输入一堆假 ...
- C#/VB.NET:如何将PDF转为PDF/A
PDF/A是一种ISO标准的PDF文件格式版本,是为长期保存文件而设计的.它提供了一种工具,使电子文件在长时间之后依然以一种保留其外观的方式重现,而不管该文件是用什么工具和系统创建.储存或制作的.这种 ...
- 【Contest】Nowcoder 假日团队赛1 题解+赛后总结
比赛链接 通过顺序:\(B\rightarrow D\rightarrow I\rightarrow J\rightarrow G\rightarrow H \rightarrow A \righta ...
- 【Vue项目】尚品汇(三)Home模块+Floor模块+Swiper轮播图
写在前面 今天是7.23,这一篇内容主要完成了Home模块和部分Search模块的开发,主要是使用了swiper轮播图插件获取vuex仓库数据展示组件以及其他信息. 1 Search模块 1.1 Se ...
- C# 获取系统已安装的.NET版本
获取系统已安装的.NET版本,来确定当前应用可运行的环境. 微软已经有相应的完整文档,请参考:确定已安装的 .NET Framework 版本 - .NET Framework | Microsoft ...
- 沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置
目录 沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置 CH32V208 CH32V208系列是沁恒32位RISC-V中比较新的一个系列, 基于青稞RISC ...
- python的format方法中文字符输出问题
format方法的介绍 前言 提示:本文仅介绍format方法的使用和中文的输出向左右和居中输出问题 一.format方法的使用 format方法一般可以解决中文居中输出问题,假如我们设定宽度,当中文 ...
- vscode使用git推送代码
下载vscode https://code.visualstudio.com/ 点击应用管理 搜素Chinese (Simplified) Language Pack for Visual Studi ...
- 【Docker】镜像管理
一.搜索镜像 1.在官方网站搜索镜像 Docker 官方镜像仓库:https://hub.docker.com/ 2.docker search 搜索镜像 Usage: docker search [ ...
- 2023-03-18:给定一个长度n的数组,每次可以选择一个数x, 让这个数组中所有的x都变成x+1,问你最少的操作次数, 使得这个数组变成一个非降数组。 n <= 3 * 10^5, 0 <= 数值
2023-03-18:给定一个长度n的数组,每次可以选择一个数x, 让这个数组中所有的x都变成x+1,问你最少的操作次数, 使得这个数组变成一个非降数组. n <= 3 * 10^5, 0 &l ...