WebSocket在分布式环境中的局限性及解决方案
WebSocket 在分布式环境中存在一些局限性,特别是当系统需要扩展多个服务实例时,单个 WebSocket 连接的管理和消息推送就变得比较复杂。因此,必须采取一些额外的措施来确保 WebSocket 能在多个服务实例之间正确工作。
WebSocket 在分布式环境中的局限性
-
单实例限制:传统的 WebSocket 连接是基于单一实例的,如果我们的应用扩展了多个实例,每个实例只能管理它自己建立的 WebSocket 连接,导致消息无法从一个实例推送到另一个实例的连接中。
-
消息同步问题:当多个实例都需要处理来自 Kafka 或其他消息队列的事件时,如果不采取措施,消息可能无法同步推送到所有 WebSocket 连接。比如,如果某个服务实例处理了 Kafka 消息,可能无法将消息推送到所有其他实例的 WebSocket 连接。
示例:在线聊天应用
假设我们正在开发一个 在线聊天应用,该应用有多个用户(客户端)同时在线,每个用户通过 WebSocket 与聊天服务器进行连接,实时接收和发送消息。
场景描述:
- 用户 A 和 用户 B 都使用浏览器登录这个聊天应用。
- 服务器 会管理每个用户与浏览器之间的 WebSocket 连接,并保持这些连接持续开放,实时推送消息。
- 由于 服务器 可能分布在多个 实例 上(例如 服务器实例 1 和 服务器实例 2),因此,每个服务器实例只会管理与其连接的 用户。
设定:
- 服务器实例 1 管理了 用户 A 的 WebSocket 连接。
- 服务器实例 2 管理了 用户 B 的 WebSocket 连接。
发生的情况:
1. 用户 A 向用户 B 发送消息:
- 用户 A 在聊天框中输入消息并点击发送。
- 服务器实例 1 接收到 用户 A 的消息。
- 服务器实例 1 将消息推送到 用户 B,但它并不知道 用户 B 连接在 服务器实例 2 上,因此,它不能直接将消息推送给 用户 B。
2. 问题:
- 服务器实例 1 无法直接推送消息给 服务器实例 2 上的 用户 B,因为 WebSocket 是一个点对点的连接协议,每个服务器实例只能与它自己管理的 WebSocket 连接进行通信。
- 用户 A 的消息只能通过 服务器实例 1 发送给 用户 A,而不能跨实例推送给 用户 B。
解决方案:使用消息队列(如 Redis)
为了解决这个问题,我们可以使用 消息队列(例如 Redis)来 同步跨实例的消息。
- 服务器实例 1 将 用户 A 的消息发布到 Redis 的一个 频道,比如频道名为
chat-channel
。 - 服务器实例 2 订阅了
chat-channel
这个频道,当 服务器实例 1 发布消息时,服务器实例 2 会收到消息。 - 服务器实例 2 收到消息后,推送该消息给它管理的 用户 B。
简化的流程:
- 用户 A 向 用户 B 发送消息 -> 服务器实例 1 处理。
- 服务器实例 1 将消息发布到 Redis 的
chat-channel
。 - 服务器实例 2 订阅
chat-channel
,接收到消息。 - 服务器实例 2 将消息推送给 用户 B。
总结
- 在 WebSocket 的传统实现中,每个 服务器实例 管理自己的 WebSocket 连接,不能直接跨实例推送消息。
- 通过 Redis 或 Kafka 等消息队列,服务器实例 可以将消息发布到共享频道,其他实例可以订阅并接收到该消息。
- 通过这种方式,即使 用户 A 在 服务器实例 1,而 用户 B 在 服务器实例 2,也能确保消息能够实时推送到 用户 B。
解决方案:使用 消息中间件 与 分布式 WebSocket 管理
为了解决 WebSocket 在分布式环境中的问题,我们可以使用 消息中间件(如 Kafka、RabbitMQ、Redis 等)来同步消息,并结合 分布式 WebSocket 管理 来保证每个 WebSocket 客户端能够接收到消息。
1. 使用 Redis 作为消息代理
- Redis 是一个支持 发布/订阅(Pub/Sub)机制的高效内存数据存储服务,适用于多实例之间的消息同步。
- 我们可以利用 Redis 的 发布/订阅 模式来广播 WebSocket 消息,将消息推送到所有连接的 WebSocket 客户端。
- 在每个 WebSocket 实例中,客户端连接后都会订阅 Redis 中的某个频道,当消息发布到该频道时,Redis 会将消息转发给所有订阅了该频道的实例,从而实现多实例间的 WebSocket 消息推送。
2. 方案设计
- Kafka 消费者:在后台,Kafka 消费者服务从消息队列中消费到的事件(如工单拒绝事件)会通过 Redis 发布 消息。
- WebSocket 服务:每个 WebSocket 服务实例会订阅 Redis 中的特定频道,当 Kafka 消费者发布消息时,Redis 会将消息广播给所有订阅了该频道的 WebSocket 实例,从而向所有客户端推送消息。
3. 总结
- WebSocket 连接:每个 WebSocket 服务实例会订阅 Redis 中的消息频道,确保多个服务实例能够接收到相同的推送消息。
- Kafka 消费者:从 Kafka 消费事件后,发布到 Redis 消息频道,确保消息的同步。
- Redis Pub/Sub:Redis 的发布/订阅机制实现了跨服务实例的消息同步,解决了多实例间 WebSocket 消息推送的挑战。
4. 优点
- 高可扩展性:利用 Redis 或其他消息中间件,能够在多个服务实例之间同步消息,解决了 WebSocket 在分布式环境中的限制。
- 解耦:消息推送和 WebSocket 连接的管理解耦,减少了直接依赖,提高了系统的灵活性和维护性。
- 实时推送:WebSocket 与 Redis 集成可以实现实时的消息推送,确保管理员能够即时收到任务拒绝或其他工单相关的通知。
这样,使用 Redis 和 WebSocket 的组合解决方案能够有效克服 WebSocket 在分布式环境中的局限性,并提供一个高效、可扩展的消息推送机制。
相关文章:
WebSocket在分布式环境中的局限性及解决方案
WebSocket 在分布式环境中存在一些局限性,特别是当系统需要扩展多个服务实例时,单个 WebSocket 连接的管理和消息推送就变得比较复杂。因此,必须采取一些额外的措施来确保 WebSocket 能在多个服务实例之间正确工作。 WebSocket 在分布式环境…...
SIM盾构建安全底座的可行性分析
一、背景 1.1安全需求现状 在数字化时代,信息安全面临着日益严峻的挑战。各类网络攻击手段层出不穷,如数据泄露、恶意软件攻击、网络诈骗等,给个人、企业和社会带来了巨大的损失。为了保障信息系统的安全性,需要构建一个可靠的安…...

