系统通知,居然有人使用拉取?

任何脱离业务场景的架构设计都是耍流氓。

广义系统通知,有1对1的通知,以及一对多的通知,有相对实时的业务通知,以及能够容忍一定延时的系统通知。结合具体的场景来看下,这样的一些系统通知,究竟是推还是拉?

一、系统对1的通知

典型业务,计数类通知:

  • 有10个美女添加了你为好友
  • 有8个好友私信了你

很多业务经常有这类计数通知,通知结果只针对你,这类通知是推送,还是拉取的呢?常见的有这样一些实践:

如果业务需求对计数需求需要实时展现,例如微博的加好友计数,假如希望实现不刷新网页,计数就实时变化

  • 登录微博时,会有一个计数的拉取,对网页端的计数进行初始化

int getCountByType(int countType)

  • 在浏览微博的过程中,一旦有人加你为好友,服务端对网页端进行实时推送,告之增加了1个(或者N个)好友

int addCountByType(int countType, int diff)

这里的思路是,一开始得到初始值,后续推送增量值,由网页端计算最终计数并呈现最终结果。需要注意,针对不同业务,计数变化的差值可增可减。

上述方案的坏处是,一旦有消息丢失,网页端的计数会一直不一致,直至再次登录重新初始化计数。这个计算计数可以优化为在服务器直接计算并通知网页端最终的结果,网页端只负责呈现即可,这样网页端的逻辑会变轻。

如果业务对此类通知的展现不需要这么实时,完全可以通过拉取:

  • 只有在链接跳转,或者刷新网页时,才重新拉取最新的通知,例如上述计数

int getCountByType(int countType)

这样系统的实现会最简单。需要注意,通知拉取要异步,不要影响主页面的快速返回。

系统对1的推送,例如针对1个用户的业务计数推送,计数的变化频率其实非常低,使用cache来存储这些计数能够极大提升系统性能。

更多计数系统架构实践可详见《计数系统架构实践一次搞定》。

二、系统对多的通知

系统对多的通知消息,会比系统对1的通知消息复杂一些,以两个场景为例:

  • QQ登录弹窗新闻
  • QQ右下角弹窗广告

IM登录弹窗新闻

这个通知的需求是:

  • 同一天,用户登录弹出的新闻是相同的(很多业务符合这样的场景),不同天新闻则不一样(但所有用户都一样)
  • 每天第一次登录弹出新闻,当天的后续登录不出新闻

不妨设有一个表存放弹窗新闻

t_msg(msg_id, date, msg_content)

有一个表来存放用户信息

t_user(user_id, user_info, …)

有一个表来存放用户收到的新闻弹窗

t_user_msg(user_id, msg_id, date)

这里的实现明显不能采用推送的方式:

  • 将t_user_msg里对于所有user_id推送插入一个msg_id,表示未读
  • 在user每天第一次登录的时候,将当天的msg_id拉取出来,并删除,表示已读
  • 在user每天非第一次登录的时候,就拉取不到msg_id于是不会再次弹窗

这个笨拙的方式,会导致t_user_msg里有大量的脏数据,毕竟大部分用户并不会登录。

如果改为拉取的方式会好很多:

  • 在user每天第一次登陆时,将当天的msg_id拉取出来,并插入t_user_msg,表示已读
  • 在user每天非第一次登陆时,则会插入t_user_msg失败,则说明已读,不再进行二次弹窗展现

这个方式虽然有所优化,但t_user_msg的数据量依然很大。

还有一种巧妙的方式,去除t_user_msg表,改为在t_user表加一列,表示用户最近拉取的弹窗时间:

t_user(user_id, user_info, last_msg_date, …)

这样业务流程会升级为:

  • 在user每天第一次登录时,将当天的msg_id拉取出来,并将last_msg_date修改为今天
  • 在user每天非第一次登录时,发现last_msg_date为今天,则说明今天已读

这种方式不再存储消息与用户的笛卡尔关系,数据量会大大减少,是不是有点意思?

IM右下角弹窗广告

