会议平台后端优化方案

会议平台后端优化方案

通过RTC的学习,我了解到了端对端技术,就想着做一个节省服务器资源的会议平台
之前做了这个项目,快手二面被问到卡着不知如何介绍,便有了这篇文章

分析当下机制

相对于传统视频平台(SFU,MCU架构)

之前帮学长做压测RTC监控时,10M校园网宽带,标清画质只能跑到22个(MCU架构),

毕竟是监控就只能卡在自己宽带下了

image-20241001001901382

所有资源从服务器拉取,大量的上下传极大的加重了服务器压力,

目前行业内如直播方式更多是使用分布式服务器,

如我在北京开了直播,一部分观众在广东一部分在上海,

此时,视频流将先传到北京服务器转发到广东服务器和上海服务器进行一个服务器的分压处理,当然下面还有更多子服务器去分压,

而这种形式对于我们这种学生开发者是行不通的,我们只能省吃俭用租用一台公有云,

而在之前开发 ESP32 Mesh 组网时来了灵感

ESP-MESH - ESP32 - — ESP-IDF 编程指南 v4.3.1 文档 (espressif.com)

image-20241001002741260

我们如果做一个多人群聊(类似会议平台),只需要使用每个设备进行 P2P 的 RTC 推拉流可以完美减缓服务器压力,

而服务器只需要负责信令汇总交换,还有客户端检测,保活的操作即可

甚至我的轻量级服务器也能跑上(压测时,用到了redis缓冲mysql)

也许好的想法总是相似的,网上看到了很多大佬也这样去做了(MESH架构)

image-20241001003423135

我第一次尝试使用了 golang gin 去写一个信令交互(也是有golang直接能调库使用RTC的原因),

实现的并不是很理想,

做了票据凭证登录(邮箱),

设计了 Mysql数据库(大家平时多练习,面试要手撕),

最后实现了点对点,并不是很理想。

毕竟跑在一个2核1G内存的超级轻量级服务器上的,

配合其他项目。。。。单是跑起来就直接爆了几次内存,(也不太敢和别人聊这个项目最后成果)

更别提对他进行压测,

后来重新捡起来后,打算直接融入到我的博客网站其中一个路由中,

实现了一个保障会议成员隐私,使用完无痕,的会议平台。(仅供学习参考)

image-20241001013250207

会议创建机制

一个post创建会议

会议号类似秘钥,名字可填可不填,不填我爬 ip 用 ip代指,

房间创建后永久保留唯一留痕在这里(不是说无痕吗?创建的人还是要跟踪记录爬取一下的哈哈哈,之前经历了sql注入,还好做了防注入 )

a20f0822cbcb1e32db5ec3580c9d65e

爬取ip以及地点 看是谁创的

image-20241001005056686

image-20241001005121677

这里meeting_id作为索引,指向另一张表参加此id的人群,

来完成一个快速查表工作,

当然此时还没加入会议,

加入会议机制

对于保活,和及时提出会议,像我个人感受

我每次开完会更希望直接关闭浏览器实现一个全自动退出会议的方式,

image-20241001012330563

关闭浏览器后,检测断开直接删除

image-20241001012344316

我之前开发 esp32 AP 模式时(哈哈哈还是esp)

需要通过wifi节点的web直接对esp进行操作,如小车前进后退

使用了websocket,

我便考虑了websocket,他可以实时检测,又是全双工,

完美的事物总是有缺陷的一面,

我需要给他额外开端口,

这可不是什么好方式,又要去申请一张证书,不然万一来个中间人攻击那大家的隐私不是没了吗?

此时我发现了SocketIO 基于websocket,可跑在443端口的神器,

python示例代码:

首先,便是相应库使用,以及对基础连接进行反应

from flask import Flask
from flask_socketio import SocketIO, emit,sessionapp = Flask(__name__)
socketio = SocketIO(app)@socketio.on('connect')
def handle_connect():print('A client has connected.')

接下来我们就要处理加入事件

拿到消息后,存入到session中,以便后续对断开操作

@socketio.on('join')
def handle_join(data):meeting_id = data['meeting_id']user_id = data['user_id']SDP = data['SDP']CANDIDATE = data['CANDIDATE']session['user_id'] = user_idsession['meeting_id'] = meeting_idprint(f"User {user_id} try to join meeting {meeting_id}")

连接数据库

把这个用户归类到相应room中

以便后续处理

connection = connector.connect(**db_config)cursor = connection.cursor()cursor.execute("SELECT * FROM meetings WHERE meeting_id = %s", (meeting_id,))meeting = cursor.fetchone()if not meeting:socketio.emit('join_response', {"error": "会议不存在"}, to=request.sid)returnprint(f'a client {user_id} has joined the meeting {meeting_id}')# 将用户加入房间join_room(meeting_id)# 插入参与者到数据库cursor.execute("INSERT INTO participants (meeting_id, user_id,SDP,CANDIDATE) VALUES (%s, %s,%s,%s)", (meeting_id, user_id,SDP,CANDIDATE))connection.commit()

