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

如何快速开发一套分布式IM系统

架构说明:

    1)CIM 中的各个组件均采用 SpringBoot 构建;2)采用 Netty + Google Protocol Buffer 构建底层通信;3)Redis 存放各个客户端的路由信息、账号信息、在线状态等;4)Zookeeper 用于 IM-server 服务的注册与发现。

 

整体主要由以下模块组成:

    1)cim-server——IM 服务端:用于接收 client 连接、消息透传、消息推送等功能。支持集群部署;2)cim-forward-route——消息路由服务器:用于处理消息路由、消息转发、用户登录、用户下线以及一些运营工具(获取在线用户数等);3)cim-client——IM 客户端:给用户使用的消息终端,一个命令即可启动并向其他人发起通讯(群聊、私聊);同时内置了一些常用命令方便使用。

流程解释如下:

    1)客户端向 route 发起登录;2)登录成功从 Zookeeper 中选择可用 IM-server 返回给客户端,并保存登录、路由信息到 Redis;3)客户端向 IM-server 发起长连接,成功后保持心跳;4)客户端下线时通过 route 清除状态信息。

所以当我们自己部署时需要以下步骤:

    1)搭建基础中间件 Redis、Zookeeper;2)部署 cim-server,这是真正的 IM 服务器,为了满足性能需求所以支持水平扩展,只需要注册到同一个 Zookeeper 即可;3)部署 cim-forward-route,这是路由服务器,所有的消息都需要经过它。由于它是无状态的,所以也可以利用 Nginx 代理提高可用性;4)cim-client 真正面向用户的客户端;启动之后会自动连接 IM 服务器便可以在控制台收发消息了。

这里就设计的比较简单,直接利用 Redis 来存储用户信息;用户信息也只有 ID 和 userName 而已。只是为了方便查询在 Redis 中的 KV 又反过来存储了一份 VK,这样 ID 和 userName 都必须唯一。

 

具体的流程:

    1)登录成功之后需要判断是否是重复登录(一个用户只能运行一个客户端);2)登录成功后需要从 Zookeeper 中获取服务列表(cim-server)并根据某种算法选择一台服务返回给客户端;3)登录成功之后还需要保存路由信息,也就是当前用户分配的服务实例保存到 Redis 中。

为了实现只能一个用户登录,使用了 Redis 中的 set 来保存登录信息;利用 userID 作为 key ,重复的登录就会写入失败。

    1)先从 Zookeeper 获取所有的服务实例做一个内部缓存;2)轮询选择一台服务器(目前只有这一种算法,后续会新增)。即时通讯聊天软件app开发可以加小蓝豆的v:weikeyun24咨询即可

当然要获取 Zookeeper 中的服务实例前自然是需要监听 cim-server 之前注册上去的那个节点。

这是一个真正发消息的接口,实现的效果就是其中一个客户端发消息,其余所有客户端都能收到!流程肯定是客户端发送一条消息到服务端,服务端收到后在上文介绍的 SessionSocketHolder 中遍历所有 Channel(通道)然后下发消息即可。服务端是单机倒也可以,但现在是集群设计。所以所有的客户端会根据之前的轮询算法分配到不同的 cim-server 实例中。

由于 Redis 单线程的特质,当数据量大时;一旦使用 keys 匹配所有 cim-route:* 数据,会导致 Redis 不能处理其他请求。所以这里改为使用 scan 命令来遍历所有的 cim-route:*。

接着会挨个调用每个客户端所在的服务端的 HTTP 接口用于推送消息。

之所以说获取在线用户是一个辅助接口,其实就是用于辅助私聊使用的。一般我们使用私聊的前提肯定得知道当前哪些用户在线,接着你才会知道你要和谁进行私聊。

所以私聊接口在收到消息后需要查询到接收者所在的 cim-server 实例信息,后续的步骤就和群聊一致了。调用接收者所在实例的 HTTP 接口下发信息。只是群聊是遍历所有的在线用户,私聊只发送一个的区别。

相关文章:

如何快速开发一套分布式IM系统

架构说明: 1)CIM 中的各个组件均采用 SpringBoot 构建;2)采用 Netty Google Protocol Buffer 构建底层通信;3)Redis 存放各个客户端的路由信息、账号信息、在线状态等;4)Zookeeper …...

W806|CKLINK LITE|调试|elf文件模板|CSDK|Debug|学习(4):CKLINK调试W806

一、硬件连接 接线方式 (连线颜色供参考,本例中采用图示颜色): 注意:CKLINK LITE的3V3须与W806的3V3相连,或者给W806开发板单独供电,两种方式均可。 ​ 否则,会提示“the referenc…...

【100个 Unity实用技能】 ☀️ | 脚本无需挂载到游戏对象上也可执行的方法

Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。Unity 平台提供一整套完善的软件解决方案&#xff…...

「IT女神勋章」挑战赛#

缓存 本地缓存 本地缓存为了保证线程安全问题,一般使用ConcurrentMap的方式保存在内存之中 分布式缓存。 常见的分布式缓存则有Redis,MongoDB等。 一致性:本地缓存由于数据存储于内存之中,每个实例都有自己的副本&#xff0c…...

易优cms user 登录注册标签

user 登录注册标签 user 登录注册入口标签 [基础用法] 标签&#xff1a;user 描述&#xff1a;动态显示购物车、登录、注册、退出、会员中心的入口&#xff1b; 用法&#xff1a; {eyou:user typeuserinfo} <div id"{$field.htmlid}"> …...

源码安装Redis 7.0.9并且systemctl管理