【Java八股文】10-数据结构与算法面试篇
【Java八股文】10-数据结构与算法面试篇 数据结构与算法面试题数据结构红黑树说一下跳表说一下?LRU是什么?如何实现?布隆过滤器怎么设计?时间复杂度? 排序算法排序算法及空间复杂度 数据结构与算法面试题 数据结构 红…...

go 并发 gorouting chan channel select Mutex sync.One
goroutine // head: 前缀 index:是一个int的指针 func print(head string, index *int) {for i : 0; i < 5; i {// 指针对应的int *indexfmt.Println(*index, head, i)// 暂停1stime.Sleep(1 * time.Second)} }/* Go 允许使用 go 语句开启一个新的运…...

亲测Windows部署Ollama+WebUI可视化
一. Ollama下载 登录Ollama官网(Ollama)点击Download进行下载 如果下载很慢可用以下地址下载: https://github.com/ollama/ollama/releases/download/v0.5.7/OllamaSetup.exe 在DeepSeek官网上,你可以直接点击【model】 到达这个界面之后,…...

linux 安装启动zookeeper全过程及遇到的坑
1、下载安装zookeeper 参考文章:https://blog.csdn.net/weixin_48887095/article/details/132397448 2、启动失败 1、启动失败JAVA_HOME is not set and java could not be found in PATH 已安装 JAVA 配置了JAVA_HOME,还是报错解决方法:参考…...
策略模式Spring框架下开发实例
策略类Spring框架下开发实例 先列出策略模式下需要那些类: 策略接口 (Strategy),定义所有策略类必须遵循的行为。 具体策略类(如 ConcreteStrategyA、ConcreteStrategyB),实现不同的算法或行为。 上下文类 (Context),…...
DeepSeek模型量化
技术背景 大语言模型(Large Language Model,LLM),可以通过量化(Quantization)操作来节约内存/显存的使用,并且降低了通讯开销,进而达到加速模型推理的效果。常见的就是把Float16的浮…...
【练习】【回溯:组合:不同集合】力扣 17. 电话号码的字母组合
题目 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits “2…...

