当前位置: 首页 > 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;在一定时…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

路由基础-路由表

本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中&#xff0c;往往存在多个不同的IP网段&#xff0c;数据在不同的IP网段之间交互是需要借助三层设备的&#xff0c;这些设备具备路由能力&#xff0c;能够实现数据的跨网段转发。 路由是数据通信网络中最基…...

SpringCloud优势

目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...

学习 Hooks【Plan - June - Week 2】

一、React API React 提供了丰富的核心 API&#xff0c;用于创建组件、管理状态、处理副作用、优化性能等。本文档总结 React 常用的 API 方法和组件。 1. React 核心 API React.createElement(type, props, …children) 用于创建 React 元素&#xff0c;JSX 会被编译成该函数…...

PostgreSQL 对 IPv6 的支持情况

PostgreSQL 对 IPv6 的支持情况 PostgreSQL 全面支持 IPv6 网络协议&#xff0c;包括连接、存储和操作 IPv6 地址。以下是详细说明&#xff1a; 一、网络连接支持 1. 监听 IPv6 连接 在 postgresql.conf 中配置&#xff1a; listen_addresses 0.0.0.0,:: # 监听所有IPv4…...