Netty+springboot开发即时通讯系统笔记(四)终
实时性
1.线程池多线程,把消息同步给其他端和对方用户,其中数据持久化往往是最浪费时间的操作,可以使用mq异步存储,因为其他业务不需要拿着整条数据,只需要这条数据的id进行操作。
2。消息校验前置,放在tcp层(netty服务中)
可靠性
tcp协议只能保证数据在传输过程中不丢失,但不能保证到某一端不会丢失,比如传输过程中接收方断网,数据就无法发送到接收方 。
可靠性可以通过消息重发来保证消息一定送到了对方手中。可以通过双重ack确认机制来实现:
A向im服务端发送数据,服务端收到就返回一个ack,A收到这个ack就停止重发,否则就再次尝试重发。当然重发需要设计上限次数的。
然后服务端接到A的数据,再发送给B,B接到之后告诉服务端,返回一个接受到的ack。服务端把收到的再传回给A,此时A确定了此次传输是成功的。中间任何环节出问题,A就执行重发就ok了。
如果B不在线,服务端是可以感知到的,服务端可以代替B向A回复停止重发指令。
有序性
因为我们使用多线程保证了消息的实时性,那么就会导致消息有乱序的风险。
解决方案:
使用redis的incr命令实现原子性的递增序列号,但是过度依赖redis可能会因为redis的崩溃而造成系统失效
幂等性
再im服务端存储每次发过来的消息id(设置过期时间),重复发送的消息id将不再进行持久化但仍会给另一个客户端发送消息。这样就会导致另一个客户端由于网络问题如果没有及时返回ack确认,那么他确实会收到2条相同的消息,但是在去重是完全可以处理的。
qq发消息失败会有红色感叹号,当再次点击重发时是把它当作一条新的消息id发送的,而不是之前的消息id。
消息已读功能
在写扩散中,每个人对自己的每条消息都可以直接获取,已读只不过是个字段罢了。
在读扩散中,以群聊为例,可以在群成员表中加入一个字段,该字段表示改成员读到的最后一条消息序列(保证有序性的那个递增序列),在这条消息之前的就表示读过了
离线消息存储
IM(即时通讯)系统中的离线消息是指在目标用户不在线或者不可达时,发送方发送的消息无法直接传递给目标用户,而是被服务器暂时存储起来,等到目标用户上线或者可达时再进行投递。
离线消息的存在是为了保证消息的可靠性和完整性。当发送方发送消息时,如果目标用户在线,消息可以直接传递给目标用户;但如果目标用户不在线,服务器会将该消息存储在消息队列或者数据库中,等到目标用户上线后,服务器会将离线消息投递给目标用户。
离线消息通常具有以下特点:
- 持久化存储:离线消息通常被存储在服务器的数据库或者消息队列中,确保消息的持久性,即使服务器重启或者断电,消息也不会丢失。
- 时效性:离线消息通常会设置一个过期时间,在一定时间范围内等待目标用户上线,过期后会被清理或者丢弃。
- 投递策略:服务器会在目标用户上线后,根据一定的投递策略(如先进先出、按时间戳等)将离线消息按顺序投递给目标用户。
- 通知机制:当目标用户上线后,服务器可能会发送通知给目标用户,告知其有离线消息待接收。
这里的存储使用redis,每人只存1000条,超过就淘汰最早的,使用zset存储,使用消息的递增序列号作为排序标准,zset支持查询范围内指定数量的元素(SMEMBERS命令)。
即使你错过了离线消息的通知和消息盒子,你仍然可以通过滚动查看聊天记录,找到之前的离线消息。
登录之后的数据同步(历史记录的拉取)
不可能说每次登录都把所有记录都删了重新拉取一遍的,所以这里采用增量拉取。
需要拉取的东西有会话,好友列表,好友申请,为每个需要拉取的数据记录下他的递增序列号,每次只拉取大于记录里最大的序列号。
客户端可以用数据库sqllite
在线状态设计
正常情况下,你的上线和下线等状态应该通知给你的所有好友,和你在的所有群里的所有成员,这将是非常恐怖的数据量。
改进1:只推给在线用户
改进2:
- 按需拉取:在按需拉取的策略下,IM 系统不会主动向所有好友和群成员发送上线和下线等状态通知。相反,当其他用户需要获取某个用户的状态时,他们可以向服务器发送请求,然后服务器根据请求返回相应的状态信息。这种方式可以避免将状态通知广播给所有人,只有真正需要获取状态信息的用户才会发起请求,减少了不必要的数据传输和处理。
- 临时订阅:临时订阅是指用户可以临时订阅某个好友或群组的状态更新通知。当用户订阅了某个用户或群组后,只有在被订阅对象的状态发生变化时,系统才会向订阅者发送通知。这样可以避免向所有好友和群成员广播状态更新,只有被订阅的对象状态发生变化时,才会发送通知给订阅者。这种方式可以根据用户的实际需求,选择性地接收特定用户或群组的状态更新通知,减少了不必要的通知量。
陌生人发消息限制
-
计数限制:为每个用户设置一个计数器,记录他们发送给陌生人的消息数量。当陌生人发送消息时,系统会检查计数器的值。如果计数器小于等于三,允许发送消息并将计数器加一;如果计数器大于三,拒绝发送消息。
-
时间限制:除了计数限制,可以设置一个时间限制,例如每小时或每天只允许陌生人发送三条消息。系统会记录陌生人发送消息的时间,并在规定的时间段内检查发送数量。如果超过限制,拒绝发送消息。
相关文章:
Netty+springboot开发即时通讯系统笔记(四)终
实时性 1.线程池多线程,把消息同步给其他端和对方用户,其中数据持久化往往是最浪费时间的操作,可以使用mq异步存储,因为其他业务不需要拿着整条数据,只需要这条数据的id进行操作。 2。消息校验前置,放在t…...
java -jar 启动服务后,关闭命令窗口后服务停止
java -jar 启动服务后,关闭命令窗口后服务停止 问题:当我们用java -jar命令启动服务后,只有一直保持Xshell的窗口开启且正常连接服务器时才能访问服务,当关闭命令窗口时,服务会停止运行 解决:使用nohup命…...
Android PowerManager的使用
唤醒锁定 如果需要使 CPU 保持运行状态,以便在设备进入休眠模式之前完成某项工作,可以使用“唤醒锁定” 。 添加权限 <uses-permission android:name"android.permission.WAKE_LOCK" />设置唤醒锁定 PowerManager powerManager (Po…...
安防监控/视频集中存储/云存储平台EasyCVR v3.3增加首页告警类型
安防监控/视频集中存储/云存储EasyCVR视频汇聚平台,可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等…...
7-6 统计字符出现次数
分数 20 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 本题要求编写程序,统计并输出某给定字符在给定字符串中出现的次数。 输入格式: 输入第一行给出一个以回车结束的字符串(少于80个字符);第二行输入一个…...
美国大模型风向速报(一)为何重视提示工程?LangChain+向量数据库+开源大模型真香...
多家,且独家来自美国的信源同时向“亲爱的数据”表示, 提示工程(Prompt Engineering)在美国大模型领域备受重视。 读者都要聊, 那就干活。 (一)开源真香 现阶段,AI开源极客大展身手&…...
excel统计函数篇2之count系列
1、COUNT(value1,[value2],…):计算参数列表中数字的个数 2、COUNTA(value1,[value2],…):计算参数列表中值的个数 联想在excel之数学函数、excel中的通配符一文中提到求和函数: SUMIF(range,ceriteria,[sum_range]):对范围内符合指定条件的…...
vue3组件多个根节点报错
打开扩展商店搜索下载 vetur 打开设置命令面板 搜索eslint 将下面的勾选取消...
基于Rust的QuickLZ压缩算法的详细实现与分析
1. 引言 QuickLZ是一种被广泛应用的高效压缩算法。在许多应用中,快速的数据压缩和解压缩是非常关键的,特别是在网络传输和存储空间有限的场景中。为了满足现代软件开发的需求,我们将使用Rust语言来实现这一算法。Rust是一种专为系统级编程而…...
next.js 创建 react ant design ts 项目
环境说明:next.js 官方文档要求node版本在16.8以上。笔者使用的 node版本是16.20.1,不要使用16.13.0,笔者在使用 node16.13.0环境时创建的 react 项目点击事件无效 next.js官网截图 next.js 官网:https://nextjs.org/ react 官网…...
无涯教程-Perl - use函数
描述 此函数将MODULE导出的所有功能(或仅LIST引用的功能)导入当前包的名称空间。有效等效于- BEGIN { require "Module.pm"; Module->import(); }也用于在当前脚本上强加编译器指令(编译指示),尽管从本质上讲它们只是模块。 请注意,use语句在编译时进行判断。在…...
(7)(7.6) 恢复任务回放
文章目录 前言 7.6.1 配置 7.6.2 工作原理 7.6.3 局限性 前言 本页介绍了什么是"任务继续时后退"功能以及如何使用该功能。 !Note 从 4.1 版起,Plane、Copter 和 Rover 均可使用此功能。 在某些应用或运行区域,为了消除冲突&…...
spark yarn 开启动态资源分配
概念 不需要指定并发,只需要指定内存, 程序在运行后会动态调节并发数量,我们只需要设置一个上线即可 在spark 配置文件设置: spark.dynamicAllocation.enabled true spark.shuffle.service.enabled true 准备shuffer jar 将spar…...
Android学习之路(8) Activity
本节引言: 本节开始讲解Android的四大组件之一的Activity(活动),先来看下官方对于Activity的介绍: 移动应用体验与桌面体验的不同之处在于,用户与应用的互动并不总是在同一位置开始,而是经常以不确定的方式开始。例如&…...
Linux的热拔插UDEV机制
文章目录 UDEV简介守护进程基本特点 守护进程和后台进程的区别开发守护进程结束 UDEV简介 udev是一个设备管理工具,udev以守护进程的形式运行,通过侦听内核发出来的uevent来管理/dev目录下的设备文件。 udev在用户空间运行,而不在内核空间 …...
Azure应用程序网关
文章目录 什么是应用程序网关实战演练创建虚拟网络创建虚拟机创建应用程序网关测试搭建结果 什么是应用程序网关 Azure应用程序网关是一种托管服务,用于提供安全、可缩放的 Web 应用程序前端点的应用程序传送控制和保护。它可以通过 SSL 终止、cookie 基于会话持久…...
免费开源服务器资源监控系统grafana+prometheus+node_exporter
有项目做测试的时候需要查询服务器资源利用情况,自己又没写相应的模块,此时就需要一套好用的资源监控系统,,咨询了运维人员给推荐了一套,装完后真的很好用。 就是grafanaprometheusnode_exporter(linux&am…...
【文化课学习笔记】【化学】金属及其化合物
【化学】必修一:金属及其化合物 钠及其化合物 钠单质 物理性质 颜色:银白色,有金属光泽;密度: ρ H 2 O > ρ N a > ρ 煤油 \mathrm{\rho_{H_2O}>\rho_{Na}>\rho_{煤油}} ρH2O>ρNa>ρ煤…...
Java面试题--设计模式
一、Java 中有几种设计模式? Java 中一般认为有 23 种设计模式 分为三大类: 1. 创建型模式 5 种 ① 工厂方法模式 ② 抽象工厂模式 ③ 单例模式 ④ 建造者模式 ⑤ 原型模式 2. 结构型模式 7 种 ① 适配器模式 ② 装饰器模式 ③ 代理模式 ④ 外观模式 …...
【VS Code插件开发】Webview面板(三)
🐱 个人主页:不叫猫先生,公众号:前端舵手 🙋♂️ 作者简介:前端领域优质作者、阿里云专家博主,共同学习共同进步,一起加油呀! 📢 资料领取:前端…...
WebDriver API及对象识别技术
html页面的iframe的切换 定位到客户管理 新增客户 会无法定位到新增客户,因为在另外一个iframe框架之中。 iframe是html中的框架标签,表示文档中可以嵌入文档,或者说是浮动的框架。在selenium中iframe同样如此,如果驱动器对…...
计算机视觉之三维重建(一)(摄像机几何)
针孔摄像机 添加屏障: 使用针孔(o光圈针孔摄像机中心),实现现实与成像一对一映射,减少模糊。其中针孔与像平面的距离为f(焦距);虚拟像平面位于针孔与真实物体之间,与像平面互为倒立关系。位置映射:利用相似…...
机器学习算法-随机森林
目录 机器学习算法-随机森林 (1)构建单棵决策树。 决策树的构建过程 决策树的构建一般包含三个部分:特征选择、树的生成、剪枝。 机器学习算法-随机森林 机器学习算法-随机森林 随机森林是一种监督式学习算法,适用于分类和回…...
Springboot 实践(10)spring cloud 与consul配置运用之服务的注册与发现
前文讲解,完成了springboot、spring security、Oauth2.0的继承,实现了对系统资源的安全授权、允许获得授权的用户访问,也就是实现了单一系统的全部技术开发内容。 Springboot是微服务框架,单一系统只能完成指定系统的功能…...
解决方案:如何在 Amazon EMR Serverless 上执行纯 SQL 文件?
《大数据平台架构与原型实现:数据中台建设实战》一书由博主历时三年精心创作,现已通过知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详…...
pytorch lightning和pytorch版本对应
参见官方文档: https://lightning.ai/docs/pytorch/latest/versioning.html#compatibility-matrix 下图左一列(lightning.pytorch)安装命令:pip install lightning --use-feature2020-resolver 下图左一列(pytorch_lig…...
Postman返回了一个html页面
问题记录 调用公司的测试环境接口,从浏览器控制台接口处cCopy as cURL(cmd),获取完整的请求内容,然后导入postman发起请求 提测时发现返回一个html页面,明显是被请求在网管处被拦截了,网关返回的这个报错html页面 …...
centos服务器搭建宝塔面板
因为电脑无线网无法登录宝塔,也无法ssh到服务器,但是热点可以连接,网上没找到解决方法,重装下。 解决办法,先追路由,结果是被防火墙拦截了,解封以后还不行,重新查,联动的…...
【微信小程序】记一次自定义微信小程序组件的思路
最近来个需求,要求给小程序的 modal 增加个关闭按钮,上网一查发现原来 2018 年就有人给出解决方案了,于是总结下微信小程序自定义组件的思路:一句话,用 wxml css实现和原生组件类似的样式和效果,之后用 JS…...
TiDB数据库从入门到精通系列之四:SQL 基本操作
TiDB数据库从入门到精通系列之四:SQL 基本操作 一、SQL 语言分类二、查看、创建和删除数据库三、创建、查看和删除表四、创建、查看和删除索引五、记录的增删改六、查询数据七、创建、授权和删除用户 成功部署 TiDB 集群之后,便可以在 TiDB 中执行 SQL 语…...
网站关键词重要性/百度联盟注册
1234567891011121314151617package practiceGO; /**5、算水仙花数(100-999):表示三位数的数字,个位的三次方十位的三次方百位的三次方这个数本身 */ public class Cto { public static void main(String[] args) { int first,sec…...
巴中网站制作公司/好口碑关键词优化地址
一、实现Comparator接口方法类似 Merge two sorted list 中介绍的,包括了有名类和匿名类两种方式具体使用:排序:Collections.sort(容器,comparator)Queue q new PriorityQueue(capacity,comparator)二、comparable 抽象类对于com…...
旅游网站结构图/百度查重软件
近期学习 javafx 自己编写了一款软件 (网上尽管也有类似功能的软件,可是界面不够美观,功能比較单一,或者操作比較复杂) 软件官方网址:http://pcm.chujianyun.com 注:安装说明、使用说明、关于等…...
去哪里学做网站app/爱站工具网
PHP调用MYSQL存储过程实例 标签: mysql存储phpsqlquerycmd2010-09-26 11:10 11552人阅读 评论(3) 收藏 举报实例一:无参的存储过程$conn mysql_connect(localhost,root,root) or die ("数据连接错误!!!");mysql_select_db(test,$conn);$sql …...
商城网站/竞价排名是什么
日前,全球影响力知识产权媒体IPRdaily联合incoPat创新指数研究中心发布“2018年全球金融科技发明专利排行榜(TOP20)”,数据范围为从2018年1月1日至2018年12月31日,全球企业2018年公开的发明专利申请数量。入榜前三名分…...
wordpress模版c2c商城/百度软件应用中心
视频教程:http://pan.baidu.com/s/1kXBQj memcached是一套分布式的快取系统,当初是Danga Interactive为了LiveJournal所发展的,但被许多软件(如MediaWiki)所使用。这是一套开放源代码软件,以BSD license授权…...