消息系统设计与实现「上篇」

由于文章篇幅较长,而作者精力有限,不希望这么早就精尽人亡,故分成上下篇来写消息系统的设计与实现。上篇主要讲的是一些概念,搞清楚我们要做的这个消息系统的主要内容。而下篇主要讲具体的实现,会包括架构设计,数据库设计,业务流程详细的实现等。

整个系统的设计与实现,并非我一人之力就可以完成的。这其中是同事们大家一起讨论与商讨的结果,而我只是把它细化,呈现出来。

我只是一个会思考的idea搬运工。

产品分析

首先我们来看一下市场上关于消息的实现是怎么样的。

简书

简书的消息系统主要分了两种

  • 简信
  • 提醒

简信
简信的性质其实跟私信是一样的,是用户发送给用户的一则消息,有具体的信息内容。

简书简信

提醒
而提醒,则是系统发送的一则消息,其文案格式是固定的,并且对特殊对象一般拥有超链接。

简书提醒

知乎

知乎跟简书一样,主要分了两种:

  • 私信
  • 消息

私信
跟简书一样,使用户发送给用户的一则消息,也可以是管理员发送给用户的消息。

知乎私信

消息
知乎的消息比简书的提醒有过之而无不及,知乎会对多条相似的消息进行聚会,以达到减轻用户阅读压力的体验。

知乎消息

消息的三种分类

通过两种产品的简单分析,得出他们的消息有两种分类,在这基础上,我们再加上一种:公告。
公告的主要性质是系统发送一则含有具体内容的消息,站内所有用户都能读取到这条消息。
所以,消息有三种分类:

  1. 公告 Announce
  2. 提醒 Remind
  3. 私信 Message

提醒的语言分析

我们从简书取一组提醒样本:

  • 3dbe1bd90774 关注了你
  • magicdawn 喜欢了你的文章 《单点登录的三种实现方式》
  • 无良程序 喜欢了你的文章 《基于RESTful API 怎么设计用户权限控制?》
  • alexcc4 喜欢了你的文章 《在Nodejs中贯彻单元测试》
  • 你在《基于RESTful API 怎么设计用户权限控制?》中收到一条 cnlinjie 的评论
  • 你的文章《Session原理》已被加入专题 《ios开发》

分析句子结构,提醒的内容无非就是

「谁对一样属于谁的事物做了什么操作」
「someone do something in someone's something」

someone = 提醒的触发者,或者发送者,标记为sender
do something = 提醒的动作,评论、喜欢、关注都属于一个动作,标记为action
something = 提醒的动作作用对象,这就具体到是哪一篇文章,标记为target
someone's = 提醒的动作作用对象的所有者,标记为targetOwner

这就清楚了,sender和targetOwner就是网站的用户,而target是具体到哪一篇文章,如果提醒的对象不仅仅局限于文章,还有其他的话,就需要增加一项targetType,来标记目标是文章还是其他的什么。而action,则是固定的,整个网站会触发提醒的动作可能就只有那几样:评论、喜欢、关注.....(或者其他业务需要提醒的动作)

消息的两种获取方式

  • 推 Push
  • 拉 Pull

以知乎为例
推的比较常见,需要针对某一个问题维护着一张关注者的列表,每当触发这个问题推送的条件时(例如有人回答问题),就把这个通知发送给每个关注者。

拉的相对麻烦一点,就是推的反向,例如每个用户都有一张关注问题的列表,每当用户上线的时候,对每个问题进行轮询,当问题的事件列表出现了比我原本时间戳大的信息就进行拉取。

而我们则根据消息的不同分类采用不同的获取方式
通告和提醒,适合使用拉取的方式,消息产生之后,会存在消息表中,用户在某一特定的时间根据自己关注问题的表进行消息的拉取,然后添加到自己的消息队列中,

信息,适合使用推的方式,在发送者建立一条信息之后,同时指定接收者,把消息添加到接收者的消息队列中。

订阅

