IM同步服务
设计概述
后台同步方案的设计就是数据存储结构的设计,如何快速体现“信息变化”,如何快速计算出“变化信息”。后台数据存储结构是由同步协议中同步契约决定的。
设计方案
该方案的同步是按照业务粒度来划分,只需要同步sdk要求同步的数据。
缓存数据模型
//用户信息
UserInfo
{int64 uid; int64 user_info_version; //个人信息版本号string nickname; int64 nickname_version; //昵称版本号string avatar; int64 avatar_version; //头像版本号string signature;int64 signature_version; //签名版本号
}
//群组信息
GroupInfo
{ int64 gid;int64 group_info_version;//群组信息版本号string group_name;string group_desc;
}
//事件信息
Event
{int64 event_id;//事件idint32 event_type; //事件类型 int64 from_uid; //事件发起者int64 gid;//群组idint64 to_uidlist; //事件当事人int64 event_version;//事件版本号
}
//群组成员
GroupUser
{ int64 gid; int64 user_info_version=2; //群组的所有成员中,用户信息最新的成员,他的个人信息版本号 int64 user_list_version=3; //群组成员列表版本号,只要user_list发生变化,该版本号也要发生变化list<UserInfo> user_list; //群组成员列表
}
//用户群组
UserGroup
{ int64 uid;int64 group_info_version; //用户的所有群组中,群组信息最新的群组的版本号 int64 group_list_version; //用户群组列表版本号,只要group_list发生变化,该版本号也要发生变化list<GroupInfo> group_list; //用户群组列表
}
//好友
UserFriend
{int64 uid;int64 user_info_version;//用户的所有好友中,用户信息最新的好友,他的个人信息版本号 int64 user_list_version;//好友列表版本号,只要user_list发生变化,该版本号也要发生变化list<UserInfo> user_list;//好友列表
}
//群组事件
GroupEvent
{list<Event> event_list;//事件列表
}
// GroupMemberSync业务契约需要的请求信息
GroupMemberSync { int64 gid; int64 user_info_version=2; //群组的所有成员中,用户信息最新的成员,他的个人信息版本号 int64 user_list_version=3; //群组成员列表版本号
}
// GroupMemberSync业务契约需要返回的信息
GroupMemberSyncRsp { GroupMemberSync group_member_sync; list<UserInfo> users; list<Event> events; }
同步流程
业务请求处理流程:业务请求->service模块->业务在改变信息本身的同时也要记录信息的变化。
用户信息更新
->用户信息更新请求
->service模块
更新用户信息UserInfo中user_info_version版本号和相应属性nickname_version、signature_version等的版本号。
更新用户所属群组的GroupUser中user_info_version版本号和成员列表中该用户的user_info_version版本号。
更新用户所有好友的UserFriend中user_info_version版本号和成员列表中该用户的user_info_version版本号。
(复杂度为o(n),n表示数据库中操作元素的量级,key-value数据库以key为单位,sql数据库以行为单位)
群组操作(创建群组、退出群组、添加群组成员、删除群组成员)
->创建群组、退出群组、添加群组成员、删除群组成员请求
->service模块
更新用户所属的群组GroupUser中user_list_version版本号。
更新用户群组列表UserGroup中group_list_version版本号。
在群组事件列表GroupEvent中添加一条新记录。
给SDK下发一条业务契约的同步通知,让SDK决定是否要及时同步信息。
// 同步通知
SyncNotification
{list<GroupMemberSync> group_member_sync;
}
同步驱动处理流程:同步驱动->sync模块->业务契约需要的增量更新结果
获取群组成员增量信息
->同步驱动
// 同步驱动
SyncRequest
{list<GroupMemberSync> group_member_sync;
}
->sync模块
比较GetGroupMemberList业务契约请求信息中group_list_version_1 和后台数据库中Group_User的 group_list_version_2,找出该群组的两个版本号之间的Event,得到群组中成员的增量变化。(复杂度为o(n))
比较GetGroupMemberList业务契约请求信息中user_info_version_1 和后台数据库中Group_User的 user_info_version_2,找出该群组两个版本号之间信息发生变化的用户,得到增量的用户信息变化。(复杂度为o(n))
->增量同步结果
// 业务契约的同步结果
message SyncResponse
{list<GroupMemberSyncRsp> group_member_sync_rsp;
}
缺陷
按业务粒度划分会导致业务和业务之间的同步信息有交集,也就是说会产生某些元信息出现重复同步。
难点
KEY-VALUE数据库需要提供批量操作KEY的接口。
需要一个可容灾的生成全局增量序列的服务。
相关文章:
IM同步服务
设计概述 后台同步方案的设计就是数据存储结构的设计,如何快速体现“信息变化”,如何快速计算出“变化信息”。后台数据存储结构是由同步协议中同步契约决定的。 设计方案 该方案的同步是按照业务粒度来划分,只需要同步sdk要求同步的数据。…...
MySQL 运维常用脚本
常用功能脚本 1.导出整个数据库 mysqldump -u 用户名 -p –default-character-setlatin1 数据库名 > 导出的文件名(数据库默认编码是latin1) mysqldump -u wcnc -p smgp_apps_wcnc > wcnc.sql 2.导出一个表 mysqldump -u 用户名 -p 数据库名 表名> 导出的文件…...
ABC322刷题记
ABC322刷题记 T1.A A - First ABC 2。 妥妥的简单题…… 用find函数做就行。(如果不存在那个子串就返回-1,否则返回第一次出现位置) 注意题目中编号是从1开始的。 时间复杂度:O(log(n))。find函数有一定代价,我记…...
visual studio的安装及scanf报错的解决
visual studio是一款很不错的c语言编译器 下载地址:官网 点击后跳转到以下界面 下滑后点击下载Vasual Sutdio,选择社区版即可 选择位置存放下载文件后,即可开始安装 安装时会稍微等一小会儿。然后会弹出这个窗口,我们选择安装位…...
React生命周期
React的生命周期主要是指React组件从创建到销毁的过程,包括三个阶段:挂载期(实例化期)、更新期(存在期)、卸载期(销毁期) 挂载期: constructor(props&#…...
SpringBoot整合RocketMQ笔记
SpringBoot版本为2.3.12.Release RocketMQ对比kafka 学习链接 https://zhuanlan.zhihu.com/p/335216381 代码实战 https://www.cnblogs.com/RedOrange/p/17401238.html Centos安装rocketmq https://blog.csdn.net/chuige2013/article/details/123783612 RocketMQ详细配置与…...
【【萌新的RiscV学习之在写代码之前对于关键路径的分析-11】】
萌新的RiscV学习之在写代码之前对于关键路径的分析-11 首先我们最简单的control 模块 全分段 因为只有分段 , 分开使用之后 , 各个阶段的具体功能才会合理使用 就像是为了后续 “气泡” 赋值 为 0 还有单独比较前递这种 EX : ALUOP ALUSrc …...
A. Sequence with Digits
题目:样例: 输入 8 1 4 487 1 487 2 487 3 487 4 487 5 487 6 487 7输出 42 487 519 528 544 564 588 628 思路: 暴力模拟题,看这数据范围,有些人可能会被唬住,以为是高精度或者容易超时,实际上…...
gitlab配置webhook限制提交注释
一、打开gitlab相关配置项 vim /etc/gitlab/gitlab.rb gitlab_shell[custom_hooks_dir] "/etc/gitlab/custom_hooks" 二、创建相关文件夹 mkdir -p /etc/gitlab/custom_hooks mkdir -p /etc/gitlab/custom_hooks/post-receive.d mkdir -p /etc/gitlab/custom_h…...
蓝桥杯Python scratch C++选拔赛stema个人如何报名?
如果不会操作,可以微信makytony协助。...
Cesium实现动态旋转四棱锥(2023.9.11)
Cesium实现动态悬浮旋转四棱锥效果 2023.9.11 1、引言2、两种实现思路介绍2.1 思路一:添加已有的四棱锥(金字塔)模型实现(简单但受限)2.2 思路二:自定义四棱锥几何模型实现(复杂且灵活ÿ…...
2023最新PS(photoshop)Win+Mac免费下载安装包及教程内置AI绘画-网盘下载
2023最新PS(photoshop)WinMac免费下载安装包及教程内置AI绘画-网盘下载 2023最新PS(photoshop)免费下载安装教程来咯~ 「PhotoShop」全套,winmac: https://pan.quark.cn/s/9d8d8ef5c400#/list/share 所有版本都有 1,复制链接…...
【JAVA】为什么要使用封装以及如何封装
个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 前言 Java的封装指的是在一个类中将数据和方法进行封装,使其可以保护起来,只能在该类内部访问,而不允许外部直接访问和修改。这是Java面向对象编程的三…...
18.示例程序(编码器接口测速)
STM32标准库开发-各章节笔记-查阅传送门_Archie_IT的博客-CSDN博客https://blog.csdn.net/m0_61712829/article/details/132434192?spm1001.2014.3001.5501 main.c #include "stm32f10x.h" // Device header #include "Delay.h" #incl…...
【超详细】Fastjson 1.2.24 命令执行漏洞复现-JNDI简单实现反弹shell(CVE-2017-18349)
前言: 看了很多别人关于漏洞复现过程,很多博客过程简洁,有的过程过于复杂,比如看到写java代码,用javac进行编译等等。所以我想写出比较详细的漏洞复现过程。 一,漏洞介绍 1-1 fastjson是什么 fastjson是…...
【牛客网】JZ39 数组中出现次数超过一半的数字
题目 思路 思路1 将数组排序,再保证有结果的情况下,此时数组中间的数字就是想要的结果 思路2 在保证有结果的情况下,此时数组的的众数是数组长度的一半以上 所以我们可以通过抵消的做法来找到最终的结果 我们可以从头遍历这个数组,如果两个数不相同,则消去这两个数,最坏的…...
【Mysql】Lock wait timeout exceeded; try restarting transaction
出现这种问题通常是有事务长时间未提交导致的 可以使用以下sql 查询事务进程 然后通过 kill 线程ID 的方式 ,结束该事务 SELECTtrx_id AS 事务ID,trx_mysql_thread_id AS 线程ID,trx_state AS 事务状态,trx_started AS 开始时间,trx_tables_locked AS 锁定的表,trx_query AS …...
python生成中金所期权行权价
参考沪深300股指期权的合约表,写一个工具函数: 使用方法 def get_format_option_gap(value: float, deviation: int 0): # 根据中证1000指数获取点位"""根据标准的行权价,生成不同档位的期权列表,适合中金所:…...
CentOS7.9 安装postgresql
# 添加postgres账户 sudo groupadd postgres sudo useradd -g postgres postgres # 修改postgres账号密码 passwd postgres # 安装postgresql cd ~tar zxvf postgresql-15.3.tar.gz cd postgresql-15.3./configure --prefix/usr/local/pgsql --without-readlinemake -j4 …...
qt线程介绍
目录 介绍 线程类 QThread 方式1 方式2 案例 线程资源释放 介绍 qt为多线程提供了完美的支持,实现多线程一般是从从QTHread中继承定义自己的线程类,QT也提供了QMutexLocker,QwaitCondition等类实现线程同步,与Linux系统或C中的线程库类似…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
