讲一个愚蠢的故事,为什么以前OurCoders那么慢,以及有时候会收到多份的周群发邮件

tinyfool 发布于 2015年09月08日
无人欣赏。

最近,我开始放精力在OurCoders上面,解决了很多技术问题。然后,一直有一个很挠头的技术问题,我一直懒得解决,就是OurCoders的页面生成时间,有时侯是几个毫秒,有时候是上千毫秒。这个问题很难解释,我以前以为有什么简单问题,但是找来照去在代码里面看不到问题。

于是我就想,我去把mysql的slow queries功能打开吧。打开以后,我发现,90%以上的slow queries其实是这句

SELECT * FROM mail_queue WHERE status = 0 ORDER BY rand() ASC

解释下mail_queue,这个表就是当系统需要发邮件的时候,先会把需要发的邮件放在这个表里面,然后每隔一分钟通过crontab启动一个发邮件的php页面,把100封邮件发出去。这句SQL就是在选择100条status=0的邮件,0代表未发送,1代表发送成功,2代表发送失败。

我就想这句怎么这么愚蠢啊,为啥by rand()啊,你一旦by rand()的话,这个就没办法被缓存命中了,也用不上索引啊。于是去掉了这句话,我还去掉了另外一个多发的slow query:

SELECT id,title,replys FROM threads where createbyid <> 28504 AND id in (SELECT threadid FROM thread_replys WHERE userid = 28504 and del = 0 GROUP BY threadid) AND del = 0 

效果非常好,整天都没有slow queries了。

但是,到了下周一,有人报周总结邮件收到了7-8封,这个bug在很久很久出现过,我已经记不得怎么解决了,但是发送代码百分百没有错误,不可能会重复发送。一时想不出来主意,我就把这个问题撂下了。

过了几天,我正在走路的时候,突然想起当年为啥会有by rand()。

原来故事是这样的,因为我要设置1发送成功和2发送失败这两个标志,所以,发送流程是,一次选择100封,一封一封的发送邮件,等待一封完成,取得返回值,根据返回值设置1或者2。

所以,在很久以前,某一次邮件服务器发送很慢的时候,一封邮件还没发完,这时候1分钟过去了,系统就又选取了100封邮件,而第一次还没发送完的邮件,因为没有设1或者2,仍旧会被选中来发送,所以就会重复发送。

当年为了解决这个问题,我加了一个by rand(),从概率上,两次发送流程很难遇到重复的邮件,所以,就不会产生重复发送问题。

一切都想通后,我发现问题还在于之前图省事儿,非要等邮件发送完毕以后才设置flag。修正方法是,选取100封邮件后,先设置为1,然后挨个发送,一旦发送失败,根据返回着设置flag为2。

这样整体效率和不重复之间的矛盾就解决了,我之前好愚蠢。

共12条回复
yuzhouwww 回复于 2015年09月08日

有意思,给自己挖了个漂亮的坑,而且没有立个标识。

tinyfool 回复于 2015年09月08日

1楼 @yuzhouwww 嗯,其实就是以前要没有文档,代码也写的比较乱的结果

likaihere 回复于 2015年09月08日

2楼 @tinyfool 所以好像问题是flag缺了一个值用来表示“发送中”,当然改成发送成功也挺好,少一次数据库更新操作

tinyfool 回复于 2015年09月08日
amazeur 回复于 2015年09月08日

有时候就需要在设计之初考虑的更完善点,这样给后人少留点坑。要不是你本人来改,可能就没人知道历史原因了。

yangwen13 回复于 2015年09月08日

正所谓:当局者迷,旁观者清。

清醒疯子 回复于 2015年09月08日

看来,注释很重要(>人<;)

brambles 回复于 2015年09月09日

TnT 说好的让我加新功能的呢?

tinyfool 回复于 2015年09月09日

8楼 @brambles 这么久也没看到你动手啊

brambles 回复于 2015年09月09日

9楼 @tinyfool

我都不知道项目在哪里呀…… TnT

已经加了我吗?

tinyfool 回复于 2015年09月09日

10楼 @brambles 哦,我再折腾折腾吧,等等,别急,我想起问题在哪里了

brambles 回复于 2015年09月10日

11楼 @tinyfool

好,坐等 /w\

可以加好多好玩的东西

本帖有12个回复,因为您没有注册或者登录本站,所以,只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。

登录 或者 注册
[顶 楼]
|
|
[底 楼]
|
|
[首 页]