清缓存的姿势不对,真的会出生产bug哦

最近解决了一个生产bug,bug的原因很简单,就是清理缓存的方式不对。本来没啥好说的,但是考虑到我们有时候确实会在一些小问题上栽跟头,最终决定把这个小故事拿出来跟大家分享下。
风起
有一天在撸代码,突然有个人加我微信,看头像是个妹子。我第一反应:对方是微商或者卖茶叶的(忍住,别笑)。因为已经有很多次这种加我好友的情况了,问对方是谁就从来没有下文。所以这次我也没有通过,而是像以前一样追问了一句“我们认识吗”,就没再管它,心想对方肯定不回的。然后继续然后继续撸串,哦不,是撸代码。
还没1分钟,对方竟然回复了,大意是“我是xxx公司的某某某,有个问题想咨询下”,哇哦,原来是客户。。。赶紧通过验证并问具体啥问题。原来是对方在点某个页面按钮的时候一直提示错误,不能正常进行业务了。
常规操作
和以往一样,我查起了生产log,发现是数据库锁表了。客户是业务型公司,一般不会出现多人同时操作的情况,数据量也不大,生产上从来没有出现过,倒是我本地调试的时候经常因为性子急多点几次导致锁表,因此感觉这个问题很好解决,让管理员把锁解了就行了。
云涌
没有锁了,让客户再试下,客户的反馈“还是报错”,没道理啊。再查日志,发现已经没有了堆栈信息,为啥还不行呢。
没办法只能看那个时间段所有的log,发现有一行“map缓存中有数据,可能多人同时操作”。
查下代码,发现代码中为了防止同一条数据多人同时操作,加了map作为缓存,数据记录的PK作为key和value。
(记住这个图,后面会考)
每次操作的时候将数据put进map,处理完后remove掉。如果map中有相关KV就表示这条记录有人正在操作,则其他人不能操作,抛提示信息。
于是乎问客户“多人同操乎?”,得到的答复是“否”,纳尼?怎可能。日志是不会骗人的啊
再查代码
针对map再把代码看一遍,看它put和remove的地方,还有日志打印的地方。终于发现一个问题,
map的清理动作是在try里面正常处理后做的,如果出现异常就不能正常清理了,而map定义的时候为了对象间共享定义成了静态成员变量,
刚才的锁表抛了异常,当时已经put进入到map里面的KV就一直没有机会清掉了,也就是说只要服务不重启,问题会一直坚定的陪着你。
对症下药
1.跟领导申请紧急重启服务,保证业务正常进行。
2.修改问题代码,将报错放到finally块。
3.横展开调查其他类似代码是不是也存在这个问题,一并修改。
风平浪静
问题解决,对方表示感谢,我也回复不客气,一切回归平静。
总结
其实这个缓存清理的问题本身很简单,大家都懂,就和释放数据库连接等情况一样,需要放到finally块里面,
这个即使代码抛异常了也能正常释放或清理。但是就是撸这段代码的时候,因为这样那样的原因一时没有想到。
如果公司有代码review的环节的话会好很多,如果没有review,那么在写完代码后最好自己review一遍。
否则,万一出现类似的问题真的有点尴尬,正如题目所说“清缓存的姿势不对,真的会出生产bug哦”。
希望你我今后都能避免这种情况的发生。
清缓存的姿势不对,真的会出生产bug哦的更多相关文章
- mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比,于是写了个插件。
使用mybatis逆向工程的时候,delete方法的使用姿势不对,导致表被清空了,在生产上一刷新后发现表里没数据了,一股凉意从脚板心直冲天灵盖. 于是开发了一个拦截器,并写下这篇文章记录并分享. 这锅 ...
- redis修改持久化路径、日志路径、清缓存
redis修改持久化路径和日志路径 vim redis.conf logfile /data/redis_cache/logs/redis.log #日志路径 dir /data/redis_cach ...
- 如何写出没有BUG的代码
1947年9月9日,美国海军准将 Grace Hopper 在哈佛学院计算机实验室里使用 Mark II 和 Mark III 计算机进行研究工作.她的团队跟踪到 Mark II 上的一个错误,操作人 ...
- 如何写出没有 bug 的代码?
来源:www.cnblogs.com/sherrywasp/p/9262877.html 1947年9月9日,美国海军准将 Grace Hopper 在哈佛学院计算机实验室里使用 Mark II 和 ...
- fir.im Weekly - 如何写出零 bug 的代码
神兽护体,代码无bug.经常看到代码注释的各种形状,这是一种程序员情怀.那么,如何能写出零 Bug 的代码呢,来看看@码农翻身 的这篇手册--零Bug的代码是怎么炼成的. 写零 Bug 一定少不了代码 ...
- QT就是别人好心帮你做一些枯燥,并且很重复的代码编写工作,让你更好的把精力投入到你界面的逻辑和功能的实现的功能库(否则写了上万行代码了,才写出个BUG一大堆的毛坯)
好了,现在开始记录我学习QT的学习历程 . 本人也不是计算机专业出来的,自学了一点,但还是不好找工作,于是参加了培训,虽然感觉没多学到什么 编程的学习生涯就是不断的看别人的源码,然后自己参考着写写自己 ...
- [UWP]合体姿势不对的HeaderedContentControl
1. 前言 HeaderedContentControl是WPF中就存在的控件,这个控件的功能很简单:提供Header和Content两个属性,在UI上创建两个ContentPresenter并分别绑 ...
- 电脑清缓存(C盘占空间)
电脑缓存目录: 1.取消文件隐藏 2.找到C:\Users\lwx351192\AppData\Local\Temp目录下的三个子文件夹local,locallow,roaming里面的文件都可删除, ...
- 微信浏览器中清缓存的方法---- http://debugx5.qq.com/
http://debugx5.qq.com/ 点击上面网址,然后把底部的四个选项打钩,然后点清除,即可把可恶的缓存清掉!!!!!
随机推荐
- 个人永久性免费-Excel催化剂功能第69波-专业图表库新增图表-刘万祥老师中国地图
Excel催化剂的[专业图表库],仅提供一个工具的输出,让用户可以在制作专业图表过程中更低的门槛,更快速的完成所想要实现的图表.具体参考:第69波-打造最专业易用的商务图表库https://www.j ...
- CSS画出三角形(利用Border)
画出三角形的原理是调整border(边框)的四个方向的宽度,线条样式以及颜色. 如果你将宽度调的足够大,改变不同方向的颜色,你就可以发现盒模型的border是四个梯形一样的线条. div{ width ...
- 使用Kubeadm创建k8s集群之部署规划(三十)
前言 上一篇我们讲述了使用Kubectl管理k8s集群,那么接下来,我们将使用kubeadm来启动k8s集群. 部署k8s集群存在一定的挑战,尤其是部署高可用的k8s集群更是颇为复杂(后续会讲).因此 ...
- JS+Jquery自定义格式导出HTML为Word(下列插件同样可以用于Excel导出)
这里的word导出主要采用了jquery.wordexport.js.FileSaver.js,做功能之前我也是找了很多网上的资料,里面涉及到js导出word的用的都是这个插件,只是在自定义样式这一块 ...
- 摘录C#代码片段
1.保存数据到指定文件String response = "";//数据 byte[] bytes = response.getBytes();//转化Byte string fi ...
- UPC Contest RankList – 2019年第二阶段我要变强个人训练赛第十五场
传送门 A: Colorful Subsequence •题意 给一个长为n的小写字母序列,从中选出字母组成子序列 问最多能组成多少种每个字母都不相同的子序列 (不同位置的相同字母也算是不同的一种) ...
- ES 22 - Elasticsearch中如何进行日期(数值)范围查询
目录 1 范围查询的符号 2 数值范围查询 3 时间范围查询 3.1 简单查询示例 3.2 关于时间的数学表达式(date-math) 3.3 关于时间的四舍五入 4 日期格式化范围查询(format ...
- python3 导入包总提示no moudle named xxx
一.python中的包有三种 1.python自带的包,如sys, os 2.python的第三方库,如 requests, selenium 3.自己写的.py文件 二.今天主要说下导入自己写的包 ...
- TIJ学习--RTTI(Runtime-Time Type Identification)
TIJ学习--RTTI(Runtime-Time Type Identification) RTTI 运行时类型检查机制 获取一个类的Class引用的三种方法 class TestClass{} Te ...
- ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建
在上一个小系列文章<ASP.NET Core on K8S学习初探>中,通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境,并初步尝试将ASP.NE ...