WebSocket集群方案解析与实现

一、WebSocket集群核心挑战

1.1 关键问题分析

会话保持
多节点同步
消息路由
精准投递
水平扩展
负载均衡

1.2 方案对比矩阵

方案类型实现复杂度网络开销可靠性适用场景
广播方案小规模集群
目标询址中大规模系统
共享存储高一致性要求

二、广播方案深度实现

2.1 服务端核心逻辑

@ServerEndpoint("/websocket/{businessType}/{userId}")
@Component
public class BroadcastWebSocket {private static final Map<String, Session> LOCAL_SESSIONS = new ConcurrentHashMap<>();@OnOpenpublic void onOpen(@PathParam("userId") String userId, Session session) {LOCAL_SESSIONS.put(userId, session);// 可添加Redis订阅逻辑}@MessageMapping("/topic/notify")@SendToUser("/queue/notice")public void handleBroadcast(Message message) {// 消息处理逻辑}
}

2.2 消息消费者实现

@Component
@RequiredArgsConstructor
public class OrderMessageConsumer {private final SimpMessagingTemplate messagingTemplate;@RabbitListener(queues = "order.queue")public void handleOrderMessage(OrderMessage message) {messagingTemplate.convertAndSendToUser(message.getUserId(),"/queue/orders",message.getContent());}
}

三、目标询址方案完整实现

3.1 服务注册与发现

@Configuration
public class ServiceRegistryConfig {@Bean@ConditionalOnMissingBeanpublic ServiceInstance serviceInstance(@Value("${server.port}") int port,@Value("${spring.application.name}") String appName) {return new DefaultServiceInstance(appName + "-" + IdUtil.simpleUUID(),appName,getLocalHost(),port,false);}private String getLocalHost() {try {return InetAddress.getLocalHost().getHostAddress();} catch (UnknownHostException e) {return "127.0.0.1";}}
}

3.2 路由服务实现

@Service
public class RoutingService {private final DiscoveryClient discoveryClient;private final RedisTemplate<String, String> redisTemplate;public String getTargetService(String userId) {String serviceName = redisTemplate.opsForHash().get("ws:mapping", userId);return discoveryClient.getInstances(serviceName).stream().findFirst().map(instance -> instance.getUri().toString()).orElseThrow();}
}

3.3 Feign客户端配置

@FeignClient(name = "ws-client", configuration = FeignConfig.class)
public interface WsClient {@PostMapping("/push/{userId}")void pushMessage(@PathVariable String userId,@RequestBody PushMessage message);class FeignConfig {@Beanpublic RequestInterceptor routingInterceptor(RoutingService routingService) {return template -> {String userId = template.pathVariables().get("userId");String baseUrl = routingService.getTargetService(userId);template.target(baseUrl);};}}
}

四、生产环境优化策略

4.1 会话健康检查

@Scheduled(fixedRate = 30000)
public void checkAliveSessions() {LOCAL_SESSIONS.forEach((userId, session) -> {try {session.getAsyncRemote().sendPing(ByteBuffer.wrap("HB".getBytes()));} catch (Exception e) {LOCAL_SESSIONS.remove(userId);redisTemplate.opsForHash().delete("ws:mapping", userId);}});
}

4.2 负载均衡策略

spring:cloud:loadbalancer:configurations: zone-preferencenacos:discovery:cluster-name: ${ZONE:default}

五、异常处理与容灾

5.1 回退机制实现

@Slf4j
public class WsClientFallback implements WsClient {private final MessageStore messageStore;@Overridepublic void pushMessage(String userId, PushMessage message) {messageStore.saveUndelivered(userId, message);log.warn("消息暂存,等待重试: {}", message);}
}

5.2 消息重试队列

@Bean
public MessageRecoveryRecovery recoveryStrategy() {return new ExponentialBackOffRecovery() {@Overridepublic void recover(Message message) {// 自定义重试逻辑}};
}

六、性能监控方案

6.1 监控指标采集

@Bean
public MeterBinder wsMetrics(WebSocketSessionRegistry registry) {return registry -> {Gauge.builder("websocket.sessions",() -> registry.getSessionCount()).register(registry);};
}

6.2 Grafana监控面板

{"panels": [{"title": "WebSocket Sessions","targets": [{"expr": "sum(websocket_sessions_active)","legendFormat": "Active Sessions"}]}]
}

七、方案选型决策指南

在这里插入图片描述

总结与建议

  1. 中小型项目:优先采用广播方案,配合Redis Pub/Sub实现简单集群
  2. 中大型系统:采用目标询址方案,确保消息精准投递
  3. 关键业务:实现双保险机制,结合两种方案优势
  4. 性能优化:重点监控会话数量和消息延迟指标
  5. 容灾设计:必须实现消息持久化和重试机制

示例项目结构建议:

websocket-cluster/
├── ws-common       # 公共组件
├── ws-gateway      # 接入层
├── ws-node1        # 节点1
├── ws-node2        # 节点2
└── ws-monitor      # 监控服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93016.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用dify搭建hr简历助手-上传简历-对接飞书ai表格

一、需求背景 hr在招聘平台获取简历后&#xff0c;想整理到简历库&#xff0c;在线管理和维护&#xff0c;及其不方便&#xff0c;所以用dify搭建一个简历上传助手&#xff0c;并且能保存到线上表格&#xff0c;方便维护和查看。 先看下最终的效果我们的工作流即可自动获取文件…

《算法导论》第 22 章 - 基本的图算法

大家好&#xff01;今天我们来深入学习《算法导论》第 22 章的基本图算法。图论是计算机科学中的重要基础&#xff0c;这些基本算法是解决很多复杂问题的基石。本文将结合代码实现&#xff0c;帮助大家更好地理解和应用这些算法。思维导图22.1 图的表示在计算机中&#xff0c;图…

基于PROFINET的西门子PLC通讯:S7-200与S7-1200在自动化仓储中的协同应用

一.行业痛点与解决方案传统仓储物流系统中&#xff0c;采用西门子SMARTS7-200PLC&#xff08;如CPUSR20、SR30等型号&#xff09;的设备往往面临三大通讯难题&#xff1a;一是无法直接接入以太网网络&#xff0c;导致多PLC间的数据交互需要通过复杂的串口级联实现&#xff0c;响…

redis实现秒杀超卖问题的解决方案:(仅限于单体项目)

秒杀实现通过乐观锁控制超卖问题通过悲观锁控制每个用户只能下一单&#xff0c;避免用户多次点击&#xff0c;发送的多次下单请求(即多个线程)都成功&#xff0c;避免恶意攻击每个请求访问Tomcat时&#xff0c;就会分配一个线程处理请求业务逻辑&#xff1a;注*以下逻辑中报错也…

Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析

目录 引言&#xff1a;两种语言&#xff0c;两种哲学 开发效率对比&#xff1a;从框架设计看易用性 Python的"开箱即用" Go的"手动组装" 性能对比&#xff1a;从并发模型看效率差异 理论性能对比 实际测试数据 错误处理对比&#xff1a;从编程范式…

初识c语言————排序方法

今天我们学习的是c语言中的排序方法目录&#xff1a;一.冒泡排序法二.选择排序法下面我们正式学习c语言中的排序方法一.冒泡排序法1.冒泡排序法的过程&#xff1a;将无序的数组通过数组之间的大小比较&#xff0c;排成有序的样子2.例如&#xff1a;5&#xff0c;3&#xff0c;4…

爬虫与数据分析结合案例:中国大学排名爬取与分析全流程

爬虫与数据分析结合案例&#xff1a;中国大学排名爬取与分析全流程 一、案例背景与目标 本案例以高三网中国大学排名&#xff08;网址&#xff1a;2021中国的大学排名一览表_高三网&#xff09;为数据源&#xff0c;完成从数据爬取到分析可视化的全流程实践。主要目标包括&am…

行业分享丨SimSolid 在汽车零部件开发中应用的可行性调研及实践

*本文源自汽车行业用户范会超投稿1、背景车型短周期开发背景下&#xff0c;高效的仿真技术显得尤为重要。Altair 推出了多款加速设计/仿真的软件&#xff0c;其中无网格软件 SimSolid 与业务有一定的契合度&#xff0c;有必要论证其在汽车零部件结构分析领域的可行性。2、目标评…

MacOS字体看起来比在 Windows 上更好?

字体控们注意啦&#xff01;&#x1f389;你们有没有发现&#xff0c;同样一段文字&#xff0c;在Mac和Windows上看起来就是不一样&#xff1f;Mac上的字仿佛自带柔光滤镜&#xff0c;圆润又舒适&#xff1b;而Windows上的字则像是精心雕琢的刀锋&#xff0c;锐利且清晰。这背后…

Torch -- 卷积学习day1 -- 卷积层,池化层

目录 一、CNN概述 二、卷积层 1、卷积核 2、卷积计算 3、边缘填充 4、步长 5、多通道卷积计算 6、多卷积核卷积计算 7、特征图大小 8、卷积参数共享 9、局部特征提取 10、卷积层API 三、池化层 1、池化层概述 1.池化层的作用 2.池化层类型 2、池化层计算 3、步…

蓝桥杯---第六届省赛单片机组真题

先出手写的代码&#xff0c;代码分析还需要一段时间&#xff0c;不难&#xff0c;大家认真写。#include <STC15F2K60S2.H> #include "Seg.h" #include "LED.h" #include "Key.h" #include "DS1302.h" #include "DS18B20.h&…

GPT-5深度解析:精准、高效、务实的新一代AI引擎

&#x1f31f; GPT-5深度解析&#xff1a;精准、高效、务实的新一代AI引擎在万众瞩目中&#xff0c;OpenAI于2025年8月7日正式推出GPT-5——这一代模型没有华丽的创意革命&#xff0c;却以惊人的准确率提升、断崖式降价和强大的工程能力&#xff0c;悄然重塑了生成式AI的应用边…

oss(阿里云)前端直传

WEB端前端直传 参考文档&#xff1a;web前端直传并设置上传回调 封装oss-upload.ts // 图片上传 import { uploadToken } from /api/uploadFile.js // 获取oss token接口// 定义 OSS 信息类型 interface OssInfo {policy: string;signature: string;x_oss_credential: strin…

vscode uv 发布一个python包:编辑、调试与相对路径导包

背景 最近一直在使用uv做python包管理&#xff0c;用起来很方便。 尤其是在代码上传到github的时候&#xff0c;pyproject.toml 会显示出当前项目依赖的python包。这样在把代码下载到本地之后&#xff0c;直接uv sync就可以很方便地恢复出python环境。 uv 除了有上述优点&…

Secure 第四天作业

实验需求&#xff1a;需求一拓扑&#xff1a;按照以上拓扑所示&#xff0c;完成以下需求&#xff1a;参考以上拓扑&#xff0c;配置设备IP地址&#xff0c;使用UNL里Secure第四天拓扑即可。&#xff08;有兴趣的同学课后也可按照PPT原拓扑做做实验&#xff09;&#xff1b;配置…

利用开漏输出模式模拟IIC

/************************************************************利用IO口模拟IIC时序&#xff0c;需要使用2个IO口(SDA和SCL)SCL时钟线只能由主器件进行控制&#xff0c;所以SCL引脚必须为输出模式SDA数据线&#xff0c;在主器件发送数据时&#xff0c;SDA引脚为输出模式SDA数…

闸机控制系统从设计到实现全解析:第 5 篇:RabbitMQ 消息队列与闸机通信设计

第 5 篇&#xff1a;RabbitMQ 消息队列与闸机通信设计RabbitMQ 是一款开源的消息队列中间件&#xff08;Message Queue&#xff0c;MQ&#xff09;&#xff0c;基于 Erlang 语言开发&#xff0c;遵循 AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高级消息队…

Linux 常用命令大全:覆盖日常 99% 操作需求

1、基本命令 pwd&#xff1a;显示当前工作目录的绝对路径&#xff0c;例如在复杂目录结构中快速确认位置&#xff0c;执行后会输出类似/home/user/documents的结果。 cd&#xff1a;切换目录&#xff0c;cd 目录路径可进入指定目录&#xff0c;cd ~回到当前用户的家目录&…

普通电脑与云电脑的区别有哪些?全面科普

近年来&#xff0c;越来越多的人不再购置升级自己的电脑&#xff0c;转而选择云电脑&#xff0c;云端产品正在变得越来越普及易用。那么它究竟跟我们的普通本地设备有什么区别呐&#xff1f;或许很多人并不知悉&#xff0c;对此&#xff0c;本篇内容小编就为大家简要科普一下普…

【Python】支持向量机SVM

示例代码&#xff1a;import numpy as np import matplotlib.pyplot as plt from sklearn import svm from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report# 设…