钉钉消息已读、未读咋实现的嘞?

前言

一款app,消息页面有:钱包通知、最近访客等各种通知类别,每个类别可能有新的通知消息,实现已读、未读功能,包括多少个未读,这个是怎么实现的呢?比如用户A访问了用户B的主页,难道用rabitmq给B发通知消息吗?量大了成本受得了吗?有没有成本低的方案呢

img

小谈

挺好的一个问题,可惜其他的回答要么是大而化之想当然,要么是顾左而言他,没有一个正经的回答。

这个是很常见的需求,在做这类需求的时候,首先要做的是,设计一个合适的业务模型,那么这个模型就是“对话模型”,

将问题中的"设置",“赚钱积分”,"最近听众","好友跟新","最近来访"当做一个“虚拟人”来处理,你跟"虚拟人"组成了一个"对话列表(msg_group)"

“虚拟人”与正常人的区别就是,虚拟人与你的对话是单向的,只能他向你发消息,你无法回复。

所有,判断有没有小红点,或者小红点的数字是多少,就是简单的获取你与虚拟人的对话的未读的消息的数量。

“最近来访”标签

当有人访问你主页的时候,后端会以这个“最近来访”虚拟人的身份给你发一条消息,不过消息里还有一个特殊标记,标明了来源。我们除了要拉取总量,还有不同来源消息的数量。当然,一个动作不一定只发一条消息,比如,图中下方有个金刚键"消息",它是所有消息的总和,所以,投递其他消息的时候,也要给它投递一次,不过它只展示一个未读数字,所以这个消息只需要一个msg_id即可,不需要消息payload。

前端怎么展示

看具体产品需求。

每个对话可以看作一个msg_group,它是一个消息的队列(注意,不是我们常说的消息队列),每条msg的msg_id都是有序递增的,至于msg_id只是队列内有序还是全局有序,就看你选择了,一般数据10亿以内没必要优化,发号器全局有序即可。这个队列有基本的信息:参与人(图中的例子只有2个,你和“虚拟人”),maximal_msg_id。

你只需要保存一个last_pull_msg_id或last_read_msg_id即可,在拉取信息的时候,带上这个last_msg_id即可。

当然,消息列表的存储,读取,就比较多样了。可以是MySQL,nosql,hbase,redis。一般我们是混合存储,特别老的存hbase,比较老的存mysq或nosql,新数据存redis。云厂商也有专门针对这类场景的存储产品。大多数情况,我们只需要一个数量,固定从maximal_id往前取,如果取到100条还没完,直接返回99+完事了。

实际上,图中的需求,比如“设置”,"隐私设置",是整个产品全局的,所以可以弄个简单的"广播消息模式",广播模式就是维持一个单向的消息的队列,所有的人都可以拉取这个队列的消息,只需要他们各位维护自己的last_id即可。

"已读和未读"。它包含两层意思,一个判否,即内容你是否读过,二是计数,即这个内容有多少人读过。

长尾原因

如果你用Redis存储,成本非常高,浪费非常严重。如果不用redis,一旦刷到历史数据,会非常非常慢。在这里bitmap肯定是搞不定的,因为bitmao需要加载全部数据,显然不可行。

这个时候,通常的策略是"[log record]"和"comb", 我们每产生一个动作,比如读,赞,收藏,就会产生一个log record( 取关,取消赞...也是一条独立的log record),我们由专门的大数据系统统一收集这些record,然后对多个维度的数据统计,将统计结果存起来,前端获取数据的时候,先从缓存取,取不到再到comb取。comb的数据规模是远远小于log record的,查询速度非常快。

log record因为不涉及查询,所以没必要用数据库,一般直接存hbase或cassandra这类廉价存储介质。

热门内容

用户互动非常活跃,所以在写入log record的时候,会直接同步更新缓存,但是缓存的数据并不保证十分准确,它只是迷惑用户的,准确的数据是以log record为准的,你在wb经常可以看热门内容的点赞数跟实际的数量不符。因为wb的缓存,独立的counter,实际的数据不同步。

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/61496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin的内置函数 apply、let、run、with、also

