系统通知,居然用拉取
广义系统通知,有1对1的通知,以及一对多的通知,有相对实时的业务通知,也有能够容忍一定延时的系统通知。任何脱离业务场景的架构设计都是耍流氓,结合具体的场景来看下,这样的一些系统通知,究竟是推还是拉?
第一大类:系统对1的通知
典型业务,计数类通知:
(1)有10个美女添加了你为好友;
(2)有8个好友私信了你;
很多业务经常有这类计数通知,通知结果只针对你,这类通知是推送,还是拉取的呢?常见的有这样一些实践:
如果业务需求对计数需求需要实时展现,例如微博的加好友计数,假如希望实现不刷新网页,计数就实时变化:
(1)登录微博时,会有一个计数的拉取,对网页端的计数进行初始化:
int getCountByType(int countType)
(2)在浏览微博的过程中,一旦有人加你为好友,服务端对网页端进行实时推送,告之增加了1个(或者N个)好友:
int addCountByType(int countType, int diff)
这里的思路是,一开始得到初始值,后续推送增量值,由网页端计算最终计数并呈现最终结果。需要注意,针对不同业务,计数变化的差值可增可减。
上述方案的坏处是,一旦有消息丢失,网页端的计数会一直不一致,直至再次登录重新初始化计数。这个计算计数可以优化为在服务器直接计算并通知网页端最终的结果,网页端只负责呈现即可,这样网页端的逻辑会变轻。
如果业务对此类通知的展现不需要这么实时,完全可以通过拉取:
(1)只有在链接跳转,或者刷新网页时,才重新拉取最新的通知,例如上述计数
int getCountByType(int countType)
这样系统的实现会最简单,需要注意,通知拉取要异步,不要影响主页面的快速返回。
系统对1的推送,例如针对1个用户的业务计数推送,计数的变化频率其实非常低,使用cache来存储这些计数能够极大提升系统性能。
第二大类:系统对多的通知
系统对多的通知消息,会比系统对1的通知消息复杂一些,以两个场景为例:
(1)QQ登录弹窗新闻;
(2)QQ右下角弹窗广告;
先说IM登录弹窗新闻。
这个通知的需求是:
(1)同一天,用户登录弹出的新闻是相同的(很多业务符合这样的场景),不同天新闻则不一样(但所有用户都一样);
(2)每天第一次登录弹出新闻,当天的后续登录不出新闻;
不妨设有一个表存放弹窗新闻:
t_msg(msg_id, date, msg_content)
有一个表来存放用户信息:
t_user(user_id, user_info, …)
有一个表来存放用户收到的新闻弹窗:
t_user_msg(user_id, msg_id, date)
这里的实现明显不能采用推送的方式:
(1)将t_user_msg里对于所有user_id推送插入一个msg_id,表示未读;
(2)在user每天第一次登录的时候,将当天的msg_id拉取出来,并删除,表示已读;
(3)在user每天非第一次登录的时候,就拉取不到msg_id于是不会再次弹窗;
这个笨拙的方式,会导致t_user_msg里有大量的脏数据,毕竟大部分用户并不会登录。
如果改为拉取的方式会好很多:
(1)在user每天第一次登陆时,将当天的msg_id拉取出来,并插入t_user_msg,表示已读;
(2)在user每天非第一次登陆时,则会插入t_user_msg失败,则说明已读,不再进行二次弹窗展现;
这个方式虽然有所优化,但t_user_msg的数据量依然很大。
还有一种巧妙的方式,去除t_user_msg表,改为在t_user表加一列,表示用户最近拉取的弹窗时间:
t_user(user_id, user_info, last_msg_date, …)
这样业务流程会升级为:
(1)在user每天第一次登录时,将当天的msg_id拉取出来,并将last_msg_date修改为今天;
(2)在user每天非第一次登录时,发现last_msg_date为今天,则说明今天已读;
这种方式不再存储消息与用户的笛卡尔关系,数据量会大大减少,是不是有点意思?
再说IM右下角弹窗广告。
这个通知的需求是:
(1)每天会对一批在线用户推送相同的弹窗TIPS广告,例如球鞋广告,手机广告等;
画外音:如果1个推送一块钱,5KW用户推送收入就有5KW收入哟,一天推个几次,实现1个亿的小目标居然如此简单。
最直观的感受,这是一个for循环批量推送的过程。如果是推送,必须要考虑的问题是,推送限速控制,避免短时间内对系统造成冲击,引发雪崩。
能不能用拉取呢?
完全可以,这是一个对实时性要求不太高的场景,用户早1分钟晚1分钟收到这个广告影响不大,其实可以借助IM原本已有的keepalive请求,在请求返回时,告之“有消息拉取”,然后采用拉取的方式拉取广告消息。
这个方案的好处是,由于5KW在线用户的keepalive请求是均匀的,所以可以很均匀的将广告拉取的请求同样均匀的分散到一段时间内,避免5KW集中推送对系统造成冲击。
总结
广义系统通知,究竟是推送还是拉取呢?不同业务,不同需求,实现方式不同。
系统对1的通知:
(1)实时性要求高,可以推送;
(2)实时性要求低,可以拉取;
系统对N的通知:
(1)登录弹窗新闻,拉取更佳,可以用一个last_msg_date来避免大量数据的存储;
(2)批量弹窗广告,常见的方法是推送,需要注意限速,也可以拉取,以实现请求的均匀分散;
系统通知,居然用拉取相关推荐
- Git 高频命令、版本回退、分支操作、文件修改删除、撤销、标签、远程仓库推送、拉取
1. 高频命令 git add 将工作文件修改提交到本地暂存区. git add . 将所有修改过的工作文件提交暂存区(常用). git commit -m "XXX" 为本次修改 ...
- Docker的使用(docker pull拉取镜像失败问题解决)
在docker拉取Nginx镜像过程中,速度慢,或者不成功 报错代码: Error response from daemon: Get https://registry-1.docker.io/v2/ ...
- 解决k8s中node拉取镜像失败问题
在k8s集群的使用过程中,初学者可能会碰到这样的(怪异)问题: 在一个k8s集群里,部署服务(用的私有镜像仓库,如harbor)的时候,只有个别node的服务是部署成功的,其他都是部署失败的. 错误的 ...
- gitee 拉取其他分支_如何使用 Gitee 快速搭建 ESP-IDF 开发环境(Windows 版)
前言 为更好地服务国内用户,构建中文需求沟通平台,帮助用户快速下载乐鑫开源代码,乐鑫将 GitHub 中的主要仓库(包含 ESP-IDF.ESP-ADF.ESP-MDF 以及阿里.腾讯.京东等国内云平 ...
- 批处理-批量拉取git代码
简介: 公司项目采取微服务方式,导致开发时要拉取多个服务代码,一个一个的拉取太麻烦了, 于是,有了 "光" ^_^ 原理: 将拉取地址写在一个文本里,利用批处理挨个读取,进行cl ...
- 拉取远程分支_git使用教程之创建本地库并关联远程库(笔记整理篇一)
笔者个人博客: https://qiucode.cn/blog 微信小程序 [秋码淘好货] 好久没写文章了,本篇文章笔者就来讲讲什么是Git版本控制系统的使用教程. SVN与Git的最主要的区别 ...
- docker 从harbor 拉取镜像慢_Harbor丨使用的正确姿势
跟着我入门 本次内容带来的是带各位同学如何使用harbor作为自己或者企业的仓库.会更多通过干货的形式分享给你们,例如安装需求,安装事项,安装步骤等. 1-环境要求 docker.io(建议版本16以 ...
- docker pull拉取镜像_docker拉取镜像失败解决
今天在虚拟机上安装了docker-ce之后,从docker官网上去拉取镜像时,报如下错误 [root@localhost util-linux-2.27]# docker pull mysql:8.0 ...
- gitee项目能用SVN拉取吗_用好 Git 和 SVN,轻松驾驭版本管理
来源 | 凌承一链接 | bubuko.com/infodetail-2844306.html 本文从 Git 与 SVN 的对比入手,介绍如何通过 Git-SVN 开始使用 Git,并总结平时工作高 ...
最新文章
- angularjs post 跨域
- Android -- Annotation(注解)原理详解及常见框架应用
- 解决IE6,IE7下子元素使用position:relative、父元素使用overflow:auto后,子元素不随着滚动条滚动的问题...
- 一道网易游戏笔试题的不同解法
- nginx 根据IP 进行灰度发布
- JavaEE 设计模式
- W3C专业术语翻译对照表
- 中职计算机属于专业课还是文化课,对中职计算机专业建设探讨.doc
- pytorch梯度下降函数_Pytorch中常用的四种优化器SGD、Momentum、RMSProp、Adam
- salesforce 架构设计_关于Salesforce证书维护重要通知
- 原版win7集成usb3.0驱动_windows7的不老传说,十代U安装win7教程
- 11.17牛客练习赛31 ABC-----未完
- 一名董事长给大学生的18条忠告(全)
- html语义化标签_9.28晨会分享 常见的HTML5语义化标签、实体字符
- 服务器终端性能测试之iometer
- Engineering Dynamics 2 --- 动量和角动量
- 写论文和平时学习时有用的网站
- Spring boot 集成邮件通知及线程异步发送
- mysql中+desc用法,数据库desc的用法有哪些用法
- python输入一个整数、输出该整数的所有素数因子_一个正整数的所有质数因子
热门文章
- Tensorflow pipeline是什么?
- linun——SElinux的简单理解
- Just another board game 博弈-vector套vector
- thinkphp 微信服务器验证代码_基于ThinkPHP5微信后台管理平台
- springboot nacos配置中心_SpringBoot开发案例之Nacos配置管理中心
- Java设计模式——为什么要用枚举实现单例模式(避免反射、序列化问题)
- Redis 修改密码
- MyBatis like 语句查询
- java io删除文件_java IO 文件操作方法总结
- asp.net session 如何知道是哪个浏览器客户端_微服务下的分布式session管理