集群聊天服务器项目(三)——负载均衡模块与跨服务器聊天

2023-05-16

负载均衡模块

为什么要加入负载均衡模块

原因是:单台服务器并发量最多两三万,不够大。

负载均衡器 Nginx的用处或意义**(面试题)**

  • 把client请求按负载算法分发到具体业务服务器Chatserver
  • 能和ChatServer保持心跳机制,检测ChatServer保持心跳机制,检测ChatServer故障
  • 能发现新添加的ChatServer设备方便服务器扩展数量

客户端和某台服务器可建立IP隧道

想要更大并发量可以对负载均衡器再做集群

负载均衡模块在整个程序中的位置如下图

在这里插入图片描述

如何配置nginx的TCP负载均衡模块

首先解压nginx的安装包 (tar zxvf);

进入nginx安装包中编译加入--with-stream参数激活tcp负载均衡模块

~/package/nginx-1.12.2# ./configure --with-stream
~/package/nginx-1.12.2# make && make install

编译完成后,默认安装在 /usr/local/nginx

$ cd /usr/local/nginx/
/usr/local/nginx$ ls

可执行文件在sbin目录里面,配置文件在conf目录里面。

nginx -s reload #重新加载配置文件启动
nginx -s stop #停止nginx服务

nginx.conf的补充内容如下

events {
    worker_connections  1024; #最大连接数1024,默认为512
}
#-------------------------------添加的内容------------------------

stream {
      upstream MyServer {
          # max_fails最大失败次数,若超过则判断连接失败
          # fail_timeout,发出心跳包超过改时间没收到回包就算一次失败
          server 127.0.0.1:6000 weight=1 max_fails=3 fail_timeout=30s;
          server 127.0.0.1:6002 weight=1 max_fails=3 fail_timeout=30s;
      }
  
      server {      
          proxy_connect_timeout 1s;
          listen 8000;
          proxy_pass MyServer; # 所有连接到8000端口的请求都往MyServer指定的主机里负载均衡
          tcp_nodelay on;
      }
  }
#---------------------------------------------------------------

其中 weight表示权重

上面配置也就是说,客户端连接服务器时端口号填8000就是连接到负载均衡器上,它会帮助我们把请求分发到 127.0.0.1:6000127.0.0.1:6002端口上.

配置修改后可用 ./nginx -s reload平滑重启。

注意:这么修改了之后,客户端连接服务端的地址都要为127.0.0.1:8000,也就是连接到负载均衡器上而不是确定的服务器端口上。

sudo netstat -anp查看nginx进程是否启动在80端口监听

在这里插入图片描述

服务器通过负载均衡器按权重分别接收一个连接

在这里插入图片描述

redis发布订阅消息队列

背景

当客户端登录到不同的服务器时,应该如何解决跨服务器通信问题?

假如采用两两服务器之间建立连接

在这里插入图片描述

上图设计相当于在服务器网络之间进行广播。这样的设计使得各个服务器之间耦合度太高,不利于系统扩展,并且会占用系统大量的socket资源,各服务器之间的带宽压力很大,不能够节省资源给更多的客户端提供服务,因此绝对不是一个好的设计。
集群部署的服务器之间进行通信,最好的方式就是引入中间件消息队列解耦各个服务器,使整个系统松耦合,提高服务器的响应能力,节省服务器的带宽资源,如下图所示:

在这里插入图片描述

集群分布式环境中,经常使用的中间件消息队列ActiveMQRabbitMQKafka等,都是应用场景广泛并且性能很好的消息队列,供集群服务器之间,分布式服务之间进行消息通信。

发布订阅是观察者模式的使用场景。

消息队列是长连接跨服务器聊天通用方法,工作流程大致如下

客户端c1在某个服务器上连接后,要把该连接在redis队列上订阅一个通道ch1

别的客户端c2在不同的服务器上登录要给c1发消息,会直接发到redis队列上的通道ch1,客户端c1可接受到信息发布到通道ch1