let 1.let函数返回类型,是根据匿名函数的最后一行变化而变化 2.let函数中的匿名函数里面持有的是it 集合自身 fun main() {var num1 1var num2 1var result:Intresult num1 num2var str result?.let {//传入本身,it指代本身即result,result不为空…

Mac下Docker Desktop安装命令行工具、开启本地远程访问

Mac系统下,为了方便在terminal和idea里使用docker,需要安装docker命令行工具,和开启Docker Desktop本地远程访问。 具体方法是在设置-高级下, 1.将勾选的User调整为System,这样不用手动配置PATH即可使用docker命令 …

Nuxt 菜鸟入门学习笔记五:CSS 样式

文章目录 本地样式表在组件内导入通过 Nuxt 配置 CSS 属性导入使用字体导入通过 NPM 发布的样式表 外部样式表动态添加样式表【高级】使用 Nitro 插件修改渲染的头部 使用预处理器单文件组件 SFC 样式类和样式绑定使用 v-bind 的动态样式Scoped StylesCSS Modules预处理器支持 …

基于Python+OpenCV智能答题卡识别系统——深度学习和图像识别算法应用(含Python全部工程源码)+训练与测试数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境PyCharm安装OpenCV环境 模块实现1. 信息识别2. Excel导出模块3. 图形用户界面模块4. 手写识别模块 系统测试1. 系统识别准确率2. 系统识别应用 工程源代码下载其它资料下载 前言 本项目基于Python和OpenCV图像处…

多重背包模板题,P1776 宝物筛选

题目描述 终于,破解了千年的难题。小 FF 找到了王室的宝物室,里面堆满了无数价值连城的宝物。 这下小 FF 可发财了,嘎嘎。但是这里的宝物实在是太多了,小 FF 的采集车似乎装不下那么多宝物。看来小 FF 只能含泪舍弃其中的一部分…

【SA8295P 源码分析】87 - SA8295P HQNX + Android 编译环境搭建指导

【SA8295P 源码分析】87 - SA8295P HQNX + Android 编译环境搭建指导 一、Android 编译环境搭建:Android + sa8295p-hqx-4-2-4-0_hlos_dev_la.tar.gz1.1 更新 Ubuntu 18.04 源路径1.2 安装基础编译环境1.3 设置JDK8 的环境变量1.4 配置sh为bash(默认为dash)1.5 Android 编译…

图像扭曲之旋转

源码: void twirl(cv::Mat& src,cv::Mat& dst,double angle,double radius) {dst.create(src.rows, src.cols, CV_8UC3);dst.setTo(0);int radius2radius*radius;int cx src.cols / 2;int cy src.rows / 2;int distance,distance2 0;for (int h 0; h &…

P13 VUE 二级menu实现

主要修改以下几个点&#xff1a; CommonAside.vue中 外层便利有孩子节点&#xff0c;关键词key是对应的标签&#xff0c;class动态图表渲染 内层遍历不能再用item&#xff0c;用subitem&#xff0c;遍历该item.childeren&#xff0c;关键词是path&#xff0c; <templat…

k8s etcd 简介

Etcd是CoreOS基于Raft协议开发的分布式key-value存储&#xff0c;可用于服务发现、共享配置以及一致性保障&#xff08;如数据库选主、分布式锁等&#xff09;。 如&#xff0c;Etcd也可以作为微服务的注册中心&#xff0c;比如SpringCloud也基于ETCD实现了注册中心功能&#…

dayjs格式转换成日期

目录 方法一&#xff1a; ​编辑方法二&#xff1a; 这个项目在筛选订单时间的时候是由前端进行筛选的&#xff0c;用的是adt-design-pro进行二开的&#xff0c;其中在用日期组件的时候遇到了一个问题&#xff0c;组件返回的是&#xff1a; 但是我需要的是年-月-日&#xff…

OpenCV中Mat、Ipllmage以及Halcon中Hobject数据类型之间转换

OpenCV中Mat、CVMat、Ipllmage类型都可以代表和显示图像。IplImage是由CVMat派生,而CvMat由CvArr派生即CvArr -> CvMat -> IplImage,Mat类型则是C++版本的矩阵类型(CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat处理)。 Mat类型侧重于计算,数…

计算机网络 第二节

目录 一&#xff0c;计算机网络的分类 1.按照覆盖范围分 2.按照所属用途分 二&#xff0c;计算机网络逻辑组成部分 1.核心部分 &#xff08;通信子网&#xff09; 1.1电路交换 1.2 分组交换 两种方式的特点 重点 2.边缘部分 &#xff08;资源子网&#xff09; 进程通信的方…

模拟电子技术基础学习笔记三 PN结

采用不周的掺杂工艺&#xff0c;将P型半导体与N型半导体制作在同一块硅片上&#xff0c;在它们的交界面就形成PN结。 扩散运动 物质总是从浓度高的地方向浓度低的地方运动&#xff0c;这种由于浓度差而产生的运动称为扩散运动。 空间电荷区 - 耗尽层 漂移运动 在电场力的作…

成集云 | 飞书审批同步金蝶云星空 | 解决方案

源系统成集云目标系统 方案介绍 飞书员工报销审批通过后&#xff0c;审批单据内容和审批状态实时同步金蝶云星空 飞书是字节跳动于2016年自研的新一代一站式协作平台&#xff0c;将即时沟通、日历、云文档、云盘和工作台深度整合&#xff0c;通过开放兼容的平台&#xff0c;…

BIO到NIO、多路复用器, 从理论到实践, 结合实际案例对比各自效率与特点(下)

文章目录 多路复用器简介多路复用器的两个阶段Java中的多路复用器封装测试代码压测结果总结 本篇文章是BIO到NIO、多路复用器, 从理论到实践, 结合实际案例对比各自效率与特点(上)的下一篇, 如果没有看的小伙伴, 可以先看下, 不然可能会不连贯. 多路复用器简介 多路复用器是对…

JavaScript Web APIs - 04 日期对象 、DOM节点操作

Web APIs - 04 文章目录 Web APIs - 04日期对象实例化方法时间戳 DOM 节点插入节点删除节点查找节点父子关系兄弟关系 进一步学习 DOM 相关知识&#xff0c;实现可交互的网页特效 能够插入、删除和替换元素节点能够依据元素节点关系查找节点 日期对象 掌握 Date 日期对象的使…

针对服务器实例安全组(Security Groups)的配置

文章目录 出入栈规则&#xff08;Onbound / Inbound rules&#xff09;1. 后端2. 数据库3. 网站 出入栈规则&#xff08;Onbound / Inbound rules&#xff09; 1. 后端 访问后端接口部分-HTTP/HTTPS&#xff0c;不能够限定IP&#xff1b;但是针对其他远程登录部分-SSH等&…

学习笔记:ROS使用经验(ROS报错)

报错&#xff1a;进程崩溃 ] process has died [pid 734, exit code -5, cmd /root/catkin_ws/devel/lib/pose_graph/pose_graph __name:pose_graph __log:/root/.ros/log/31b0ae1c-3295-11ee-bda9-02429b5737dc/pose_graph-5.log]. log file: /root/.ros/log/31b0ae1c-3295-11…

足球联赛积分2

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

使用 Laf 一周内上线美术狮 AI 绘画小程序

“美术狮 AI 绘画”&#xff08;以下简称“美术狮”&#xff09;&#xff0c;是我们小团队的一次尝试&#xff0c;定位是人人都可以上手的&#xff0c;充满创意的&#xff0c;理解中文和中国文化的图片生成工具。 在完善图像模型和论证核心问题之后&#xff0c;我们开始构建 MV…