炫技亮点 Websocket集群解决方案汇总

news2024/9/28 15:19:30

文章目录

    • 问题
    • 方案
      • 方案一:~~Session共享~~(不可行)
      • 方案二:负载均衡器(状态路由)
      • 方案三:广播机制(异步方式 - 建议)
      • 方案四:路由转发(同步方式)
      • 方案五:高可用(多活冗余)

问题

假设我们有一个聊天应用程序,其中客户端通过WebSocket与服务器进行实时通信。在单机环境下,所有的WebSocket连接都由单个服务器处理。

单机场景

用户A、用户B和web服务器建立连接之后,用户A发送一条消息到服务器,服务器再推送给用户B,在单机系统上所有的用户都和同一个服务器建立连接,所有的session都存储在同一个服务器中。

但随着用户数量的增加,我们需要将应用程序扩展为WebSocket集群,以提供更好的性能和可伸缩性。

集群场景

当演变为集群环境后,用户A与节点1建立连接,用户B与节点2建立连接,用户A发送一条消息到服务器,服务器无法再推送用户B

在WebSocket集群中,一个常见的问题是连接状态同步。当一个节点接收到客户端的连接请求并与其建立WebSocket连接时,其他节点也需要了解这个连接的存在。这样,当其他节点收到消息时,它们可以将消息正确地推送给与该客户端相关联的节点。

然而,如果连接状态同步存在问题,可能会导致消息发送错误或丢失。例如,在一个WebSocket集群中,当一个客户端连接到节点A时,而其他节点(B、C)不知道这个连接存在,当节点B收到一条消息并尝试将其推送给该客户端时,它会失败,因为它不知道该客户端连接到了节点A。

这种情况下,客户端可能会错过重要的消息或者体验不一致的消息推送。此外,如果客户端断开连接时,各个节点的连接状态同步也是至关重要的。如果某个节点仍然认为客户端处于活动状态,而实际上该客户端已经断开连接,节点可能会继续尝试将消息推送给它,从而浪费资源和带宽。

为了解决这个问题,需要在集群中实现连接状态的一致性和同步机制,以确保消息能够正确地传递和推送给客户端。

方案

方案一:Session共享(不可行)

在WebSocket集群中,共享Session的方法并不适用于解决连接状态同步的问题。虽然在HTTP中,可以使用共享Session来解决集群问题,例如将Session信息存储在Redis数据库中,但是在WebSocket中这种方法是不可行的。

WebSocket的Session与HTTP的Session有所不同。WebSocket的Session是与连接相关的状态,而不是像HTTP的Session那样与请求相关。WebSocket的连接在不同的服务器之间是无法共享的,因此无法将WebSocket的Session存储在共享的存储中。

换句话说Http短连接是无状态的,websocket是长链接的有状态,连接在哪个节点就在哪个节点了。

方案二:负载均衡器(状态路由)

在WebSocket集群中,使用负载均衡器进行状态路由是一种常见的解决方案。负载均衡器可以将客户端的连接请求分发到集群中的不同节点上,以实现负载均衡和高可用性。

用户A、用户B与节点1建立连接,用户C与节点2建立连接,用户A发送一条消息到服务器,服务器再推送给用户B

固定参数哈希(Fixed Parameter Hashing): 这种策略是根据请求中的特定参数(例如会议ID)进行哈希计算,然后将相同哈希结果的请求路由到同一节点上。这样可以确保同一会话或同一组相关连接始终被路由到同一个节点上。这种方法的优点是保持了连接的一致性,缺点会导致节点负载不均衡,因为某些参数值可能会导致较大的连接集中在某些节点上。

下面是一个示例的Nginx配置,展示了如何使用固定参数哈希进行WebSocket连接的负载均衡:

http {
    upstream websocket_backend {
        hash $arg_meeting_id consistent;
        server backend1.example.com:8080;
        server backend2.example.com:8080;
        server backend3.example.com:8080;
    }
    
    server {
        listen 80;
        
        location /websocket {
            proxy_pass http://websocket_backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
        }
    }
}

方案三:广播机制(异步方式 - 建议)

在集群中的每个服务节点上发送群发消息,以确保消息能够覆盖到所有连接的客户端。可以通过使用消息队列或广播协议来实现该机制。然而,需要注意的是广播机制可能会增加网络负载和处理成本

为了解决发送方和接收方必须在同一个服务器下才能发送消息的限制,可以采用消息广播的方式将消息通知给所有的服务器。这可以通过使用消息中间件的发布订阅模式来实现。通过将消息发送到中间件,然后再将消息广播给订阅的服务器,类似于广播的方式,只要订阅了消息,就能接收到消息的通知。