拉取room的所有人进行广播,更新参与者,把拉取的数据整理成字典,传至前端

#返回此会议室的所有人的信令cursor.execute("SELECT user_id, SDP, CANDIDATE FROM participants WHERE meeting_id = %s",(meeting_id,))room_participants = cursor.fetchall()dist={}for i in room_participants:dist[i[0]]={"SDP":i[1],"CANDIDATE":i[2]}# 成功后发送确认消息socketio.emit('join_response', {"status": "success", "message": f"User {user_id} joined meeting {meeting_id}.","room_participants":dist}, to=request.sid)# 通知所有房间内的客户端更新参与者列表socketio.emit('update_participants', participants_list[meeting_id], room=meeting_id)

image-20241001012453533

{王宇:{Can:“ssss”,Sdp:“sss”},王:{Can:“ssss”,Sdp:“sss”},。。。。。
}

检测断联,从session读取操作对象信息

@socketio.on('disconnect')
def handle_disconnect():user_id = session.get('user_id')meeting_id = session.get('meeting_id')print(f'A client {user_id} has disconnected.')leave_room(meeting_id)# 从数据库中删除参与者connection = connector.connect(**db_config)cursor = connection.cursor()cursor.execute("DELETE FROM participants WHERE meeting_id = %s AND user_id = %s", (meeting_id, user_id))connection.commit()# 通知所有客户端更新参与者列表socketio.emit('update_participants', participants_list[meeting_id], room=meeting_id)

通过以上能简单完成我们想要的效果.

测试并进行二次开发

我先对上面板块进行单元测试

发现没有任何问题,

将其与博客网站进行整体测试,

最终没有问题直接上传代码更新了服务器(2c 1g 30MB),

我们对其进行压测,

在无连接时,内存占用到了700mb

哈哈哈至少还有250mb给我们用

(我这里把 ip 限制关闭和 uwsgi 限制客户端个数关闭了 ,本来只能一个ip五个坑位,这里放开以便测试)

通过python自动构建了客户端与其连接,

当产生到320+客户端的时候,成功崩了

但通过查询内存占用的时候(如下图)

发现还不到20Mb,零头都没到啊,看来不是内存原因

image-20241001014730406

30/8大概在3.8mb/s

大概问题出现在宽带,

但相对传统架构(MCU)真的节省太多昂贵的服务器资源了

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

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

相关文章

Nagle 算法:优化 TCP 网络中小数据包的传输

1. 前言 在网络通信中,TCP(传输控制协议)是最常用的协议之一,广泛应用于各种网络应用,如网页浏览、文件传输和在线游戏等。然而,随着互联网的普及,小数据包的频繁传输成为一个不容忽视的问题。…

828华为云征文 | 云服务器Flexus X实例:向量数据库 pgvector 部署,实现向量检索

目录 一、什么是向量数据库 pgvector ? 二、pgvector 部署 2.1 安装 Docker 2.2 拉取镜像 2.3 添加规则 三、pgvector 运行 3.1 运行 pgvector 3.2 连接 pgvector 3.3 pgvector 常见操作 四、总结 本篇文章通过 云服务器Flexus X实例 部署向量数据库 pgve…

Windows11系统下SkyWalking环境搭建教程

目录 前言SkyWalking简介SkyWalking下载Agent监控实现启动配置SkyWalking启动Java应用程序启动Elasticsearch安装总结 前言 本文为博主在项目环境搭建时记录的SkyWalking安装流程,希望对大家能够有所帮助,不足之处欢迎批评指正🤝&#x1f91…

计算机毕业设计之:音乐媒体播放及周边产品运营平台(源码+文档+讲解)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

Json 在线可视化工具,分享几个

文章目录 1.json.cn2.json4u.cn3.jsonvisual.com4.jsoncrack5.altearius.github.io6.json.wanvb.com 前序:本文是对多种 Json 在线可视化工具 的介绍、分享。Json官网 https://www.json.org/json-en.html 个人比较中意第四款: https://jsoncrack.com/ed…

测试用例的进阶二

1. 按开发阶段划分 1.1 测试金字塔 从上到下,对于测试人员代码就是要求越来越低; 从下到上,越来越靠近用户; 从下到上,定位问题的成本越来越高; 1.2 单元测试(Unit Testing) 单元测试是对软件组成单元进…

uni-app+vue3开发微信小程序使用本地图片渲染不出来报错[渲染层网络层错误]Failed to load local image resource

我把图片放在assets里面页面通过相对路径引入。结果一直报错。 最后我把图片放在static文件夹下面。然后修改路径指向static就可以了 或者是我们必须先import 这个图片然后在使用 import banner1 from ../../assets/images/banner/banner1.png; <image :src"banner…

