聊天服务器分布式改造
目前的聊天室是单节点的,无论是http接口还是socket接口都在同一个进程,无法承受太多人同时在线,容灾性也非常差。因此,一个成熟的IM产品一定是做成分布式的,根据功能分模块,每个模块也使用多个节点并行部署。
1.技术选型
Spring Cloud Alibaba 和 Netflix 都是用于构建分布式系统的工具集,它们在微服务架构中发挥着重要作用,但在多个方面存在差异:
发展与维护
- Netflix:部分核心组件(如 Eureka、Hystrix)停止更新维护,企业使用有后续风险。
- Spring Cloud Alibaba:由阿里巴巴开源并持续投入开发,社区活跃,不断迭代优化,能及时修复问题、添加新功能。
核心组件功能
- Netflix 服务注册与发现(Eureka),负载均衡(Ribbon),熔断与限流(Hystrix),都已经停更。
- Spring Cloud Alibaba的各种组件处于活跃的开发和维护状态,不断推出新的功能和优化。
生态系统
- Netflix:早期生态完整,但因组件停更发展受限。
- Spring Cloud Alibaba:深度集成 Spring Cloud,与阿里巴巴其他开源项目配合好,社区文档和示例丰富,生态发展好。
综上,我们选择Spring Cloud Alibaba(2021.x 版本)。
2.主要服务组件
| 组件 | 功能 |
| Nacos | 服务注册与发现组件,配置中心 |
spring-cloud-starter-gateway | 通信网关 |
| Spring Cloud Alibaba LoadBalancer | 客户端负载均衡器 |
spring-security-oauth2 | 集中授权中心 |
2.1.Nacos服务发现与配置管理
Nacos 是 Spring Cloud Alibaba 中核心的服务注册与发现组件,同时也具备配置管理功能。除了Nacos,还有Eureka,Consul,ZooKeeper等有类似功能,但Nacos同时在这两个方面表现优异,还有一个可视化管理后台,作为首选产品。

2.2.spring-security-oauth2授权中心
spring-security-oauth2作为一个集中授权中心,无论是客户端请求,还是微服务内部的请求,都需要先到它这里进行认证,结合jwt算法,可以生成一个无需服务器管理的token。
Spring Security OAuth2 实现了 OAuth 2.0 协议中的四种授权方式,分别是授权码模式(Authorization Code)、简化模式(Implicit)、密码模式(Resource Owner Password Credentials)和客户端模式(Client Credentials)。下面为你详细介绍这四种授权方式:
授权码模式(Authorization Code)
授权码模式是 OAuth 2.0 中最安全、最常用的授权方式。它适用于有服务器端的应用,通过客户端引导用户到授权服务器进行登录授权,获取授权码,再用授权码换取访问令牌。
简化模式(Implicit)
简化模式是一种简化的授权方式,适用于没有服务器端的客户端应用(如单页应用)。它省略了授权码的步骤,直接在浏览器中获取访问令牌。
密码模式(Resource Owner Password Credentials)
密码模式是一种简单直接的授权方式,适用于受信任的客户端应用。用户直接将自己的用户名和密码提供给客户端,客户端使用这些信息向授权服务器换取访问令牌。
客户端模式(Client Credentials)
客户端模式是一种用于客户端应用自身获取访问令牌的授权方式,不涉及用户的身份信息。适用于客户端应用需要以自己的身份访问资源服务器的场景。
在微服务内部授权上,本文使用客户端模式。当微服务之间以服务自身的身份进行交互,且不需要区分用户身份时,客户端模式是一个简单、安全、高效的授权方式。可以使用 OAuth 2.0 协议的客户端模式来管理服务之间的访问权限。
在客户端登录验证上,本文使用密码模式,结合jwt算法,实现无状态的授权。
3.模块划分
对于一个聊天软件,按照功能进行划分,先简单划分为用户,web,socket模块。后面根据需要再进行细化。
主要目标,除了聊天这种实时性要求,以及客户端推送这种需要服务器主动发送消息以外,其他逻辑尽可能走http,实现负载均衡。 架构图如下:

客户端统一访问gateway网关,通过账号密码向授权中心认证通过后,得到一个token,后续所有http请求都需要带上此header。http登录成功之后,服务器还会根据负载均衡策略选择一个socket节点,作为客户端聊天的主要通信网关,用户在这次登录的生命周期只会绑定该节点,而其他http请求则会被分散到不同模板的不同节点。
4.第三方中间件
| 中间件 | 作用 |
| mysql | 用户,讨论群,消息等数据的持久化方案 |
| minio | 头像,多媒体消息的文件存储系统 |
| redis | 用户数据快速缓存 |
| nacos | 服务注册发现,配置管理 |
由于使用的中间件比较多,本文使用docker-compose进行集中化配置,配置如下:
version: '3.3'services:db:image: mysql:latestcontainer_name: im-mysqlenvironment:MYSQL_PASSWORD: '123456'MYSQL_ROOT_PASSWORD: '123456'ports:- "3306:3306"volumes:- ./data/mysql/data:/var/lib/mysqlrestart: alwaysnetworks:- im-networknacos:image: nacos/nacos-server:v2.3.1container_name: im-nacosenvironment:- PREFER_HOST_MODE=hostname- MODE=standalone- NACOS_AUTH_IDENTITY_KEY=serverIdentity- NACOS_AUTH_IDENTITY_VALUE=security- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789ports:- "8848:8848"- "9848:9848"networks:- im-network minio:image: minio/minio:latestcontainer_name: im-s3ports:- "9000:9000"- "9001:9001"environment:MINIO_ROOT_USER: minioadminMINIO_ROOT_PASSWORD: minioadmincommand: server --console-address ":9001" /data volumes:- ./data/minio:/datarestart: alwaysnetworks:- im-networkredis:image: redis:latestcontainer_name: im-redisports:- "6379:6379"volumes:- ./data/redis:/datarestart: alwaysnetworks:- im-network
networks:im-network:driver: bridge
全部代码已在github上托管
服务端代码请移步 --> 聊天室服务器
客户端代码请移步 --> 聊天室客户端
相关文章:
聊天服务器分布式改造
目前的聊天室是单节点的,无论是http接口还是socket接口都在同一个进程,无法承受太多人同时在线,容灾性也非常差。因此,一个成熟的IM产品一定是做成分布式的,根据功能分模块,每个模块也使用多个节点并行部署…...
el-table(elementui)表格合计行使用以及滚动条默认样式修改
一、el-table新增合计行以及el-table展示数据出现的问题 1. 使用合计行 el-table的属性show-summary设为true,即可在表格尾部展示合计行。默认情况下,第一列不展示数据,而显示合计二字,可以通过sum-text自己配置,其余…...
Web前端开发——HTML基础下
HTML语法 一表格1.基本格式2.美化表格合并居中属性 二表单1.input2.select3.textarea4.button5.date6.color7.checkbox8.radio9.range10.number 一表格 1.基本格式 HTML表格由<table>标签定义 其中行由<tr>标签定义,单元格由<td>定义。我们先来…...
Python使用入门(一)
初识数据类型 整型(int) print(666) print(2 10) print(2 * 12)字符串(str) 单行字符串 #单行字符串 print("我是小红aaa") print(我是小红aaa)print("中国上海") print(中国上海)# 输出带引号的字符串 print(我是"小红aaa) print("我是\&qu…...
基于multisim的花样彩灯循环控制电路设计与仿真
1 课程设计的任务与要求 (一)、设计内容: 设计一个8路移存型彩灯控制器,基本要求: 1. 8路彩灯能演示至少三种花型(花型自拟); 2. 彩灯用发光二极管LED模拟; 3. 选做…...
求最大公约数【C/C++】
大家好啊,欢迎来到本博客( •̀ ω •́ )✧,我将带领大家详细的了解最大公约数的思想与解法。 一、什么是公约数 公约数,也称为公因数,是指两个或多个整数共有的因数。具体来说,如果一个整数能被两个或多个整数整除&…...
leetcode day27 455+376
455 分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有…...
go的grpc
GRPC介绍 目录 单体架构微服务架构问题原始的grpc 服务端客户端原生rpc的问题 grpc的hello world 服务端客户端 proto文件proto语法 数据类型 基本数据类型其他数据类型 编写风格多服务 单体架构 只能对整体扩容一荣俱荣,一损俱损代码耦合,项目的开…...
算法每日一练 (9)
💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 算法每日一练 (9)最小路径和题目描述解题思路解题代码…...
软考高级信息系统项目管理师笔记-第10章项目进度管理
第10章项目进度管理 10.1 管理基础 10.1.1 项目进度计划的定义和总要求 1、项目进度计划是 一种用于沟通和管理干系人期望的工具,为绩效报告提供依据。 2、项目管理团队编制进度计划的一般步骤为: 首先选择进度计划方法,例如关键路径法; 然后将项目特定数据,如活动、计…...
专门为高速连续扫描设计的TDI工业相机
TDI(Time Delay Integration,时间延迟积分)工业相机是一种基于特殊CCD(电荷耦合器件)技术的成像设备,主要用于高速、高灵敏度、高分辨率的图像采集场景。其核心原理是通过多级积分和同步电荷转移技术&#…...
【Vue3】实现一个超过高度后可控制显示隐藏的组件
组件效果图 未达到最大高度 达到设置的最大高度 进行展开 实现代码 组件代码 备注:通过tailwindcss设置的样式,通过element-plus/icons-vue设置的图标,可根据情况进行替换 <template><!-- 限制高度组件 --><div ref"…...
Spring提供的SPEL表达式
SPEL 1. 概述 SpEL是Spring框架中用于表达式语言的一种方式。它类似于其他编程语言中的表达式语言,用于在运行时计算值或执行特定任务。 SpEL提供了一种简单且强大的方式来访问和操作对象的属性、调用对象的方法,以及实现运算、条件判断等操作。它可以…...
JAVA编程【jvm垃圾回收的差异】
jvm垃圾回收的差异 JVM(Java Virtual Machine)的垃圾回收(GC)机制是自动管理内存的一种方式,能够帮助开发者释放不再使用的内存,避免内存泄漏和溢出等问题。不同的垃圾回收器(GC)有…...
Elasticsearch:“Your trial license is expired”
目录标题 问题原因解决方案 问题 原因 ES的X-pack许可证是提供免费一个月的试用,到期之后就会报这个错误。 解决方案 查看license GET _license 开启试用license POST _xpack/license/start_trial?acknowledgetrue修改为基础license POST _xpack/license/start_…...
fmql之Linux WDT
正点原子第52章。 基础知识 正点原子教程 fmql-dts 代码 APP代码(不需要编写驱动代码) static int dw_wdt_drv_probe(struct platform_device *pdev) {struct device *dev &pdev->dev;struct watchdog_device *wdd;struct dw_wdt *dw_wdt; …...
【算法学习之路】7.链表算法
链表算法 前言一.原地逆置思路一:头插法思路二:双指针法思路3:递归 例题:1.头插法2.双指针法3,递归 二.双指针快慢指针:一个指针快一个指针慢例题1例题2 前言 我会将一些常用的算法以及对应的题单给写完&am…...
IDEA Commit 模态提交界面关闭VS开启对比
IDEA Commit 模态提交界面关闭VS开启对比 前言开启模态提交界面优点快捷且灵活的选择需要commit文件显示文件修改内容多(主观) 缺点在模态提交界面选择文件,临时关闭模态框重新打开会重置选择的commit文件 关闭模态提交界面优点允许在commit选择文件时查看其它没有修…...
【AI赋能】AI 工具生成视频教材:从创意到成品的全流程指南
AI 工具生成视频教材:从创意到成品的全流程指南 目标 通过本教材,您将学会如何利用 AI 工具(Grok、Sora、Speechify 和 CapCut)生成一个完整的视频,包括脚本生成、视频片段制作、字幕添加、音频生成以及最终剪辑合成…...
qt 操作多个sqlite文件
qt 操作多个sqlite文件 Chapter1 qt 操作多个sqlite文件1. 引入必要的头文件2. 创建并连接多个SQLite数据库3. 代码说明4. 注意事项 Chapter2 qt 多线程操作sqlite多文件1. 引入必要的头文件2. 创建数据库操作的工作线程类3. 在主线程中创建并启动多个工作线程4. 代码说明5. 运…...
别再搞混了!AUTOSAR通信栈里,PduR和CanTp到底为谁打工?一个DCM诊断请求的完整旅程
AUTOSAR通信栈揭秘:诊断请求如何穿越PduR与CanTp的迷宫 在汽车电子系统的开发中,诊断通信就像车辆的"健康检查系统",而AUTOSAR架构中的通信栈则是确保这些诊断命令能够准确传达的神经网络。许多工程师第一次接触AUTOSAR通信栈时&am…...
为什么你的Pyd文件在Windows上总报“DLL加载失败”?系统级依赖扫描、Manifest嵌入与UCRT版本对齐终极方案
第一章:Pyd文件在Windows上的本质与加载机制Pyd 文件是 Windows 平台上 Python 的 C 扩展模块的二进制格式,其本质是遵循特定 ABI 约束的动态链接库(DLL),但被 Python 解释器以特殊方式识别和加载。它并非普通 DLL&…...
RTX4090D显存优化:OpenClaw长文本处理实测Qwen3-32B性能
RTX4090D显存优化:OpenClaw长文本处理实测Qwen3-32B性能 1. 测试背景与实验设计 去年我在处理学术论文时,经常遇到需要分析几十页PDF的情况。传统工具要么截断文本,要么丢失关键上下文。当我发现OpenClaw支持本地部署大模型后,立…...
开发效率翻倍:用快马智能推荐最佳排序算法,告别性能焦虑
今天想和大家分享一个提升开发效率的实用技巧——如何快速找到最适合当前场景的排序算法。作为开发者,我们经常需要处理各种排序需求,但面对不同规模、不同特征的数据集时,如何选择最优算法往往让人头疼。 数据准备阶段 在实际项目中…...
告别标注烦恼:用DINOv2自监督模型,在Intel Image数据集上3个epoch实现93%准确率
零标注成本实战:DINOv2自监督模型在Intel Image数据集上的高效迁移方案 当我在实验室第一次尝试用传统方法训练一个图像分类模型时,面对数千张需要手动标注的图片,几乎要放弃这个课题。直到发现了自监督学习这个宝藏领域——特别是DINOv2这样…...
Django REST framework的应用场景
目录一、鉴权开发框架介绍二、Django REST framework是什么三、如何实现认证、权限与限流功能四、Django REST framework的应用场景一、鉴权开发框架介绍 鉴权开发框架是一种用于实现身份验证和授权的软件开发工具。它可以帮助开发者快速构建安全、可靠的身份验证和授权系统&a…...
Google与Cohere发布新一代音频AI模型
Google LLC和Cohere Inc.今日发布了专为音频处理任务优化的新人工智能模型。这家搜索巨头的算法Gemini 3.1 Flash Live能够自动化客户服务交互。Cohere的新AI模型则专为语音转录而设计。两款模型的输出质量都比其前代产品有显著提升。企业可使用Gemini 3.1 Flash Live构建语音智…...
老牌CMS的隐痛:从DedeCMS漏洞看开源系统会员模块的安全设计误区
DedeCMS会员模块漏洞剖析:开源系统安全设计的深层反思 当一款拥有百万级安装量的老牌CMS系统曝出前台任意密码修改漏洞时,我们看到的不仅是一个具体的技术缺陷,更是开源项目在安全架构设计上的系统性隐忧。2018年那场影响广泛的DedeCMS漏洞事…...
避坑指南:Pyannote3.1+Whisper本地部署的5个常见报错解决方案
避坑指南:Pyannote3.1Whisper本地部署的5个常见报错解决方案 语音处理技术正在重塑教育、会议记录和客服质检等场景的交互方式。当开发者尝试将Whisper的精准语音识别与Pyannote的说话人分离能力结合时,常会在环境配置环节遭遇"拦路虎"。本文…...
能源监控项目避坑指南:为什么DLT645电表直连Modbus系统会失败?
能源监控项目避坑指南:为什么DLT645电表直连Modbus系统会失败? 在智慧能源项目的实施过程中,数据采集的可靠性直接关系到整个系统的运行效果。许多项目团队在遇到DLT645规约电表与Modbus系统对接时,往往会尝试直接连接,…...
