SpringBoot生产级WebSocket集群实践,支持10万连接!
off999 2025-03-19 01:02 26 浏览 0 评论
1、问题背景
智慧门诊系统旨在从一定程度上解决患者面临的三长一短(挂号、看病、取药时间长,医生问诊时间短)的问题。实现“诊前、诊中、诊后”实时智能一体化,整合完善医院工作流程。围绕门诊看病的各个环节,让患者全程手机有提醒,让患者少排队、少跑腿、看病更简单,获得全流程的陪伴服务从而有效提升就医体验。
系统通过接收医院第三方系统推送的门诊数据,再结合业务服务处理后主动推送到前端,从而实时的将数据同步给患者手机。之所以没有采用传统的前端轮训方案,主要是在当前业务场景下存在时效性不足,资源浪费等问题。但与此同时也有代价的,相比于Http的无状态通信,服务端主动推送是有状态协议的,客户端连接服务器时只和集群中一个节点连接,数据传输过程中也只与这一节点通信,在集群多台服务器环境下,我们就出现了服务端部分消息推送丢失的现象。
当前架构图如下:
2、问题分析和整体思路
客户端和服务端每次建立连接时候,会创建有状态的会话Session,服务器得保存维持连接的Session。客户端每次只能和集群服务器其中的一个服务器连接,后续也是和该服务器进行数据传输。因此集群的问题,应该考虑Session的问题,客户端成功连接服务器之后,其他服务器也知道客户端连接成功。
可以使用Nginx负载均衡的ip hash算法,客户端每次都是请求同一个服务器,客户端的session都保存在该服务器上,而后续请求都是请求该服务器,都能获取到session,就不存在分布式session问题了。websocket相对http来说,可以由服务端主动推动消息给客户端,如果接收消息的服务端和发送消息消息的服务端不是同一个服务端,发送消息的服务端无法找到接收消息对应的session,即两个session不处于同一个服务端,也就无法推送消息。
解决问题的方法是将所有消息的发送方和接收方都处于同一个服务器下,而消息发送方和接收方都是不确定的,显然是无法实现的。将消息的发送方和接收方都处于同一个服务器下才能发送消息,那么可以转换一下思路,可以将消息以消息广播的方式通知给所有的服务器,可以使用消息中间件发布订阅模式,消息脱离了服务器的限制,通过发送到中间件,再发送给订阅的服务器,类似广播一样,只要订阅了消息,都能接收到消息的通知。
3、解决方案
WebSocket协议是基于TCP的一种新的网络协议,是一个应用层协议,是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议,与 TCP 一样,客户端和服务器都可以随时向对方发送数据,而不用像 HTTP请求 - 应答”通信模式。于是,服务器就可以变得更加“主动”了。一旦后台有新的数据,就可以立即“推送”给客户端,不需要客户端轮询,“实时通信”的效率也就提高了。
浏览器是一个“沙盒”环境,有很多的限制,不允许建立 TCP 连接收发数据,而WebSocket利用了 HTTP 本身的“协议升级”特性,“伪装”成 HTTP,这样就能绕过浏览器沙盒、与服务器直接建立“TCP 连接”,获得更多的自由。
一个典型的 Websocket 握手请求如下:
1、客户端请求
2、服务器回应
WebSocket是有状态的,无法像直接HTTP以集群方式实现负载均衡,长连接建立后即与服务端某个节点保持着会话,因此集群下想要得知会话属于哪个节点,有两种方案,一种是使用类似微服务的注册中心来维护全局的会话映射关系,一种是使用事件广播由各节点自行判断是否持有会话,两种方案对比如表所示。
综合考虑实现成本与集群规模,选择了轻量级的事件广播方案。实现广播可以选择基于RocketMQ的消息广播、基于Redis的Publish/Subscribe、基于服务的通知等方案,其优缺点对比如表所示。从实时性、实现难易等方面考虑,同时对于持久化高可靠级别并没有太高要求,最终选择了Redis。
改造后架构图如下:
4、核心实现
基于spring boot建立websocket连接
基于spring boot接收 websocket消息
基于spring boot发布和订阅Redis消息
vue前端websocket建立连接、心跳检测、发送消息、消息订阅等
Nginx反向代理配置
5、性能测试
性能压测选择两台配置为2核16G的虚拟机,分别作为服务器和客户端。压测时选择为网关开放了5个端口,同时建立5个客户端,每个客户端使用一个服务端端口建立起2万连接,可以同时创建10万个连接。连接数与内存使用情况如图所示。
给10万个长连接同时发送一条消息,采用单线程发送,服务器发送完成的平均耗时在10s左右,如图所示。
当前的性能指标已满足智慧门诊的实际业务场景,可支持未来的业务增长。
6、产品效果
7、问题和展望
当前WebSocket实现分散在在各个服务中,与业务系统强耦合,如果有其他业务需要集成WebSocket,面临着重复开发的窘境,浪费成本、效率低下。后续建议在网关中扩展统一集成管理websocket,能够具备以下特点:
- 集中实现长连接管理和推送能力。统一技术栈,将长连接作为基础能力沉淀,便于功能迭代和升级维护。
- 与业务解耦。将业务逻辑与长连接通信分离,使业务系统不再关心通信细节,也避免了重复开发,浪费研发成本。
- 使用简单。提供HTTP推送通道,方便各种开发语言的接入。业务系统只需要简单的调用,就可以实现数据推送,提升研发效率。
- 分布式架构。实现多节点的集群,支持水平扩展应对业务增长带来的挑战;节点宕机不影响服务整体可用性,保证高可靠。
- 多端消息同步。允许用户使用多个浏览器或标签页同时登陆在线,保证消息同步发送。
- 多维度监控与报警。自定义监控指标与现有微服务监控系统打通,出现问题时可及时报警,保证服务的稳定性。
来源:
https://mp.weixin.qq.com/s/whdDS-k0JVXo_dRGqDo0Rw
相关推荐
- Python自动化脚本应用与示例(python自动化脚本教程)
-
Python是编写自动化脚本的绝佳选择,因其语法简洁、库丰富且跨平台兼容性强。以下是Python自动化脚本的常见应用场景及示例,帮助你快速上手:一、常见自动化场景文件与目录操作O批量重命名文件...
- 如何使用Python实现一个APP(如何用python做一个程序)
-
要使用Python实现一个APP,你可以选择使用一些流行的移动应用开发框架,如Kivy、PyQt或Tkinter。这里以Kivy为例,它是一个跨平台的Python框架,可以用于创建漂亮的图形用户界面(...
- 免费定时运行Python程序并存储输出文档的服务推荐
-
免费定时运行Python程序并存储输出文档的服务推荐以下是几种可以免费定时运行Python程序并存储输出结果的云服务方案:1.PythonAnywhere特点:提供免费的Python托管环境支持定时...
- 【Python程序开发系列】如何让python脚本一直在后台保持运行
-
这是我的第385篇原创文章。一、引言让Python脚本在后台持续运行,有几种常见的方式,具体方式可以根据你的系统环境和需求选择。二、Linux或macOS系统2.1使用nohup命令no...
- 运行和执行Python程序(运行python的程序)
-
一、Python是一种解释型的脚本编程语言,这样的编程语言一般支持两种代码运行方式:交互式编程在命令行窗口中直接输入代码,按下回车键就可以运行代码,并立即看到输出结果;执行完一行代码,你还可以继续...
- Python 初学者指南:计算程序的运行时长
-
在编写Python程序时,了解程序的运行时长是一项很有用的技能。这不仅能帮助你评估代码的效率,还能在优化程序性能时提供关键的数据支持。对于初学者来说,计算程序运行时长其实并不复杂,接下来就让我们看...
- pyest+appium实现APP自动化测试,思路全总结在这里
-
每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试码同学抖音号:小码哥聊软件测试01appium环境搭建安装nodejshttp://nodej...
- 血脉觉醒后,编程小白我是如何通过Deepseek和Trae轻松开发软件的
-
以下就是作为一个编程小白的我,是如何一步步开发软件的保姆级教程,请点赞收藏:第一步:打开#deepseek#(首先关闭深度思考和联网搜索)输入或复制你要让它做一个什么样软件的要求和提示词(你可以先用...
- 我用Deepseek+Trae写的python小软件,小白也能轻松用上模型啦!
-
利用AI大模型deepseek,搭配TraeCN,用半个小时做了一个本地Ollama安装部署和一键卸载的小工具,哈哈哈!感觉还不错#deepseek#一直想做一个本地Ollama安装部署和一键卸载...
- 在安卓设备上运行Python的方法(安卓能运行python吗)
-
技术背景在安卓设备上运行Python可以为开发者提供更多的开发选择和灵活性,能够利用Python丰富的库和简洁的语法来开发各种应用,如游戏、脚本工具等。然而,由于安卓系统原生不支持Python,需要借...
- 零基础小白,DeepSeek全自动编程,超详细提示词,一键生成软件!
-
我前面发表了文章,详细说了编程零基础小白,如何利用DeepSeek进行编程的全过程,感兴趣的可以去看看:DeepSeek全自动编程很多人不会写提示词,不知道怎么开始对话。话不多说,请先看下图中的对话,...
- 小白用DeepSeek+Python编写软件(用python制作软件)
-
周末无事,用DeepSeek生成全部代码,写了一个mp3音乐播放器,几分钟搞定,DeepSeek确实太强大了。我的提示语是这么写的:“请用Python语言写一个音乐播放器,支持常见音乐格式,我是Pyt...
- 零基础使用DeepSeek开发Windows应用程序,超简单超实用!
-
你敢相信,我居然用DeepSeek开发了一个能用的Windows软件!整个过程就像和学霸同桌组队做作业,我负责提需求,DeepSeek负责写代码改bug,全程碰到任何问题直接丢给DeepSeek即可。...
- 第二篇:如何安装Python并运行你的第一个程序
-
欢迎回到我的Python入门教程系列!在上一篇中,我们讨论了为什么Python是一门值得学习的编程语言。今天,我们将迈出第一步:安装Python并运行你的第一个程序。无论你是Windows、macOS...
- Python 运行,带你找入口,快速读懂程序
-
有C或Java编程开发经验的软件开发者,初次接触python程序,当你想快速读懂python项目工程时,是否觉得python程序有些太过随意,让你看有些无所适从,进而有些茫然。这是...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Python自动化脚本应用与示例(python自动化脚本教程)
- 如何使用Python实现一个APP(如何用python做一个程序)
- 免费定时运行Python程序并存储输出文档的服务推荐
- 【Python程序开发系列】如何让python脚本一直在后台保持运行
- 运行和执行Python程序(运行python的程序)
- Python 初学者指南:计算程序的运行时长
- pyest+appium实现APP自动化测试,思路全总结在这里
- 血脉觉醒后,编程小白我是如何通过Deepseek和Trae轻松开发软件的
- 我用Deepseek+Trae写的python小软件,小白也能轻松用上模型啦!
- 在安卓设备上运行Python的方法(安卓能运行python吗)
- 标签列表
-
- python计时 (54)
- python安装路径 (54)
- python类型转换 (75)
- python进度条 (54)
- python的for循环 (56)
- python串口编程 (60)
- python写入txt (51)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python qt (52)
- python人脸识别 (54)
- python斐波那契数列 (51)
- python多态 (60)
- python命令行参数 (53)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- centos7安装python (53)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)