分布式文件系统HDFS
一、HDFS简介 HDFS( Hadoop Distributed File System ),意为:Hadoop分布式文件系统。是Apache Hadoop核心组件之一,作为大数据生态圈最底层的分布式存储服务而存在。分布式文件系统解决大数据如何存储问题。分布式意味…...

从WebRTC到EasyRTC:嵌入式适配的视频通话SDK实现低延迟、高稳定性音视频通信
WebRTC最初是为浏览器之间的实时通信设计的,其资源需求和复杂性可能对嵌入式设备的性能提出较高要求,因此在嵌入式系统中应用时面临一些挑战: 1)资源消耗较高 CPU和内存占用:WebRTC是一个功能强大的实时通信框架&…...

WordPress自定义排序插件:Simple Custom Post Order完全指南(SEO优化版)
在WordPress建站中,文章、分类目录或页面的默认排序方式往往无法满足个性化需求。WordPress自定义排序插件:Simple Custom Post Order插件,你可以轻松实现拖拽式自定义排序,无需修改代码即可优化内容展示逻辑。本文将详细介绍这款…...
docker安装ros2 并在windows中显示docker内ubuntu系统窗口并且vscode编程
这里包括docker desktop安装ros2 humble hawkshill , 安装xserver(用来在windows中显示ubuntu中窗口), vscode安装插件连接docker并配置python的一系列方法 1.安装xserver 为了能方便的在windows中显示ubuntu内的窗口,比如rqt窗口 参考文章:https://www.cnblogs.com/larva-zhh…...
【QT中的一些高级数据结构,持续更新中...】
QT中有一些很精妙、便捷的设计,在了解这些数据的同时,我们可以学到如何更好的设计代码。本贴持续更新中,欢迎关注和收藏 一 QScopedPointer主要特点:示例代码 二 Q_DISABLE_COPY 一 QScopedPointer QScopedPointer 是 Qt 中的一种…...
简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用
简单工厂模式(Simple Factory Pattern)虽然不属于 GoF 23 种经典设计模式,但在实际开发中非常常用,尤其是在 Spring Boot 项目中。它提供了一种简单的方式来创建对象,将对象的创建逻辑集中到一个工厂类中。 一、简单工…...

《95015网络安全应急响应分析报告(2024)》
2025年2月,95015服务平台发布了最新一期的《95015网络安全应急响应分析报告(2024)》。报告分别从整体形势、受害者特征、攻击者特征等方面,对2024年95015平台接报的739起网络安全应急响应事件展开分析,并给出了7个年度…...
TensorFlow v2.16 Overview
TensorFlow v2.16 Overview 一、模块 Modules二、类 Classes三、函数 Functions TensorFlow v2.16.1 Overview 一、模块 Modules 模块是TensorFlow中组织代码的一种方式,将相关的功能和类封装在一起,方便用户使用和管理。每个模块都提供了特定领域的公共…...
Udp发送和接收数据(python和QT)
服务端代码 (python) import socketdef udp_server(host0.0.0.0, port12345):# 创建一个UDP套接字sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 绑定服务器的IP地址和端口号sock.bind((host, port))print(f"UDP服务器已启动,监听端口 {port}...&…...
element-plus 根据条件显示多选框
代码如下: <el-table :data"pager.lists" selection-change"handleSelectionChange" row-key"id" :tree-props"{ checkStrictly: true }" :cell-class-name"cellClass"> <el-table-column type"s…...

Ubuntu 22.04 Install deepseek
前言 deepseekAI助手。它具有聊天机器人功能,可以与用户进行自然语言交互,回答问题、提供建议和帮助解决问题。DeepSeek 的特点包括: 强大的语言理解能力:能够理解和生成自然语言,与用户进行流畅的对话。多领域知识&…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...