具体实现方式可以使用以下两种方式之一:

  1. Redis的发布订阅(Pub/Sub):使用Redis作为消息中间件,发布者将消息发布到特定的频道,而订阅者会订阅该频道,从而接收到消息的通知。
  2. 消息队列的广播:使用支持广播功能的消息队列,如RabbitMQ或Apache Kafka。发布者将消息发送到消息队列的特定主题(topic),而所有订阅了该主题的消费者都能接收到消息。

以上方案都将消息的发送和接收解耦,并通过消息中间件来实现跨服务器的消息广播。这样,无论连接的客户端分布在哪个服务器上,都能够接收到广播的消息。

方案四:路由转发(同步方式)

在WebSocket集群中,可以采用路由转发的方式来处理群发消息。该方案的核心思想是在集群的每个服务节点上维护一个路由表(查不到时去redis查),记录连接的客户端和对应的服务节点。当发消息时,根据路由表将消息转发到对应的服务节点,由该节点负责将消息发送给连接的客户端。

具体实现该方案需要以下步骤:

  1. 连接路由表:每个服务节点维护一个连接路由表,用于记录客户端连接的信息,包括客户端标识(如客户端ID)和对应的服务节点(查不到时去redis查)。
  2. 路由协议:实现一个路由协议,用于在集群中的各个服务节点之间传递路由信息和消息(用Http协议或者用websocket协议模拟一个客户端都行)。
  3. 路由转发:当需要发消息时,消息发送方的服务节点根据路由表确定每个连接的客户端所在的服务节点,并将消息转发给对应的服务节点。
  4. 消息发送:接收到转发的消息的服务节点负责将消息发送给连接的客户端,确保消息能够到达每个客户端。

通过路由转发方案,可以将群发消息的负载分散到各个服务节点上,避免了单个节点处理大量消息的压力。同时,该方案也能够确保消息能够正确路由和转发到每个连接的客户端。

方案五:高可用(多活冗余)

在WebSocket集群中,可以采用高可用多活冗余方案来提高系统的可用性和容错性。该方案的核心思想是将多台服务器同时工作,并允许客户端同时连接到多台服务器。当需要发送消息时,每台服务器都将消息发送给连接到它的客户端。

具体实现该方案的步骤如下:

  1. 多台服务器:配置多台服务器,每台服务器都运行相同的应用程序,形成一个集群。这些服务器可以位于不同的物理位置或云服务商上。
  2. 客户端连接多台服务器,每个客户端就可以同时与多台服务器建立连接。
  3. 消息发送:当需要发送消息时,每个服务器都将消息发送给连接到它的客户端。这意味着每个服务器都需要维护自己的连接列表,并向连接的客户端发送消息。
  4. 容错处理:如果某台服务器出现故障或断开连接,其他服务器仍然可以继续发送消息给客户端。

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

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

相关文章

【JS经验分享】你真的会写JS吗?满满干货,建议读三遍(2)

大家好,最近准备总结一下JS的经验,分享分享,有不对的欢迎讨论哈~ JS作为前端的基础技能,每一位前端开发都要运用熟练,但你真的会写JS吗?js全称JavaScript,是运行在浏览器上的脚本语言&#xff0…

【高危】Nuxt.js <3.4.3 远程代码执行漏洞(POC公开)

漏洞描述 Nuxt.js(简称 Nuxt)是一个基于 Vue.js 的通用应用框架,用于构建服务端渲染的应用程序(SSR)和静态生成的网站。 Nuxt.js 3.4.3之前版本中的 test-component-wrapper 组件的动态导入函数存在代码注入漏洞,当服务器在开发…

Java集合流式编程

一、简介 1、什么是集合流式编程 集合流式编程(Stream API)是Java 8引入的一个功能强大的特性,它提供了一种更简洁、更高效的方式来操作集合数据。它的设计目标是让开发者能够以一种更声明式的风格来处理集合数据,减少了显式的迭…

Ubuntu部署jmeter与ant

为了整合接口自动化的持续集成工具,我将jmeter与ant都部署在了Jenkins容器中,并配置了build.xml 一、ubuntu部署jdk 1:先下载jdk-8u74-linux-x64.tar.gz,上传到服务器,这里上传文件用到了ubuntu 下的 lrzsz。 ubunt…

WordPress 备份插件 BackUpWordPress

WordPress备份是一件必不可少的事情,毕竟自己辛辛苦苦花了很多时间精力写得博客,经验总结,必须保留传承。WordPress备份可以在发生灾难性情况(比如劫持或意外锁定)下迅速恢复,确保了网站安全。 BackUpWord…

揭示不断增长的预切蔬菜市场:深入研究行业驱动因素和挑战

随着现代社会的快节奏和人们生活压力的增加,越来越多的人选择预制菜作为饮食解决方案,预制菜已经成为餐饮行业的新兴赛道。预制菜的优点包括方便快捷、卫生安全、节省时间、质量可靠,以及丰富的菜品选择和灵活的烹饪和食用方式,满…