要开一个单独线程进行监听通道上的事件,有消息给业务层上报。

当服务器发现发送的对象id没有在自己的_userConnMap上,就要往消息队列上publish,消息队列就会把消息发布给订阅者。

redis服务器后台运行输入如下指令

redis-server --daemonize yes

发布订阅功能要开两条redis连接即两个redisContext *,一条用于订阅和接收消息,一条用于发布消息,这么做的原因是因为订阅 SUBSCRIBE时会进入阻塞状态,代码如下

// 向redis指定通道channel发布消息
bool Redis::publish(int channel, string message)
{
    redisReply *reply = (redisReply *)redisCommand(_publish_context, "PUBLISH %d %s", channel, message);
    if (nullptr == reply)
    {
        cerr << "publish command failed!" << endl;
        return false;
    }
    freeReplyObject(reply);
    return true;
}

// 向redis指定通道subscribe订阅消息
bool Redis::subscribe(int channel)
{
    // SUBSCRIBE命令本身会造成线程阻塞等待通道里发生消息,这里只做订阅通道,不接受通道消息
    // 通道消息接收专门在 observer_channel_message 函数中的独立线程中进行
    // 只负责发送命令,不阻塞接收redis server响应消息,否则和notifyMsg线程抢占响应资源
    if (REDIS_ERR == redisAppendCommand(this->_subscribe_context, "SUBSCRIBE %d", channel))
    {
        cerr << "subscribe command failed!" << endl;
        return false;
    }
    // redisBufferWrite可循环发送缓冲区累积的命令,知道缓冲区数据发送完毕(done被置1)
    int done = 0;
    while (!done)
    {
        if (REDIS_ERR == redisBufferWrite(this->_subscribe_context, &done))
        {
            cerr << "subscribe command failed!" << endl;
            return false;
        }
    }
    return true;
}

本项目使用hiredis进行redis编程,加入redis的发布订阅消息队列后,业务层的改动大致如下:

  • chatservice构造中连接redis即调用connect,并设置上报消息的回调,connect中会开启一条新线程调用 observer_channel_message函数进行循环接收订阅通道上的消息,有消息到来给业务层上报。
  • 登录时订阅subscribe channel
  • 聊天时遇到用户在别的服务器上登录(userid不在map中,但状态为online)就publish
  • 注销就取消订阅 unsubscribe channel

杂项

  • 若不满意Nginx负载均衡效果前面可加LVS(Linux Virtual Server)

  • 负载均衡器 - 一致性哈希算法学有余力可了解

  • IP隧道

    IP隧道(IP Tunnel)是一种虚拟的网络连接方式,它允许将一个IP数据包传输到另一个IP网络中,同时保留原始数据包的源和目的地址。它通常用于将两个不同的IP网络连接起来,使它们看起来像一个单一的网络。IP隧道的主要目的是为了解决网络互联问题,特别是当两个不兼容的网络需要进行通信时。

    在IP隧道中,数据包被封装在另一个IP数据包中,以便在一个网络上传输到另一个网络。这个封装过程称为“隧道ing”,隧道的两端点被称为“入口”和“出口”。入口点将原始IP数据包封装在另一个IP数据包中,将其发送到出口点。出口点接收到封装后的数据包,然后解封装出原始的IP数据包,并将其传送到目的地。

    IP隧道的优点是它可以让不同的网络连接起来,同时保持原有的网络拓扑结构和地址分配。但是,它也会带来一些缺点,例如会增加网络延迟和降低网络性能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