这个通知的需求是:

  • 每天会对一批在线用户推送相同的弹窗TIPS广告,例如球鞋广告,手机广告等

画外音:如果1个推送一块钱,5KW用户推送收入就有5KW收入哟,一天推个几次,实现1个亿的小目标居然如此简单。

最直观的感受,这是一个for循环批量推送的过程。如果是推送,必须要考虑的问题是,推送限速控制,避免短时间内对系统造成冲击,引发雪崩。

能不能用拉取呢?

完全可以,这是一个对实时性要求不太高的场景,用户早1分钟晚1分钟收到这个广告影响不大,其实可以借助IM原本已有的keepalive请求,在请求返回时,告之“有消息拉取”,然后采用拉取的方式拉取广告消息。

这个方案的好处是,由于5KW在线用户的keepalive请求是均匀的,所以可以很均匀的将广告拉取的请求同样均匀的分散到一段时间内,避免5KW集中推送对系统造成冲击。

三、总结

广义系统通知,究竟是推送还是拉取呢?不同业务,不同需求,实现方式不同。

系统对1的通知:

  • 实时性要求高,可以推送
  • 实时性要求低,可以拉取

系统对N的通知:

  • 登录弹窗新闻,拉取更佳,可以用一个last_msg_date来避免大量数据的存储
  • 批量弹窗广告,常见的方法是推送,需要注意限速,也可以拉取,以实现请求的均匀分散

系统通知究竟是推还是拉,是一个相对比较简单的场景。对于feed流,单聊群聊,状态同步会更为复杂,这些场景,下期分解。

原文发布于微信公众号 - 架构师之路(road5858)

原文发表时间:2018-05-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Kirito的技术分享

【千米网】从跨语言调用到dubbo2.js

微服务架构已成为目前互联网架构的趋势,关于微服务的讨论,几乎占据了各种技术大会的绝大多数版面。国内使用最多的服务治理框架非阿里开源的 dubbo 莫属,千米网也...

13810
来自专栏小白课代表

软件分享 | C4D R14 安装教程

18920
来自专栏IT 指南者专栏

「Chrome 插件」低调推荐系列(一)

因为 Chrome 浏览器是目前世界上最强大最好用扩展性最广的浏览器,市场份额长期盘踞第一,如下所示图片是人们曾经用来调侃 IE 浏览器速度的,其实最终目的是不...

24030
来自专栏知晓程序

「大众点评点餐」小程序开发经验 06:解析开发工具

邹弓一,美团点评前端工程师,4年 Web 前端开发经验,现在是美团点评点餐团队的一员。

14830
来自专栏王清培的专栏

.NET应用架构设计—重新认识分层架构(现代企业级应用分层架构核心设计要素)

阅读目录: 1.背景介绍 2.简要回顾下传统三层架构 3.企业级应用分层架构(现代分层架构的基本演变过程) 3.1.服务层中应用契约式设计来解决动态条件不...

28770
来自专栏华仔的技术笔记

ios开发小结之重构及随想

28670
来自专栏Java面试笔试题

什么是中间件?

计 算机技术迅速发展。从硬件技术看,CPU速度越来越高,处理能力越来越强;从软件技术看,应用程序的规模不断扩大,特别是Internet及WWW的出 现,使计算机...

37720
来自专栏Crossin的编程教室

Python 实战(0):初识 web.py

在 Python 系列的基础课程结束之后,很长一段时间我不知道该写点什么。再加上工作很忙,也没法很系统地写一些教程文章。于是之前东拉西扯说过不少方面的东西,也分...

35980
来自专栏云成本管理

云成本管理方法论(四)——云优化管理之管理措施

因为判定规则分析中的判定结果较分散,为便于后继的分析和使用,我们将判定结果进行分类,不同的类别称为“问题类型”。

498100
来自专栏大魏分享(微信公众号:david-share)

VMware SDDC 分析工具介绍----第一篇

在接下来的一段时间,笔者会分享VMware SDDC体系架构中分析工具,vROps和LogInsight。由于篇幅有限,我会以连载的方式,先介绍vROps(预计...

455130

扫码关注云+社区

领取腾讯云代金券