基于SpringCloud微服务流动资金贷款业务系统设计与实现

一、引言 由于传统的贷款业务系统并不能够顺应时代的变化,同时在一定程度上对业务发展进行了限制,所以为了适应时代的发展,信息贷款业务应该能够被产品化、丰富化,同时还需要制定一套特定的流程来满足新时代用户的需求。流程化的规范管理是当今银行业务发展的必然趋势,研究并开…

基于Stable Diffusion的2D游戏关卡生成【实战】

接下来的几篇文章将与常规主题有所不同(这是在从事通用机器人技术的职业中吸取的教训)。 相反,我决定利用我的一些新空闲时间 1 边做边学,并使用所有酷孩子都在谈论的一些很酷的新 ML。 推荐:用 NSDT设计器 快速搭建可…

分割回文串-ii

分割回文串-ii 题目链接:分割回文串-ii 思路:分割字符串s,使得子串都是回文串,最后获得最小分割次数。那么我们可以不断把字符串缩短,判断子串是否可以被分割成回文串,并且最小分割次数。这就是子问题分割…

贝叶斯算法人生

哈喽大家好,我是咸鱼 之前看到过耗子叔写的一篇文章《程序算法与人生选择》,这篇文章中耗子叔结合计算机中的经典算法(排序、动态规划等等),让大家在人生道路的选择上获得了一些启发 我最近看了一些关于贝叶斯思想的…

StringBuilder和StringBuffer

StringBuilder和StringBuffer 目录 StringBuilder和StringBuffer特点常见方法练习:测试字符串连接StringBuilder和StringBuffer的区别 特点 封装了char[]数组 是可变的字符序列 提供了一组可以对字符内容修改的方法 常用append()来代替字符串做字符串连接”” 内部…

智慧文旅VR全景展示,深度VR沉浸式体验

导语: 智慧文旅VR全景展示为我们带来了一种独特的旅行体验,让我们可以穿越时空、身临其境地感受历史、艺术和自然的魅力。 在这个数字化时代,智慧文旅VR全景展示成为了旅游界的新宠,它让我们能够以一种前所未有的方式探索世界&am…

看完这篇 教你玩转渗透测试靶机vulnhub—Corrosion:2

Vulnhub靶机Corrosion:2渗透测试详解 Vulnhub靶机介绍:Vulnhub靶机下载:Vulnhub靶机安装:Vulnhub靶机漏洞详解:①:信息收集:②:Tomcat msf 上传漏洞拿到shell:③:look越权…

何时使用Kafka而不是RabbitMQ

Kafka 和 RabbitMQ 都是流行的开源消息系统,它们可以在分布式系统中实现数据的可靠传输和处理。Kafka 和 RabbitMQ 有各自的优势和特点,它们适用于不同的场景和需求。本文将比较 Kafka 和 RabbitMQ 的主要区别,并分析何时使用 Kafka 而不是 R…

独立商城系统开发功能注意事项有哪些?

电商行业的不断发展,越来越多的企业开始构建自己的独立商城系统,以满足消费者日益增长的需求。然而,在开发独立商城系统时,需要注意什么样的功能才能使其成为一个成功的电商平台呢?下面我们就来谈一谈独立商城系统开发…

【C++ 程序设计】第 8 章:文件操作

目录 一、文件基本概念和文件流类 (1)文件的概念 (2)C 文件流类 二、打开和关闭文件 (1)打开文件 (2)关闭文件 三、文件读写操作 (1)读写文本文件…

软件测试工程师的那些经验分享

前几天,一个朋友去面软件测试工程师的职位了,回来还信心满满的跟我诉说自己的面试经历。然而,最后这个面试扑街了。其实我早就料到了…… 在面试这个环节,很多细节如果处理不好,最后就会凉凉,无论你软件测…

《名侦探柯南》所有主题曲名字

《名侦探柯南》所有主题曲名字列表: 1.第1-30集:心中动荡不安 2.第21-52集:Feel Your Heart 3.第53-96集:谜 4.第97-123集:转动命运之轮 5.第124-142集:真相究明 6.第143-167集:情义之印 7.第16…

IDEA导入Web项目的三种方式

文章目录 前言一、第一种方式二、第二种方式三、第三种方式 前言 无论那种方式,它们都有相同的前提,那就是首先将你想要导入的Web项目放置在你想要导入的工程目录下 例如(举例子):笔者要将一个名为mavenWeb1的Web项目&…

设计模式-05.02-行为型-策略职责链

策略模式【常用】 策略模式。在实际的项目开发中,这个模式也比较常用。最常见的应用场景是,利用它来避免冗长的 if-else 或 switch 分支判断。不过,它的作用还不止如此。它也可以像模板模式那样,提供框架的扩展点等等。 策略模式…