web消息通知系统设计问题


一般网站上都会消息提醒通知,如一个用户给另一个用户发了一条站内信,那么就会在网站顶部的导航栏上就会有一个消息提醒的数字来提示您有新消息。

上面只是一个简单例子,在实际项目中可能就会有多种类型的提醒,如某个用户给你留言了,就显示提醒“新留言x条”或者“新回复y条”等等吧。

我打算设计成把所有类型的消息提醒统一的放到一张表(notice)里,并标记用户是否已处理了这条消息提醒,在网站的前台就可以只统计这一张表就行了,比如用户A给用户B发送了一条私信,就在notice表里插入一条新的未读消息提醒,用来提醒用户,当用户B查看完成私信后,再回到这张notice表标记为已处理或者直接删除。

但是大数据量或高并发的时候就会存在一个问题,当用户已经查看完了新收到的私信后,去notice表做标记处理时,可能由于种种原因其对应的“未读消息提醒”还没有写进去,这时候就出问题了,当用户去请求是否有“未读消息提醒”时,刚好又写进去了,然后就提示用户有“新消息”,但是实际上用户早已处理掉了,只不过就是“未读消息提醒”延时了。

如果说统计新消息提醒,去各个业务(如私信,留言)中单独统计,然后合并,再通知给用户,这样做的话,怎么称得上是“消息通知系统”呢?总觉得这样是不合理的

对于消息通知系统,我的notice表是否有存在的意义呢,大家是怎么设计的?

Redis web php mysql nginx

Tantra 9 years, 7 months ago

关于消息系统的设计,肯定是需要一个数据表记录通知的,比如Notice表,至于这个通知可能有很多类型,就像你说的 私信和留言,这些在设计中都可以通过字段表示,这里分享下 Worktile 中 Notice的数据结构设计。


 {
    nid: { type: String, unique: true },
    published: { type: Number, default: Date.now },
    verb: { type: String },
    template: { type: String },
    is_read: { type: Number, index: true, default: 0 },
    is_pending: { type: Number, index: true, default: 0 },
    filter: {
        ftype: { type: String }
    },
    sender: { type: Actor },
    receiver : { type: String , index: true},
    data: {
        entity: { type: Entity },
        source: { type: Entity },
        target: { type: Entity }
    }
}

具体细节设计可以参考 activity 的一个标准: http://activitystrea.ms/
至于你说的消息高并发的问题其实是没有问题的,你标记完未读消息为已读后在切换页面,这是再读取未读消息前面的标记为已读应该早就处理完了。除非你系统高并发的程度已经达到系统瘫痪了,在没有遇到瓶颈的时候不需要过度优化,即使到达瓶颈也有解决方案的,你可以把所有未读的消息放到内存或者redis中来提高性能。

上面说的是数据结构方面的东西,一般web的消息都是实时更新的,意思就是:你没有刷新页面,此时来消息了,应该立即显示未读消息多少条。关于实时消息系统的做法要取决于你服务端用的什么语言。Node.js+ socket.io
就很容易做到,我们的产品Worktile是采用erlang语言实现的,如果你感兴趣可以参考: http://segmentfault.com/blog/worktile/1190000000665676

长的丑哈出道 answered 9 years, 7 months ago

Your Answer