[集群聊天服务器]----(一)项目简介

avatar
作者
筋斗云
阅读量:1

在最近的学习中,实现了基于muduo网络库的集群聊天服务器,在此做一个剖析以及相关内容的梳理介绍,希望可以帮助到大家。
这一篇,先来简单介绍一下这个项目。

源码地址

Cluster_Chat_System-项目

项目技术特点

  • 使用C++开发并基于 muduo 网络库开发网络核心模块,实现高效通信
  • 封装 MySQL 接口,将重要的用户数据储存到磁盘中,实现数据持久化
  • 使用第三方 JSON 库实现通信数据的序列化和反序列化
  • 使用 Nginx 的 TCP 负载均衡功能,将客户端请求以轮询的方式派发到多个服务器上,提高了并发处理能力
  • 基于发布-订阅的服务器中间件redis消息队列,解决客户端之间跨服务器通信难题
  • 基于 CMake 构建项目

项目需求

  1. 客户端新用户注册,用户登录
  2. 添加好友和添加群组
  3. 好友聊天以及群组聊天
  4. 存储以及显示离线消息
  5. 利用nginx配置tcp负载均衡,提高并发量
  6. 集群聊天系统支持客户端跨服务器通信

项目开发环境

  1. Linux环境 CentOS7
  2. 安装json第三方开发库 Linux下安装JSON的步骤以及JSON是什么
  3. 安装boost以及muduo网络库开发环境,注意,gcc/g++编译器必须保证在5.4 - 7.8版本之间,并且因为muduo是libmuduo_xx.a静态链接库,链接阶段直接合并到可执行文件中的,如果原先安装编译过muduo库,升级完gcc,需要把muduo重新源码编译安装一下,建议在安装之前就升级g++版本 有关安装步骤请看Linux平台下muduo网络库源码编译安装与测试,包含boost库的安装与测试!!!!
  4. 安装redis环境 Linux下安装redis并配置开机自启保姆级教程-----附带每一步截图
  5. 安装mysql数据库 Linux安装MySQL(超详细)
  6. 安装nginx Linux系统下安装配置nginx—附带每一步截图
  7. 安装CMake环境Linux下安装CMake的方法

开发环境

vscode在linux环境下直接开发 VSCode - 使用VSCode远程连接到Linux并实现免密码登录

MySQL数据库表格设计

在这里插入图片描述
关于表的配置,以user为例Mysql基础—创建数据库以及表,附带截图

业务模块简介

注册模块

从网络模块接收数据,根据 msgid 定位到注册模块。从传递过来的 json 对象中获取用户 ID 和用户密码。并以此生成 User 对象,调用 model 层方法将新生成的 User 插入到数据库中。

登录模块

从 json 对象中获取用户ID和密码,并在数据库中查询对比获取用户信息是否匹配。如果用户已经登录过或者账号密码错误,返回错误信息。登录成功后更改用户表中用户状态,并显示该用户的好友列表群组列表以及收到的离线消息。

客户端异常退出模块

客户端异常退出了,从服务端记录用户连接的表中找到该用户,如果它断连了就从此表中删除,并设置其状态为 offline。

服务端异常退出模块

服务端异常退出(捕捉到CTRL + C ),将所有在线的客户的状态都设置为 offline。使用了 Linux 的信号处理函数,向信号注册回调函数,然后在函数内将所有用户置为下线状态。

一对一聊天模块

通过传递的 json 查找对话用户 ID:
用户处于同一台服务器并且处于登录状态:直接向该用户发送信息
用户不在同一台服务器,在redis查找,处于登录状态:向该用户发送信息
用户处于离线状态:存储离线消息

添加好友模块

从 json 对象中获取添加登录用户 ID 和其想添加的好友的 ID,调用 model 层代码在 friend 表中插入好友信息。

群组模块

创建群组需要描述群组名称,群组的描述,然后调用 model 层方法在数据库中记录新群组信息。加入群组的用户需要给出用户 ID 和想要加入群组的 ID,并显示显示该用户是群组的普通成员还是创建者。

群组聊天

给出群组 ID 和聊天信息,
群内成员用户处于同一台服务器并且处于登录状态:直接向该用户发送信息
群内成员用户不在同一台服务器,在redis查找,处于登录状态:向该用户发送信息
群内成员用户处于离线状态:存储离线消息

Nginx负载均衡模块

假设一台机器支持两万的并发量,现在我们需要保证八万的并发量。但是单台机器的性能是有限的,即使我们升级服务器的配置,(提高 CPU 执行频率,加大内存等提高机器的物理性能),也无法达到并发量。所以需要增加服务器的数量,将用户请求分发到不同的服务器上分担压力,这就是负载均衡。就需要有一个第三方组件充当负载均衡器,由它负责将不同的请求分发到不同的服务器上。而本项目,我们选择 Nginx 的负载均衡功能。
相关配置,会在Nginx模块中给出。

负载均衡模块需要实现三个功能
  1. 把client的请求按照轮询算法分发到服务器ChatServer上
  2. 能够和ChantServer保持心跳机制,及时检测ChatServer故障,确保不会分发到故障机上
  3. 及时发现新添加的ChatServer设备,方便扩展服务器数量,不需要停止服务器

redis发布-订阅功能解决跨服务器通信问题

使用集群服务器,有多个服务器维护自己的用户列表。ChatServer1与ChatServer2的用户聊天,ChatServer1在自己服务器的用户表中找不到,但是可能用户在线,所以我们需要保证跨服务器间的通信!但是如果让后端的服务器之间互相连接,让各个ChatServer服务器互相之间直接建立TCP连接进行通信,相当于在服务器网络之间进行广播。ChatServer维护了一个连接的用户表,每次向别的用户发消息都会从用户表中查看对端用户是否在线。然后再判断是直接发送,还是转为离线消息。这样的设计使得各个服务器之间耦合度太高,不利于系统扩展,并且会占用系统大量的socket资源,各服务器之间的带宽压力很大,不能够节省资源给更多的客户端提供服务,并且存在一个服务器瘫痪其余都崩溃的情况,不采用。
所以引入中间件消息队列,解耦各个服务器,使整个系统松耦合,提高服务器的响应能力,节省服务器的带宽资源,在集群分布式环境中,经常使用的中间件消息队列有ActiveMQ、RabbitMQ、Kafka等,都是应用场景广泛并且性能很好的消息队列,供集群服务器之间,分布式服务之间进行消息通信。但是本项目业务类型并不是非常复杂,对并发请求量也没有太高的要求,因此我们的中间件消息队列选型的是-基于发布-订阅模式的redis。

好了~关于Cluster_Chat_System项目简介就到此结束了,下一篇我们将正式开始剖析代码实现具体功能!感兴趣的伙伴们可以按照步骤按照好环境,一步一步跟着来哦 ~ 写在最后,小白一枚,希望看到错误的各位大佬批评指正 ~ ~

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!