当前位置: 首页 > news >正文

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

前言

一款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 发布!

相关文章:

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

前言 一款app,消息页面有:钱包通知、最近访客等各种通知类别,每个类别可能有新的通知消息,实现已读、未读功能,包括多少个未读,这个是怎么实现的呢?比如用户A访问了用户B的主页,难道…...

Java 读取TIFF JPEG GIF PNG PDF

Java 读取TIFF JPEG GIF PNG PDF 本文解决方法基于开源 tesseract 下载适合自己系统版本的tesseract ,官网链接:https://digi.bib.uni-mannheim.de/tesseract/ 2. 下载之后安装,安装的时候选择选择语言包,我选择了中文和英文 3.…...

研磨设计模式day14模板方法模式

目录 场景 原有逻辑 有何问题 解决方案 解决思路 代码实现 重写示例 模板方法的优缺点 模板方法的本质 何时选用 场景 现在模拟一个场景,两个人要登录一个系统,一个是管理员一个是用户,这两个不同身份的登录是由后端对应的两个接…...

7 集群基本测试

1. 上传小文件到集群 在hadoop路径下执行命令创建一个文件夹用于存放即将上传的文件: [atguiguhadoop102 ~]$ hadoop fs -mkdir /input上传: [atguiguhadoop102 hadoop-3.1.3]$ hadoop fs -put wcinput/work.txt /input2.上传大文件 [atguiguhadoop1…...

chrono学习(一)

我想用chrono进行沙土的仿真,首先学习demo_GPU_ballCosim.cpp,这个例子仿真了一些沙土的沉降过程。 首先,运行编辑完成的文件demo_GPU_ballCosim: (base) eowyneowyn-MS-7D20:~/build_chrono/bin$ ./demo_GPU_ballCosim 运行完得…...

后端面试话术集锦第 十 篇:springMVC面试话术

这是后端面试集锦第十篇博文——springMVC面试话术❗❗❗ 1. 介绍一下springMVC springmvc是一个视图层框架,通过MVC模型让我们很方便的接收和处理请求和响应。 我给你说说他里边的几个核心组件吧: 它的核心控制器是DispatcherServlet,他的作用是接收用户请求,然后给用户…...

基于Django 框架搭建的机器学习在线平台源代码+数据库,实现KNN、ID3、C4.5、SVM、朴素贝叶斯、BP神经网络等算法及流程管理

结果展示(Kmeans): 完整代码下载地址:基于Django 框架搭建的机器学习在线平台源代码数据库 python机器学习之 K-邻近算法 简单的理解:[ 采用测量不同特征值之间的距离方法进行分类 ] 优点 :精度高、对异常…...

大数据组件-Flume集群环境搭建

🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…...

想系列服务迁移专有云效实操

想系列服务迁移专有云效实操 1注册应用 查看jenkins脚本是否需要修改代码编译路径 gemdale_jenkins/maven3-service/k8s-image/maven3-service-deploy.sh Jenkins上的打包路径 service_tgt_path s e r v i c e w s / t a r g e t / service_ws/target/ servicew​s/target/ser…...

2020 牛客多校第三场 C Operation Love (叉积判断顺逆时针)

2020 牛客多校第三场 (叉积判断顺逆时针) Operation Love 大意: 给出一个手型 , 每个手型都有 20 个点 ,手型有可能旋转后给出 , 但不会放大和缩小 . 手型点集有可能顺时针给出也可能逆时针给出 , 判断给出的是左手还…...

基于OFDM的水下图像传输通信系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 function [rx_img] func_TR(tx_img, num_path, pathdelays, pathgains, snr) rng(default); …...

Docsify + Gitalk详细配置过程讲解

💖 作者简介:大家好,我是Zeeland,开源建设者与全栈领域优质创作者。📝 CSDN主页:Zeeland🔥📣 我的博客:Zeeland📚 Github主页: Undertone0809 (Zeeland)&…...

React中的setState的执行机制

文章目录 前言setState是什么?更新类型批量更新后言 前言 在 React 中,setState 是用于更新组件状态的方法。它是一个异步操作 值得注意的是,由于 setState 是异步的,所以在调用 setState 后立即访问 this.state 可能得到的还是旧的状态值。…...

2023最新任务悬赏平台源码uniapp+Thinkphp新款悬赏任务地推拉新充场游戏试玩源码众人帮威客兼职任务帮任务发布分销机

新款悬赏任务地推拉新充场游戏试玩源码众人帮威客兼职任务帮任务发布分销机制 后端是:thinkphpFastAdmin 前端是:uniapp 1.优化首页推荐店铺模块如有则会显示此模块没有则隐藏。 2修复首页公告,更改首页公告逻辑。(后台添加有公…...

微服务事务管理(Dubbo)

Seata 是什么 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 一、示例架构说明 可在此查看本示例完整代码地址&#x…...

Springboot整合ClickHouse

一、快速开始 1、添加依赖 <dependency><groupId>ru.yandex.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version>0.3.1-patch</version> </dependency> <dependency><groupId>com.alibaba&…...

【材料整理】-- Python、Matlab中常用调试代码,持续更新!

文章目录 Python、Matlab中常用调试代码&#xff0c;持续更新&#xff01;一、Python常用调试代码&#xff1a;二、Matlab常用调试代码&#xff1a; Python、Matlab中常用调试代码&#xff0c;持续更新&#xff01; 一、Python常用调试代码&#xff1a; 1、保存.mat文件 from…...

什么是同源策略(same-origin policy)?它对AJAX有什么影响?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 同源策略&#xff08;Same-Origin Policy&#xff09;与 AJAX 影响⭐ 同源策略的限制⭐ AJAX 请求受同源策略影响⭐ 跨域资源共享&#xff08;CORS&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记…...

视频汇聚/视频云存储/视频监控管理平台EasyCVR接入海康SDK协议后无法播放该如何解决?

开源EasyDarwin视频监控/安防监控/视频汇聚EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#…...

CSC2121A

半桥架构的栅极驱动电路CSC2121A CSC2121系列是一款高性价比的半桥架构的栅极驱动专用电路&#xff0c;用于大功率MOS管、IGBT管栅极驱动。IC内部集成了逻辑信号处理电路、死区时间控制电路、欠压保护电路、电平位移电路、脉冲滤波电路及输出驱动电路&#xff0c;专用于无刷电…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...