消息系统的设计与实现

栏目: IT技术 · 发布时间: 7年前

内容简介:消息系统的设计与实现

消息系统的设计与实现

在开发 Web 应用的时候,消息系统是一个绕不过的话题,特别是在社交类的应用中。用户的点赞、评论、关注、回复等等,对于电商类的应用,还需要有公告等消息,而这些都需要把操作详情通知到对应的人,而且还要满足个性化的定制。

 需求梳理

我们首先来看看关于消息这一块具体的业务形态是怎么样的:
1.对于知乎的消息聚合
2.对于简书的消息聚合
通过对这些的分析,我们可以得出对于消息一般是分为三类:公告、提醒、私信,这里着重讲一下提醒类的消息。
- 公告就是针对全部用户的消息推送(比如停机维护、业务升级)
- 提醒是指在特定环境下的通知(比如点赞、评论)
- 私信就类似点对点聊天

再来看看一组具体提醒类消息的样本:

  • 张三三 关注了你
  • 李思思 喜欢了你的文章 《消息系统的设计与实现》
  • 赵武武 收藏了你的文章 《消息系统的设计与实现》
  • 周正正 评论了你的文章 《消息系统的设计与实现》

可以看到消息都是有一个统一的范本:

  • sender: 提醒的触发者(比如上文中的张三三)
  • action: 提醒的动作(评论、喜欢、关注)
  • target: 提醒的作用对象(具体的某一篇文章)
  • user: 提醒动作作用对象的所有者(比如文章的作者)

通过这样的分析,就可以明白其中senderuser是网站的用户,而target是具体的作用对象,比如文章(article)、商品(product)、订单(order),action动作对于每个应用来说都是固定的,比如点赞(like)、收藏(collection)、评论(comment)等等。

 个性化配置

对于消息系统来说,个性化配置是不可或缺的需求。我们来看看知乎上面的配置:

对于这样的个性化配置,我们还需要维护一个用户对于某个对象可能产生的动作的关注。对于文章,他可能存在的通知范畴有:点赞、收藏、评论。作者只有去订阅了该文章的这些动作,才能在特定的事件产生的时候给作者推送提醒。比如我发布了一篇文章,那么我会根据自己的配置(比如配置中打开了只接收评论)订阅该文章的动作(那么只订阅评论动作),所以文章每被人评论了,就需要发送一则提醒告知我。
对于订阅的规则,不拘泥于这一些,可以根据不同的业务与通知对象进行拓展,而且假如用户没有配置的话,我们还要提供默认的配置。通过上面的分析,我们可以抽象出三个实体,其中通知(Notify)包括三类(公告、提醒、私信)

  • 通知(Notify)
  • 订阅(Subscription)
  • 配置(SubscriptionConfig)

 数据结构

  1. Notify
    id          : {type: 'integer'}      // 主键
    content     : {type: 'text'}         // 消息的内容
    type        : {type: 'string'}       // 消息类型(公告announce、提醒remind、私信message)
    target_id   : {type: 'integer'}      // 目标的ID(比如文章ID)
    target_type : {type: 'string'}       // 目标的类型(比如文章article)
    action      : {type: 'string'}       // 动作类型(比如点赞like)
    sender_id   : {type: 'integer'}      // 发送者ID
    sender_type : {type: 'string'}       // 发送者类型(前台用户user,管理员admin)
    is_read     : {type: 'integer'}      // 阅读状态
    user_id     : {type: 'integer'}      // 消息的所属者(比如文章的作者)
    created_at  : {type: 'datetime'}     // 时间

    对于targetsender这两个可能不是很理解,对于提醒类的消息我们需要标记作用对象(target)与触发者(sender),举一个简单的例子: 「张三三喜欢了你的文章《我的家乡》」,那么:

    target_id:  123          // 文章ID
    target_type: 'article',  // 指明target所属类型是文章
    sender_id: 123456        // 张三三
    sender_type: 'user'      // 张三三的用户类型(普通用户or管理员)

    上面sender_type区分的目的就是为了在发送公告类的时候保存发送者。而且对于公告和私信类的消息还会用到content字段,而不会用到targetaction字段