以下是在/usr/local/redis中通过源代码安装Redis 7.0.9并将其加入systemctl管理的步骤&#xff1a; 首先&#xff0c;下载Redis 7.0.9源代码包&#xff1a; wget https://download.redis.io/releases/redis-7.0.9.tar.gz解压缩Redis源代码包&#xff1a; tar xzf redis-7.0.9…...

编写程序:有92号和95号汽油可以选择,选择你需要的汽油,并输入需要加油的升数,点击按钮“`计算总价钱`“在div中可以得到你所需要支付的价格

需求&#xff1a; 有92号汽油和95号可以选择&#xff0c;选择你需要的汽油&#xff0c;并输入需要加油的升数&#xff0c;点击按钮"计算总价钱"在div中可以得到你所需要支付的价格。结构如下图所示&#xff1a; 详细代码如下&#xff1a; <!DOCTYPE html> &l…...

参考文献去哪里查找,参考文献标准格式是什么

1、参考文献类型&#xff1a; 普通图书[M]、期刊文章[J]、报纸文章[N]、论文集[C]、学位论 文[D]、报告[R]、标准[s]、专利[P]、数据库[DB]、计算机程序[CP]、电 子公告[EB]、联机网络[OL]、网上期刊[J&#xff0f;OL]、网上电子公告[EB&#xff0f;OL]、其他未 说明文献[z]。…...

WIFI标签操作步骤

1. 打开并设置手机WIFI热点&#xff0c;设置SSID为ESL&#xff0c;密码为123456789&#xff08;如下图&#xff09; ​ 2. 运行APP&#xff0c;设置要接入的WIFI名称密码等信息&#xff08;如下图&#xff09; ​ 3. 长按背面按键&#xff08;长按2-3秒&#xff09;&#xff0c…...

【Hello Linux】命令行解释器

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;使用进程的基础知识和进程控制知识做出一个简单的shell程序 命令行解释器介绍搭架子缓冲区获取命令如何从标准输入中获取字符串解析命令…...

开源一个通用的 HTTP 请求前端组件

像 Postman 这样可视化的 HTTP 请求工具是调试 API 不可或缺的利器。Postman 虽好但也越来越重&#xff0c;而且如果要整合到其他工具中&#xff0c;显然 Postman 又不是一个可行的方案。于是我想打造一个简单的前端组件&#xff08;widget&#xff09;&#xff0c;它是一个标准…...

等保测评机构资质申请条件是什么?个人可以申请吗?

最近看到不少网友在问&#xff0c;等保测评机构资质申请条件是什么&#xff1f;个人可以申请吗&#xff1f;今天我们小编就来给大家详细回答一下。 等保测评机构资质申请条件是什么&#xff1f;个人可以申请吗&#xff1f; 【回答】&#xff1a;首先需要明确一点的是&#xf…...

android 卡顿、ANR优化(1)屏幕刷新机制

前言&#xff1a; 本文通过阅读各种文章和源码总结出来的&#xff0c;如有不对&#xff0c;还望指出 目录 正文 基础概念 视觉暂留 逐行扫描 帧 CPU/GPU/Surface&#xff1a; 帧率、刷新率、画面撕裂 画面撕裂 Android屏幕刷新机制的演变 单缓存&#xff08;And…...

Landsat8中*_MTL.txt文件详解

01 什么是*_MTL.txt文件&#xff1f;所有的Landsat8 1级数据产品中均包含MTL.txt(Metadata File)文件。Landsat MTL文件包含对数据的系统搜索和归档分类有益的信息。该文件还包含关于数据处理和恶对增强陆地卫星数据有重要价值的信息&#xff08;例如转换为反射率和辐射亮度&am…...

好的提高代码质量的方法有哪些?有什么经验和技巧?

用于确保代码质量的6个高层策略&#xff1a; 1 编写易于理解的代码 考虑如下这段文本。我们有意地使其变得难以理解&#xff0c;因此&#xff0c;不要浪费太多时间去解读。粗略地读一遍&#xff0c;尽可能吸收其中的内容。 〓ts〓取一个碗&#xff0c;我们现在称之为A。取一…...

yum保留安装包

一. 用downloadonly下载 1.1 处理依赖关系自动下载到/tmp/pages目录&#xff0c;pages这个目录会自动创建 yum install --downloadonly --downloaddir/tmp/pages ceph-deploy注意&#xff0c;如果下载的包包含了任何没有满足的依赖关系&#xff0c;yum将会把所有的依赖关系包下…...

ERP系统哪家比较好?

ERP系统哪家好&#xff1f;在选择ERP系统时&#xff0c;我们可以按照这三个维度&#xff0c;然后再按照需求去选择ERP系统。 市面上ERP软件大概可以分为三大类&#xff1a; ① 标准ERP应用&#xff1a;功能比较固定&#xff0c;难以满足个性化需求&#xff0c;二次开发难度很高…...

Python读写mdb文件的实战代码

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...

MAC和IP地址在字符串形式、数字形式和byte数组中的转换

MAC地址 mac地址作为网卡的物理地址,有6个byte的长度。在实际表示形式上,以每个字节的16进制,中间用冒号隔开,比如:“01:02:03:04:05:06”。这就是mac地址的字符串形式 而在网络通信传输中,需要对mac地址从字符串形式转换为数字形式或byte数组形式发送。并且网络上传输…...

时间轮来优化定时器

在raft协议中&#xff0c; 会初始化三个计时器是和选举有关的&#xff1a; voteTimer&#xff1a;这个timer负责定期的检查&#xff0c;如果当前的state的状态是候选者&#xff08;STATE_CANDIDATE&#xff09;&#xff0c;那么就会发起选举 electionTimer&#xff1a;在一定时…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...