根据提醒使用拉取的方式,需要维护一个关注某一事物的列表。
这种行为,我们称之为:**「订阅」Subscribe **

一则订阅有以下三个核心属性

  • 订阅的目标 target
  • 订阅的目标类型 targetType
  • 订阅的动作 action

比如我发布了一篇文章,那么我会订阅文章《XXX》的评论动作,所以文章《XXX》每被人评论了,就需要发送一则提醒告知我。

订阅的规则还可以扩展
我喜欢了一篇文章,和我发布了一篇文章,订阅的动作可能不一样。
喜欢了一篇文章,我希望我订阅这篇文章更新、评论的动作。
而发布了一篇文章,我希望我只是订阅这篇文章的评论动作。

这时候就需要多一个参数:subscribReason
不同的subscribReason,对应着一个动作数组,
subscribReason = 喜欢,对应着 actions = [更新,评论]
subscribReason = 发布,对应着 actions = [评论]

订阅的规则还还可以扩展
用户可能会有一个自己的订阅设置,比如对于所有的喜欢的动作,我都不希望接收。
比如Knewone的提醒设置

Knewone提醒设置

所以我们需要再维护一个表:SubscriptionConfig,来存放用户的提醒设置。
并且,当用户没有提醒设置的时候,可以使用系统提供的一套默认设置:defaultSubscriptionConfig

聚合

如果我发布了一篇文章《XXX》,在我不在线的时候,被评论了10遍,当我一上线的时候,应该是收到十条信息类似于:「谁谁谁评论了你的文章《XXX》」?
还是应该收到一条信息:「甲、乙、丙、丁...评论了你的文章《XXX》」?

知乎在聚合上做的很优秀,要知道他们要实现这个还是挺有技术的:
知乎的消息机制,在技术上如何设计与规划?
网站的消息(通知)系统一般是如何实现的?

关于这部分功能,我们还没有具体的实现方法,暂时也无法讲得更加详细。⊙﹏⊙

五个实体

通过上面的分析,大概知道做这个消息系统,需要哪些实体类:

  1. 用户消息队列 UserNotify
  2. 用户 User
  3. 订阅 Subscription
  4. 订阅设置 SubscriptionConfig
  5. 消息 Notify
    • 通告 Announce
    • 提醒 Remind
    • 信息 Message

行为分解

说了这么多,整理一下整个消息流程的一些行为:

  • 系统或者管理员,创建消息
    • createNotify (make announce | remind | message)
  • 用户,订阅消息,取消订阅
    • subscribe, cancelSubscription
  • 用户管理订阅设置
    • getSubscriptionConfig, updateSubscriptionConfig
  • 用户,拉取消息
    • pullNotify (pull announce | remind | message | all)
  • 用户,查询消息队列
    • getUserNotify(get announce | remind | message | all)
  • 用户阅读消息
    • read

在本文的「下篇」我们来探讨一下:模型怎么做、数据库怎么设计、代码结构怎么来、一些逻辑上的时序图应该是怎么样的。

-------- 更新于 2015/11/15 ----------

关联文章:消息系统设计与实现「下篇」


如果本文对您有用
请不要吝啬你们的Follow与Start
这会大大支持我们继续创作

「Github」
MZMonster :@MZMonster
JC_Huang :@JerryC8080

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容

  • 关联文章:消息系统设计与实现「上篇」 模型设计 Notify Save Remind消息表,我们需要target、...
    JC_Huang阅读 25,989评论 52 197
  • 背景 在一个系统中,资源,数据会持续不断的更新。而用户如果需要知道这些数据的更新,就需要一个系统,将系统中不断更新...
    goaheadhj阅读 4,590评论 1 14
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,050评论 18 139
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,234评论 0 15
  • 看过很多产品设计的文章,很少有对消息系统这个模块的设计讲得比较清晰的,最近搜集了一些资料,结合实际例子梳理了消息系...
    jason_peng阅读 2,634评论 3 46