集群聊天服务器项目(三)——负载均衡模块与跨服务器聊天 的相关文章

  • linux---生产者和消费者模型(条件变量和信号量实现)

    问题的提出 在我们对一些全局变量的进行非原子性操作的时候就可能出现非线程安全 xff0c 比如我们吃面的问题 我们做面的人就是生产者 xff0c 吃面的人就是我们的消费者 xff0c 当我们的消费者需要吃面的时候就唤醒我们的生产者进行生产
  • 【SLAM学习】一些必备依赖包的安装与问题总结

    Ceres xff1a 下载地址 xff1a https github com ceres solver ceres solver releases tag 1 14 0 1 修改 sources list sudo gedit etc a
  • 【数据集】数据集下载总结

    1 AI Studio 数据集 开放数据集 百度AI Studio 人工智能学习与实训社区 2 天池 数据集 数据集 阿里系唯一对外开放数据分享平台 3 Papers with code 数据集 Machine Learning Datas
  • 【RealSense】L515学习记录

    Intel RealSense SDK 2 0的安装 1 注册服务器的公钥 sudo apt key adv keyserver keyserver ubuntu com recv key F6E65AC044F831AC80A06380C
  • 【YOLOv5】记录YOLOv5的学习过程

    以下记录的是Ubuntu20 04版本 xff0c 其他Ubuntu版本也相差不大 一 安装pytorch GPU版本 显卡驱动 CUDA cuDNN 下载pytorch GPU版本 xff1a 最新版本链接 xff1a Start Loc
  • 【Kinect】Ubuntu20.04 安装Azure Kinect Sensor

    本文主要记录Ubuntu20 04 安装Azure Kinect Sensor SDK Azure Kinect 人体跟踪 SDK官网 xff1a https learn microsoft com zh cn azure Kinect d
  • 【ORB_SLAM】Ubuntu20.04 配置ORB_SLAM3

    本文主要记录基于Ubuntu20 04环境下 xff0c 对普通的ORB SLAM3和稠密版本的ORB SLAM3进行环境的配置 一 配置ORB SLAM3 lt 普通版本 gt 1 安装ROS开发环境 这里采用鱼香ros的一键安装 xff
  • 【工具】记录安装Zsh

    本文主要记录下安装Zsh的过程 xff0c 方便后续换设备安装 xff01 与大家共同学习 xff01 xff08 Ubuntu 20 04 xff09 安装zsh sudo apt install zsh 2 下载oh my zsh 并安
  • 【Ubuntu】记录Ubuntu缺少启动项问题

    今天突然发现自己装的Ubuntu没有启动项 xff0c 也就是没有那个EFI分区 xff0c 人都麻了 xff01 原因是先把装Ubuntu的固态拿了出来 xff0c 再装的win11 xff0c 结果win11可以用了 xff0c Ubu
  • 【SLAM学习】基于Pangolin绘制运动轨迹

    Pangolin库 是一个轻量级的跨平台视图控制库 xff0c 主要用于可视化 交互和调试三维数据 该库提供了一系列图形界面工具 xff0c 包括窗口 OpenGL渲染器 3D相机 图像显示等 xff0c 可以方便地进行三维数据可视化和交互
  • Groovy学习-IO/文件操作

    读取文件 读取文本文件并打印每一行文本 new File 39 39 39 a txt 39 eachLine line gt println line eachLine方法是Groovy为File类自动添加的方法 xff0c 同时提供多个
  • linux---线程池种类以及实现(固定数量)

    线程池是什么 一堆固定的数量的或者有最大数量限制的线程 43 任务队列 gt 用于我们并发处理请求 xff0c 避免了大量频繁的线程的创建和销毁的事件成本 xff0c 同时避免了峰值压力带来瞬间大量线程被创建资源耗尽 xff0c 程序奔溃的
  • 什么是线程池?为什么使用线程池?

    1 什么是线程池 xff1f 线程池和数据库连接池非常类似 xff0c 可以统一管理和维护线程 xff0c 减少没有必要的开销 2 为什么要使用线程池 xff1f 因为频繁的开启线程或者停止线程 xff0c 线程需要重新从cpu从就绪状态调
  • Java实现List按条件分成多个子List

    一 业务场景 相信很多开发的小伙伴都有遇到过需要对表按特定条件进行查询 xff0c 然后再进行归类 xff0c 比如 xff1a 对员工表进行检索 xff0c 然后分别按他们所在的部门进行归类 xff0c 一般的做法都是按部门唯一标识 xf
  • MySQL生成随机姓名

    CREATE DEFINER 61 96 root 96 64 96 localhost 96 FUNCTION 96 rand name 96 n int RETURNS varchar 16 CHARSET utf8 begin 初始化
  • RabbitMQ的安装教程

    本文介绍RabbitMQ在Linxu上的安装教程 一 下载相关安装包 相应的安装包可以从官网上 xff08 https www rabbitmq com xff09 进行下载 xff0c 也可以从我的网盘上下载 蓝奏云地址 xff1a ht
  • SpringBoot实现广州健康通疫苗预约提醒

    一 前言 终于轮到了打第二针疫苗的时候 xff0c 无奈每次打开 广州健康通 或 粤康通 小程序 xff0c 每次都是被预约完的状态 xff0c 广州人口众多 xff0c 说不定有很多人一直守在小程序前等着放号 xff0c 所以这篇文章就诞
  • 搭建SFTP服务器实现文件上传

    1 前言 最近一直在做数据迁移接口的开发 xff0c 涉及到大文件的远程下载与上传 xff0c 其实倒没有什么原理可言 xff0c 无非就是两台机器互连之后 xff0c 获得文件流然后进行传输 xff0c 不过在这过程也遇到过一些小坑 xf
  • SpringBoot整合RabbitMQ实现五种消息模型

    一 什么是消息队列 xff1f 消息 xff0c 可以理解为两个应用之间传递的数据 xff0c 数据可以是基本数据类型 xff0c 也可以是对象等 消息队列 xff0c 则是容器 xff0c 生产者产生的消息存放在这个容器里面 MQ的整个过

