如今的内容型产品,不管提供的是什么类型的内容,在其主功能之外,不可避免的会有另一个十分重要的功能——消息中心。
而无论是信息流、论坛、信箱,还是私聊、群聊、通知,推拉模型是内容型(包括:社交型)产品架构的核心。做出正确选择的关键在于对产品形态和系统组件清晰的认识。
今天我们将重心放在消息中心上,聊一聊如何设计一个消息中心。
需求分析 消息中心通常会有两个功能(如下图所示):
用户通知(点赞、评论、关注、@等) 官方通知 接下来我们将会对这两类通知进行一个简单的抽象。
首先,可以确定的是,对于用户通知,每个用户都不一样(我的点赞列表和你的点赞列表肯定是不一样的),因此对于每个人我们都需要维护一个「收件箱」。
当 A 点赞了 B 的内容,后端系统在收到了这一个点赞消息后,会将点赞信息写入 B 的 「收件箱」,并标明这是 A 在 xxx 时点赞的 xxx 内容。这是一个系统将消息 推送 给 B 的过程。
而对于官方通知,每个人(几乎)都是一样的(用户有可能设置了屏蔽,系统也可能指定了发送人群),并且官方通知是由系统自然下发的,因此对于系统来说需要维护一个系统**「发件箱」**。
发件箱维护了官方想给用户的通知,每次打开消息中心时,用户都会主动来系统**「拉取」官方最新的消息,并和用户自己的「收件箱」里的官方通知进行比较,以确认是否已读该条通知。这是一个用户主动从系统「拉取」**通知的过程。
推拉模型 其实到这里就已经点出了这两个场景背后的一套模型——推拉模型。而之所以在这两种场景选择不同的运行机制,其实背后牵扯到的是读写扩散的问题。
推模型 先看推模型,对于任何一个内容创作者来说,最开心的事情莫过于打开软件会有一堆点赞/评论的小红点。对于大 V 来说,打开 App 查看点赞消息的频率根本比不过别人给你点赞的频率,这是一个很典型的读少写多的场景。每当有一个用户点赞该大 V 时,都会将索引信息(一般为内容 ID、类型、发表时间等索引数据)写到用户的收件箱中。
优点:读很轻。仅需要读取消息列表即可。 缺点:写很重。一旦用户的内容质量很高,可能会收到大量的点赞/评论,会有大量的写入操作。 拉模型 再看拉模型,以官方通知为例,一般官方通知是由运营人员发布的,一个月可能也不会有几条,但是每次用户进入 App 时都会看看是否有新的官方通知进来,这是一个很典型的读多写少的场景。
优点:写很轻,节省空间。系统只需维护一个属于自己的消息列表即可。 缺点:读很重,计算量大。假设可以发送官方通知的生产者较多(例如淘宝里的一系列官方业务),则每次都需要从这些消息生产者里拉取最新的内容。 流程设计 用户通知 对于用户通知,流程设计如下:
对于该流程,有几点需要注意的:
异步发送 当用户出发了点赞/关注/评论行为时,被点赞/评论/关注的用户,其实不需要立即感知,因此也不需要立即将互动信息写入该用户的收件箱中,因此可以考虑以消息队列的方式通知出去,缓解系统压力。
缓存前置 写入消息时,如果直接写入用户收件箱,可能会导致用户在请求消息列表时,将请求全部打到 DB,造成系统故障,因此通常会在更新用户收件箱时双写用户缓存。
官方通知 相较于用户通知,官方通知由于引入官方运营这一角色,操作上会稍微复杂一些(如上图所示),因此整个系统的设计也会稍微复杂一些。...
浅谈策略模式在消息转发场景下的应用
背景 在上一篇文章中,我们介绍了如何设计一个消息中心,传送门 👉《如何设计一个消息中心》
有了承载这些消息的地方后,接下来的问题便是,这些消息从哪里来?
通常对于一个内容型产品来说,在其互动体系中,为了增强消息的用户触达,增强用户的互动心智,在互动(评论、点赞等)行为发生后,会将互动消息推送至消息中心,然后根据不同的互动行为类型匹配不同的消息模版。
然而随着互动行为种类的增加(内容的点赞、评论的点赞……),不断的通过 if…else 来根据不同的消息类型生成不同的消息模版会使得业务代码愈发复杂,难以维护。
不仅如此,一旦需要增加一种新的互动消息时,需要对原有代码进行破坏性修改,违背了“开闭原则”。因此有必要对互动行为消息转发至消息中心这一场景进行抽象,让后续的维护者、建设者只需要关心某一特定的互动行为消息即可(我可不想未来被别人喷在 💩 山上拉 💩)。
策略模式 在说明具体的实现方案前,我们先介绍一个设计模式——策略模式。
策略模式,英文全称是 Strategy Design Pattern。在 GoF 的《设计模式》一书中,它是这样定义的:
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
翻译成中文就是:定义一簇算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。
策略模式用来解耦策略的定义、创建、使用。实际上,一个完整的策略模式就是由这三个部分组成的。
策略类的定义比较简单,包含一个策略接口和一组实现这个接口的策略类。 策略的创建由工厂类来完成,封装策略创建的细节。 策略模式包含一组策略可选,客户端代码如何选择使用哪个策略,有两种确定方法:编译时静态确定和运行时动态确定。其中,“运行时动态确定”才是策略模式最典型的应用场景。 实现方案 在对策略模式有了基本的了解后,我们尝试在本节将其运用起来。
仔细分析了第一章的应用场景后我们发现其实实现链路并不复杂,整体流程如下图所示:
在本例中,根据不同的互动行为类型,我们将点赞消息和评论消息分成以下几类:
点赞类:
内容点赞 评论点赞 评论类:
内容评论 内容评论的回复 转发策略的定义 整个方案中最重要的一环是对转发策略的匹配,因此第一步我们要做的应该是定义一个策略。为了方便后续的扩展(未来可能会有多种转发策略),我们此处定义一个策略接口MsgTransmitStrategy。...
前言 本文是笔者在团队内部做分享整理的资料的一部分,本次分享主要是站在一个服务端开发的视角对(前端)低代码平台的一些调研,已经剔除了一些敏感数据和信息,可放心食用。
太阳底下无新事 Dreamweaver -> Low-Code 将时钟拨回到 20 年前,那个时候的开发者对于 html/css/js 还处在望而生畏的阶段,Dreamweaver 的出现仿佛让他们看见了曙光。通过简单的拖拽就可以实时预览编排的页面,点击按钮就可以自动生成对应的前端代码,配置好机器信息就可以一键部署访问…… 这些特性让无数开发者趋之若鹜,然后现在他的境况
现如今,Dreamweaver 几乎已经退出了历史舞台,但 Low-Code 似乎又有卷土重来的迹象……
Low-Code 是什么? A low-code development platform (LCDP) is software that provides a development environment used to create application software through graphical user interfaces and configuration instead of traditional hand-coded computer programming.
一句话概括就是 👉 用 GUI+配置取代传统手工编码 技术上,实现低代码平台的关键要素是模型驱动设计、代码自动生成和可视化编程,通过这些手段来隐藏下层的代码细节。
更激进的—— No-Code(零代码) Low-Code 更激进的演进方向是 No-Code,主要的差异点如下:
平台用户:任何业务人员都能使用无代码平台,而低代码平台面向开发者(尽管专业要求不那么高)
核心设计:无代码平台倾向于让用户通过拖拽或简单的表达式来操纵完成应用设计,而低代码平台更倾向于通过人工编码来指定应用程序的核心结构
用户界面:无代码平台为了简化应用设计,一般只支持内置的 UI 库,而低代码平台可能会提供更灵活的 UI 选项,但代价是需要额外编码,使用上的复杂性有所增加...