酒店构建数字化业产业—未来之窗行业应用跨平台架构

一、建设酒店产业数字化 二、酒店数字化产业目标 三、酒店数字化业务指标 四、酒店数字化管理层 五、酒店数字化数据应用 六、酒店数字化子系统 七、酒店数字化分析

Arthas sc(查看JVM已加载的类信息 )

文章目录 二、命令列表2.2 class/classloader相关命令2.2.5 sc&#xff08;查看JVM已加载的类信息 &#xff09;举例1&#xff1a;模糊搜索&#xff0c;xx包下所有的类举例2&#xff1a;打印类的详细信息举例3&#xff1a;打印出类的Field信息 本人其他相关文章链接 二、命令列…

C++ 游戏开发

C游戏开发 C 是一种高效、灵活且功能强大的编程语言&#xff0c;因其性能和控制能力而在游戏开发中被广泛应用。许多著名的游戏引擎&#xff0c;如 Unreal Engine、CryEngine 和 Godot 等&#xff0c;都依赖于 C 进行核心开发。本文将详细介绍 C 在游戏开发中的应用&#xff0…

DC00024基于ssm实验室预约管理系统java web项目web教师预约jsp预约管理系统

1、项目功能演示 DC00024基于web实验室预约管理系统ssm教室预约实验室预约管理系统java web项目MySQL 2、项目功能描述 基于ssm实验室预约管理系统分为用户和系统管理员两个角色。 2.1 系统管理员 1、系统登录 2、用户管理&#xff1a;修改个人信息、修改个人密码、教师管理…

执行力怎么培养?

执行力怎么培养&#xff1f; 并行&#xff1a;适合在初期养成习惯&#xff0c;不抱对结果的期望天才就是强迫症&#xff1a;适合中期修身&#xff1a;适合高级 并行&#xff1a;适合在初期养成习惯&#xff0c;不抱对结果的期望 在你开始做任何事情的时候&#xff0c;不要一开…

单调队列应用介绍

单调队列应用介绍 定义应用场景实现模板具体示例滑动窗口最大值问题描述问题分析代码实现带限制的子序列和问题描述问题分析代码实现跳跃游戏问题描述问题分析代码实现定义 队列(Queue)是另一种操作受限的线性表,只允许元素从队列的一端进,另一端出,具有先进先出(FIFO)的特…

疾风大模型气象,基于气象数据打造可视化平台

引言 随着气象数据的广泛应用&#xff0c;越来越多的行业依赖天气预报与气候分析来做出决策。从农业、航空、能源到物流&#xff0c;气象信息无时不刻影响着各行各业的运作。然而&#xff0c;气象数据本身复杂且多样&#xff0c;如何将这些数据转化为直观、易于理解的图形和信…

【微服务】组件、基础工程构建(day2)

组件 服务注册和发现 微服务模块中&#xff0c;一般是以集群的方式进行部署的&#xff0c;如果我们调用的时候以硬编码的方式&#xff0c;那么当服务出现问题、服务扩缩容等就需要对代码进行修改&#xff0c;这是非常不好的。所以微服务模块中就出现了服务注册和发现组件&…

基于深度学习的乳腺癌分类识别与诊断系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 乳腺癌是全球最常见的癌症之一&#xff0c;早期诊断对于治疗效果至关重要。近年来&#xff0c;深度学习技术在医学图像分析领域取得了显著进展&#xff0c;能够从大量的医学影像数据中自动学习和提…

Vue3.X + SpringBoot小程序 | AI大模型项目 | 饮食陪伴官

gitee平台源码 github平台源码 饮食陪伴师是一个管理饮食的原生大模型小程序&#xff0c;优势&#xff1a; 精确营养监控&#xff1a;用户记录饮食后&#xff0c;我们会计算出食用的营养成分与分量&#xff0c;并反馈给用户。饮食建议有效&#xff1a;大模型经过我们训练具备大…

Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件

Qt 中的 QListWidget、QTreeWidget 和 QTableWidget&#xff1a;简化的数据展示控件 在 Qt 的用户界面开发中&#xff0c;展示和管理数据是常见的需求。Qt 提供了丰富的控件供开发者选择&#xff0c;其中 QListWidget、QTreeWidget 和 QTableWidget 是三个高层封装控件&#x…

程计软考题2-编译、解释程序翻译阶段

(一) 编译器和解释器的工作阶段 1.编译和解释与源程序的区别 分析&#xff1a;编译和解释是语言处理的两种基本方式。 编译过程包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等阶段&#xff0c;以及符号表管理和出错处理模块。 解释过程在词法、语…

【Kubernetes】常见面试题汇总(四十三)

目录 98. kube-apiserver 和 kube-scheduler 的作用是什么&#xff1f; 99.您对云控制器管理器了解多少&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;…