随机推荐

  • SpringBoot整合CXF框架实现Webservice服务端

    1 前言 近期接手一个10多年的老项目 xff0c 敲重点 xff0c 10多年 xff01 xff01 xff01 就是最纯粹的servlet技术 xff0c 貌似是从2008年运维到现在 xff0c 老项目终究会有被淘汰的这一天 xff
  • Windows下切换不同版本JDK

    1 前言 从四月份重新入职新公司以来 xff0c 主要负责两个项目的开发 xff0c 一个是10多年前的项目 xff0c 一个是2019年开始开发的项目 xff0c 这两个项目依赖于不同版本的JDK xff0c 一个是JDK6 xff0c
  • css实现圆形div旋转,如“已预约”效果

    lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt lt title gt lt head gt lt style g
  • c++---类和对象(六大默认成员函数)

    类中默认的六个成员函数构造函数析构函数拷贝构造函数赋值操作符重载取地址和const取地址操作符重载const成员函数 1 类中默认的六个成员函数 首先看看下面代码 class A int main A a return 0 这个代码并没有报
  • 微服务系列--nacos注册中心与服务发现

    1 前言 终究还是到了更新关于微服务相关博客的时候了 xff0c 经过挺长一段时间微服务的自主学习 xff0c 现在不敢说自己熟悉微服务 xff0c 但我也能略知一二 微服务嘛 xff0c 其实入门之后便会发现 xff0c 其实关于微服务相
  • 微服务系列--Ribbon负载均衡

    1 前言 这篇文章接上一篇文章进行开发 xff0c 上一篇整合完了Nacos xff0c 这篇来整合Ribbon Ribbon不属于SpringCloud Alibaba的东西 xff0c 而是基于Netflix Ribbon实现的 可以让
  • Centos7安装Jenkins

    将Jenkins存储库添加到yum repos xff0c 并安装Jenkins sudo wget O etc yum repos d jenkins repo http pkg jenkins ci org redhat jenkins
  • Jenkins自动化部署SpringBoot项目

    首先需要安装所需的两个插件 xff0c Maven Integration plugin 和 Publish Over SSH 在 系统配置 xff0c 将服务器信息配置到jenkins xff0c 我用的是腾讯云服务器 xff0c 所以将
  • 优雅关闭SpringBoot项目-接口方式

    前言 一般在服务器重新部署SpringBoot项目 xff0c 无非就是用kill 9暴力停止进程 xff0c 但会造成很多数据问题 xff0c 如果遇到一些耗时或者正在处理交易类的业务时 xff0c 直接导致数据异常 xff0c 严重会导
  • Linux安装Jenkins

    前言 现在Jenkins的最新版本都需要基于JDK11以上才能够正常使用 xff0c 不然会出现各种插件安装不上的问题 又不想安装JDK11 xff0c 想继续用JDK8 xff0c 只能通过指定安装符合JDK8的Jenkins版本 PS
  • rosdep update出错解决办法(2021)

    ROS安装方法 xff1a ros安装后 xff0c 初始化时rosdep update出错解决办法 2021 06 30 初始化时rosdep update出错解决办法 2021年以前 xff0c 通过科学上网 手机开热点等方式 xff0
  • 0x0FA23729 (vcruntime140d.dll)处(位于 类和对象-封装.exe 中)引发的异常(已解决)

    运行程序的时候第42行 抛出异常 xff0c 但是我将该cpp文件放到别的解决方案下就不会出异常 include lt iostream gt include lt string gt using namespace std class P
  • Win10 摄像头:由于其配置信息(注册表中的)不完整或已损坏,Windows无法启动这个硬件设备.【未解决完全】

    问题描述 xff1a 刚刚重装完win10系统之后 xff0c 出现无法打开摄像头的问题 xff0c 解决方法 xff1a 通过修改注册表中得相关信息进行解决 首先打开设备管理器 xff0c 找到设备的类Guid记录下Guid 的值 如此处
  • 2021年总结与2022年展望

    一 工作和学习 通过调剂 xff0c 正式成为了一名研究生 xff0c 结束了自己两年的考研备考 xff0c 不知道是好还是坏 xff0c 看到周围朋友考的时候心里还是会有点失落感 在一家通信设备公司实习软件测试 xff0c 收获很多 xf
  • 计算机网络---网络基础(TCP/IP五层模型,数据的封装和分用)

    认识网络中常用的名词以及基本的概念熟悉OSI七层模型和TCP IP五层模型理解网络通信的数据传输流程 认识网络中常用的名词 ip地址 ip地址就是表示我们一台主机的因为数字不好记忆 xff0c 通常使用点分十进制表示IP xff0c 每条数
  • C语言简易TCP服务端程序

    C语言TCP服务端程序 文章目录 C语言TCP服务端程序项目介绍关键技术代码实现一请求一线程方式epoll方式实现多个客户端连接的TCP服务端程序epoll的水平触发和边缘触发 完整代码编译和启动使用NetAssist测试 项目介绍 本项目
  • C++使用gRPC实例

    什么是gRPC RPC 即远程过程调用协议 xff08 Remote Procedure Call Protocol xff09 xff0c 可以让我们像调用本地对象一样发起 远程调用 RPC 凭借其强大的治理功能 xff0c 成为解决分布
  • 复睿智行CC++开发实习面试

    线上面试 xff0c HR和一位技术的面试官 自我介绍 现在研究生学习的方向是什么 xff1f 我还去答区块链 xff0c 本来就半桶水 xff0c 还不如直接回答C C 43 43 后端这个方向 大数据分析这一块有做过吗 xff1f 我
  • 经纬恒润LinuxC++日常实习面经

    自我介绍 在学校成绩如何 xff0c 有没有获得奖学金 xff0c 考研的时间等等相关问题 能实习多久 xff0c 研究生研究的方向 你这个LinuxC 43 43 开发的学习是自学的吗 xff0c 怎样的自学途径 我 xff1a 看书 看
  • 集群聊天服务器项目(三)——负载均衡模块与跨服务器聊天

    负载均衡模块 为什么要加入负载均衡模块 原因是 xff1a 单台服务器并发量最多两三万 xff0c 不够大 负载均衡器 Nginx的用处或意义 xff08 面试题 xff09 把client请求按负载算法分发到具体业务服务器Chatserv