2.Subscription

target_id   : {type: 'integer'}      // 目标的ID(比如文章ID)
target_type : {type: 'string'}       // 目标的类型(比如文章article)
action      : {type: 'string'}       // 动作类型(比如点赞like)
user_id     : {type: 'integer'}      // 订阅用户

订阅表的设定是为了个性化配置铺路,当用户发表一篇文章的时候,我们会把文章可能产生的动作都保存到订阅表中,在此之后这个目标触发该动作产生的消息,都会被通知到该用户。比如用户想要接收一篇文章的评论消息,那么订阅的数据表现为:

target_id   : 123        // 目标的ID(文章ID)
target_type : 'article'  // 目标的类型
action      : 'comment'  // 动作类型
user_id     : 1          // 订阅用户

而且有订阅的情况下,还可以实现特定文章才接收通告的需求,同学们可以自行发挥想象。

3.SubscriptionConfig
对于每个订阅动作来说,用户可能并不想要都通知到自己。比如文章的动作有点赞、评论、收藏,但是用户只想接收评论的消息,那么配置就派上用场了。他的数据结构很简单:

config      : {type: 'json'}         // 具体配置
user_id     : {type: 'integer'}      // 订阅用户

其中config是一个特定的 json对象,根据不同的业务配置有所不同,比如对于文章和用户可能有:

{
    comment    : true,
    like       : false,
    collection : false,
    follow     : true       //关注用户
}

当然了并不是每个用户都会去配置,所以我们要提供一组默认的配置,而且配置还可以根据业务进行拓展:

defaultConfig: {
    comment    : true,
    like       : true,
    collection : true,
    follow     : true       //关注用户
}

 业务逻辑

通过上面的分析整个需求已经很明朗了,再详细说下每个功能点的实现过程中,具体的业务逻辑。

  1. 创建提醒
    创建提醒主要的参数是用户、动作、目标,然后到订阅表中查询该用户是否有订阅该目标的该动作,然后再去配置表中查询是否开启了该项配置,进而就可以进行入库处理了。

2.创建订阅
一般情况下,我们都会在创建特定实体的时候同步创建订阅记录。比如用户写了一篇文章,然后文章有评论、点赞、收藏事件,那么我们就要在新建文章后这个节点入库三条记录:

{
    target_id   :  111,
    target_type : 'article',
    action      : 'comment'
    user_id     : 10
}
{
    target_id   :  111,
    target_type : 'article',
    action      : 'like'
    user_id     : 10
}
{
    target_id   :  111,
    target_type : 'article',
    action      : 'collection'
    user_id     : 10
}

然后在文章收到评论(comment)等的时候,就可以去查询并且判定是否通知用户了。

3.针对特定实体设定配置
我们还会有这样的需求,用户发表完文章后不想接收该文章的所有或者特定提醒,那么就可以在订阅表中把不想要的那个订阅动作删除了即可

4.设定已读
对于提醒和私信类的消息,设定已读只要在 notify 表里面设定 is_read 字段即可,但是对于公告类的消息,并没有存储user_id字段,这样如果直接设置的话所有用户拉取到的公告都会被设定为已读。这里提供一个解决方案就是通过 RedisBitmap 来存储每个用户每条公告的阅读状态。

论坛传图片太难受,具体可以查看:https://mp.weixin.qq.com/s/JVvyFu_K0CdJwWbGDEkxAw


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

复杂网络理论及其应用

复杂网络理论及其应用

汪小帆、李翔、陈关荣 / 清华大学出版社 / 2006 / 45.00元

国内首部复杂网络专著 【图书目录】 第1章 引论 1.1 引言 1.2 复杂网络研究简史 1.3 基本概念 1.4 本书内容简介 参考文献 第2章 网络拓扑基本模型及其性质 2.1 引言 2.2 规则网络 2.3 随机图 2.4 小世界网络模型 2.5 无标度网络模型 ......一起来看看 《复杂网络理论及其应用》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换