ThinkingF
日拱一卒
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
238-集群聊天服务器为什么要引入负载均衡器
集群聊天服务器为什么要引入负载均衡器我们使用的socketfd本质上是文件描述符,默认大小是1024个,我们通过一个进程,使用limit调大,一台服务器在我们的32位的linux下并发量:2万左右的并发量,单台的chatserver支持2万左右的用户在线聊天,如果要支持3万,4万用户同时在线聊天就不可以了。如果我们想提供我们聊天服务器的并发能力,让更多的用户可以同时在线聊天,我们要进行集群部署。在水平方向上扩展多台主机,每一台主机运行着独立的chatserver;我们在下图中,引入了3台主机,每一原创 2022-05-18 14:15:35 · 257 阅读 · 0 评论 -
268-为什么要用redis作为跨服务器通信的组件 & 为什么各个server不能相互直接进行通信呢?
为什么要用redis作为跨服务器通信的组件 & 为什么各个server不能相互直接进行通信呢???加入现在集群了6台服务器,A和B在不同的服务器上注册的,服务器AB之间肯定要进行消息的转发;如果服务器直接是这样的直接连接,所有的Server既当客户端,也要当服务器;此时的网络拓扑就称这样了:服务器和服务器之间耦合度太高了!为了和检测其他服务器是否正常,需要和其他服务器不断的保持一个心跳!当一个服务器产生故障,其他服务器会花费很大力气和它维持心跳,心跳维持不住了,救护拆除连接!当再增加原创 2022-05-22 13:35:00 · 375 阅读 · 0 评论 -
267-Redis运行不稳定&还有哪些组件可用
1、这个项目中,除了使用redis,你还知道其他组件,能完成同样的功能吗?1.1、redisredis:主业是一个缓存数据库(存储key-value),性能非常好,响应快,低延时;还能实现分布式锁;还能实现发布-订阅功能,我们可以订阅上几个通道channel,然后有人在这个channel上发布消息,所有订阅这个channel的订阅者都可以接收到这个消息;redis还提供了数据持久化的功能,因为本质上数据是在缓存上存储的,为了提高可用性,就算出问题了,数据也是可以恢复的,因为数据是可以落盘的。原创 2022-05-22 13:06:43 · 226 阅读 · 0 评论 -
266-聊天服务器的历史消息存储问题
聊天服务器的历史消息存储问题1、本地消息存储本地消息存储:一对一聊天中,可以在本地程序的目录以好友的QQ号作为文件夹(这个肯定是不会重复的),超过200M,存储到下一个文件,也可以按天存储消息。考虑到安全性,我们可以在存储文件的时候给文件的内容进行对称加密。由好友的QQ号结合一下系统时间,作为默认生成的密钥, 在客户端生成就可以了,直接进行加密,管理起来,方便解密。也可以把历史消息存到数据库SQLite(嵌入式数据库,嵌入到当前进程中,也是一种关系型数据库,支持标准的SQL),可以根据好友的QQ原创 2022-05-22 11:29:03 · 972 阅读 · 0 评论 -
265-聊天服务器和客户端如何保证消息的可靠传输
如何保证消息的可靠传输?意思是: 客户端把消息发送出去了,只要客户端这里显示他的消息发送成功,就要保证对端一定要收到,要么收不到,客户端就显示发送失败,用户后续选择重新发送消息。如果客户端显示消息发送成功,就一定保证对端一定收到这条消息。我们可以在业务层实现消息的确认机制(结合心跳):在消息发送之后对端给予响应。问题: 集群聊天服务器是基于TCP协议实现的,TCP协议本身是可靠的传输协议,在发送数据的时候,有超时重传机制,TCP发送每一个数据的时候,都会等待得到接收方返回的ACK消息确认,它如果得不到原创 2022-05-22 11:20:06 · 331 阅读 · 0 评论 -
261-Server端如何感知客户端的状态
Server端如何感知客户端的状态如果网络拥塞严重,chatserver端如何感知客户端在线还是掉线了?客户端主动发送close(fd),相当于TCP的四次挥手,发送FIN包,进行挥手操作,对应服务端,就有一个响应:recv=0(判断客户端掉线,下线了)这是我们在局域网的聊天服务器里面,网络是良好的,是不会出现问题的。但是,如果放在真实的网络环境中,这个客户端发送的FIN包有可能服务器根本收不到,因为真实的网络环境是非常非常复杂的,有可能现在我们的客户端到服务端的中间网络节点的路由器里面的报文非常原创 2022-05-21 12:46:01 · 477 阅读 · 0 评论 -
260-怎么保证消息在客户端按序显示
怎么保证消息在客户端按序显示?客户端以什么样的顺序发送给服务端消息,服务端就以什么顺序接收这些消息。我实现的集群聊天服务器是跑在局域网上的,局域网的网络没有那么复杂,基本不会出现消息乱序到达,所以没有考虑到实现这个“保证”。如果是在真实的网络环境,要做一个产品,线上的产品,给广大客户使用,这个“保证”是一定要实现的。大家的解决方案如果是给消息添加一个时间戳:甲(客户端),消息是要通过服务端server进行转发。所以,我们要设置成长连接。如果是短连接,类似于http协议,是应用层的协议,原创 2022-05-21 11:17:12 · 1116 阅读 · 0 评论 -
259-数据明文传输的安全问题
数据明文传输的安全问题在集群聊天服务器项目上,是明文的交互,采用的是Json做序列化和反序列化,从登录,注册的基本的业务开始,和后端的服务的交互,全都是明文的交互,相当于在浏览器上去访问web后端是用的https协议,数据确实是非常的不安全;所以我们可以通过加密,传输之前要进行加密,对端接收之后要进行解密。真真正正的项目,客户端和服务器通信:加密算法。用的是对称和非对称的混合加密。1、数据的加密解密1.1、对称加密算法客户端client要给服务器server发送消息,client有一个密钥原创 2022-05-21 10:23:52 · 1288 阅读 · 0 评论 -
254-集群聊天服务器的客户端注销问题
集群聊天服务器的客户端注销问题这个问题是概率性的,这里以老师的进行演示!1、客户端注销问题客户端注销后再次登录,失败了。这种假死的场景在Ubuntu比较小概率,但是在centos大概率会发生。我们gdb去调试看看是什么原因:gdb attach 4207info threads我们的客户端有2个线程:一个专门读(主线程,接收客户端用户的输入,然后发送);一个专门写(子线程,recv接收,打印信息)但是,我们现在看到,这2个线程都在recv:bt //查看函数调用堆栈原创 2022-05-20 16:40:24 · 332 阅读 · 0 评论 -
244-项目一键编译脚本
项目一键编译脚本创建文件名为autobuild.sh的脚本文件:#!/bin/bashset -xrm -rf `pwd`/build/*cd `pwd`/build && cmake .. && make给autobuild.sh赋予 可执行的权限chmod +x autobuild.sh原创 2022-05-19 13:26:03 · 313 阅读 · 0 评论 -
243-ChatServer支持跨服务器通信功能
ChatServer支持跨服务器通信功能我们将redis在项目代码中的添加!1、完善chatservice.hpp我们完善chatservice.hpp#ifndef CHATSERVICE_H#define CHATSERVICE_H#include <muduo/net/TcpConnection.h>#include <unordered_map>//一个消息ID映射一个事件处理 #include <functional>#include &原创 2022-05-19 13:12:40 · 257 阅读 · 0 评论 -
242-redis发布订阅消息队列代码实现
编程中遇到的问题: https://blog.youkuaiyun.com/QIANGWEIYUAN/article/details/97895611?spm=1001.2014.3001.5502redis发布订阅消息队列代码实现redis支持多种不同的客户端编程语言,例如Java对应jedis、php对应phpredis、C++对应的则是hiredis。下面是安装hiredis的步骤:1. git clone https://github.com/redis/hiredis 从github上下载hiredi原创 2022-05-19 11:32:53 · 367 阅读 · 0 评论 -
241-redis发布-订阅相关命令
1、redis环境安装和配置ubuntu命令安装redis服务sudo apt-get install redis-server ubuntu通过上面命令安装完redis,会自动启动redis服务,通过ps命令确认:可以看到redis默认工作在本地主机的6379端口上。启动Redis客户端(老师的)对13这个Channel感兴趣,订阅它!是以阻塞的方式!我们再开一个客户端,现这个13通道发布消息!然后原来客户端就收到信息:继续发:能收到,OK的!服务器登录成功,原创 2022-05-19 10:38:53 · 454 阅读 · 0 评论 -
240-nginx的tcp负载均衡配置
nginx的tcp负载均衡配置负载均衡器:一致性哈希算法单台服务器受限于硬件资源,其性能是有上限的,当单台服务器不能满足应用场景的并发需求量时,就需要考虑部署多个服务器共同处理客户端的并发请求,但是客户端怎么知道去连接具体哪台服务器呢?此时就需要一台负载均衡器,通过预设的负载算法,指导客户端连接服务器。负载均衡器有基于客户端的负载均衡和服务器的负载均衡。普通的基于哈希的负载算法,并不能满足负载均衡所要求的单调性和平衡性,但一致性哈希算法非常好的保持了这两种特性,所以经常用在需要设计负载算法的应用场原创 2022-05-18 17:52:28 · 328 阅读 · 0 评论 -
239-如何解决集群聊天服务器跨服务器通信
如何解决集群聊天服务器跨服务器通信我们在集群聊天服务器中涉及的通信是:一对一的聊天群聊我们看上图,client1登录在chatserver1上,client2登录在chatserver2上,client3登录在chatserver3上;按我们现有的单台服务器业务来说,当client1给client2发送聊天消息的话,我们在每一台服务器上都有_userConMap,在chatserver1上的_userConMap肯定是找不到client2的connection;所以,在集群环境中,我们服原创 2022-05-18 16:36:44 · 422 阅读 · 0 评论 -
227-集群聊天服务器的客户端开发 & 测试
集群聊天服务器的客户端开发我们之前把聊天服务器的代码基本上功能开发完了,在后面转成集群版本的时候要引入中间件-基于发布订阅的Redis。现在我们先开始客户端的开发我们聊天服务器项目工程的客户端和服务器会共用很多代码,所以把他们放在集成编译环境中有很大的优势。当客户端和服务器共享头文件,可以同步修改,修改一份都是可见的。为了减少服务器的压力,这种好友列表群组列表一般是在客户端存储的。如果从服务端拉回,返回数据挺多的,压力挺大的1、客户端开发我们在src下创建一个文件夹:client我们完善原创 2022-05-17 13:03:45 · 392 阅读 · 0 评论 -
228-服务端注销业务
服务端注销业务1、完善public.hpp我们完善public.hpp#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件*/enum EnMsgType{ LOGIN_MSG = 1,//登录消息 LOGIN_MSG_ACK,//登录响应消息 LOGINOUT_MSG,//注销消息 REG_MSG,//注册消息 REG_MSG_ACK,//注册响应消息 ONE_CHAT_MSG,//聊原创 2022-05-17 10:55:42 · 164 阅读 · 0 评论 -
222-群组业务
群组业务1、群组业务介绍群组业务包含:管理员创建群组员加入群群聊群组里面包含组员,一个组员可以在多个群组,一个群组可以有多个组员(多对多的关系,需要有一张中间表GroupUser,体现user和群的隶属关系)2、group.hpp我们在include下的server下的model下创建文件:group.hpp#ifndef GROUP_H#define GROUP_H#include "groupuser.hpp"#include <string>#includ原创 2022-05-16 12:33:38 · 673 阅读 · 0 评论 -
221-添加好友业务代码和测试
添加好友业务代码和测试在mysql数据库有Friend表表中两个字段,一个是用户id,一个是用户的friend的id,这种关系不用写多次,所以用联合主键(id和friendid可以单独重复,联合主键不可以重复); 我跟你是好友写一遍就可以了。我把你添加好友,服务器会给我返回好友列表信息,然后我根据列表上的用户的id号进行聊天。1、完善public.hpp我们完善public.hpp#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件原创 2022-05-16 10:30:03 · 1000 阅读 · 0 评论 -
217-服务器异常退出处理代码和测试
服务器异常退出处理代码和测试在之前,我完成看客户端异常退出的处理代码,客户端异常退出是因为它没有发出json字符串,是通过连接异常断开进行用户的connection的删除和用户表状态的更改。但是服务器异常退出了,user表的用户的状态还是online,这个问题还没有解决。因为我们Ctrl C强制退出服务器的时候,服务器根本没有机会去数据库里更改用户的状态信息。1、main.cpp我们完善src下的server下的main.cpp#include "chatserver.hpp"#inclu原创 2022-05-15 13:49:54 · 299 阅读 · 0 评论 -
216-离线消息业务代码和测试
离线消息业务代码和测试在我们的数据库中,我们有专门一个表来存储离线消息(OfflineMessage表)1、offlinemessagemodel.hpp我们在include的server下的model文件夹里创建文件:offlinemessagemodel.hpp#ifndef OFFLINEMESSAGEMODEL_H#define OFFLINEMESSAGEMODEL_H#include <string>#include <vector>using na原创 2022-05-15 12:20:44 · 215 阅读 · 0 评论 -
215-对点聊天业务代码和测试
对点聊天业务代码和测试在一对一的聊天业务中,发送过来的json数据都包含了哪些字段?1、完善一下public.hpp首先我们完善一下public.hpp#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件*/enum EnMsgType{ LOGIN_MSG = 1,//登录消息 LOGIN_MSG_ACK,//登录响应消息 REG_MSG,//注册消息 REG_MSG_ACK,// 注册响应消息原创 2022-05-15 11:22:51 · 165 阅读 · 0 评论 -
214-客户端异常退出业务代码和测试
我们要处理一下客户端的异常退出,客户端在没有任何响应的情况下,直接给异常退出了,它在目前的代码下,退出没有合法的json字符串,json请求,而只是网络连接断开了,我们还要修改用户的状态为offline。客户端异常退出业务代码和测试1、完善chatserver.cpp如果客户端异常退出,它根本就没有发出合法的json消息,而是直接断开连接了。所以,在这里,我们专门写一个方法。//上报链接相关信息的回调函数void ChatServer::onConnection(const TcpConnec原创 2022-05-15 10:26:25 · 210 阅读 · 0 评论 -
213-记录用户的连接信息和线程安全问题
假设有2个用户,用户1把它的id号和要说的内容发过去,服务器要主动地去给用户2推送这个消息,但是用户2又不知道什么时候谁会给他说话,他不可能去服务器上拉取消息,所以这个聊天 肯定得是服务器推送给用户2,所以聊天服务器也必须是长连接,不仅仅是客户端请求,服务端被动接收,而且服务端还要主动推送消息到客户端,所以我们拿到用户2的id号,怎么知道这个用户的连接connection在哪里,所以,我们在业务层要想办法,一个用户一个connection,登录成功,连接就建立成功了,这个连接就可以存储下来。记录用户的.原创 2022-05-15 06:07:12 · 146 阅读 · 0 评论 -
212-用户登录业务代码和测试
1、public.hpp我们先完善一下public.hpp#ifndef PUBLIC_H#define PUBLIC_H/*server和client的公共文件*/enum EnMsgType{ LOGIN_MSG = 1,//登录消息 LOGIN_MSG_ACK,//登录响应消息 REG_MSG,//注册消息 REG_MSG_ACK,//注册响应消息};#endif...原创 2022-05-14 23:52:22 · 309 阅读 · 0 评论 -
211-用户注册业务代码和测试
1、chatservice.hpp我们先完善chatservice.hpp#ifndef CHATSERVICE_H#define CHATSERVICE_H#include <muduo/net/TcpConnection.h>#include <unordered_map>//一个消息ID映射一个事件处理 #include <functional>using namespace std;using namespace muduo;using nam原创 2022-05-14 22:41:56 · 279 阅读 · 0 评论 -
203-Model数据层代码框架设计
1、Model数据层代码框架设计数据库的操作和业务代码分离开在业务层看到对象,在数据库层看到数据库的操作。我们要定义相关的一些类,和数据库的表一一对应的,才能把数据库读出来的字段合成一个对象提供给业务方去使用!映射类!(业务层直接操作映射类,就不需要具体操作sql了)2、user.hpp我们在inlcude的server下创建一个文件夹:model首先我们在model文件夹下创建文件:user.hpp#ifndef USER_H#define USER_H#include <原创 2022-05-13 23:41:23 · 241 阅读 · 0 评论 -
199-MySQL数据库代码封装
我们在上一节中把网络模块和业务模块的代码通过事件回调完全地拆分开。现在我们需要把业务模块的和数据层的代码区分开。不在业务模块出现数据库的增删改查,增加中间的一层类。原创 2022-05-13 23:14:43 · 198 阅读 · 0 评论 -
194-完成业务模块代码ChatService &和网络模块耦合度降级处理
1、完成业务模块代码ChatService我们怎么把网络模块收到的消息派发到业务模块,服务模块。让网络模块的代码和业务模块的代码完全解耦?假设一个用户在做登录业务,messageid,name,passwd1.1、chatservice.hpp我们在include下的server创建头文件:chatservice.hpp#ifndef CHATSERVICE_H#define CHATSERVICE_H#include <muduo/net/TcpConnection.h>#i原创 2022-05-11 23:28:35 · 150 阅读 · 0 评论 -
193-网络模块代码ChatServer
1、ChatServer.hpp首先,我们在include下的server下创建头文件:chatserver.hpp#ifndef CHATSERVER_H#define CHATSERVER_H#include <muduo/net/TcpServer.h>#include <muduo/net/EventLoop.h>using namespace muduo;using namespace muduo::net;//聊天服务器的主类class ChatSe原创 2022-05-11 21:47:19 · 204 阅读 · 0 评论 -
192-基于muduo和nginx的集群聊天服务器的项目工程构建
1、项目工程目录我们的聊天服务器程序和客户端程序都在一个工程里面,最后在bin生成2个可执行文件,一个是服务器,一个是客户端。2、配置chatserver(根)下的CMakeLists.txt# 入口CMakeLists.txtcmake_minimum_required(VERSION 3.0)project(main) #给工程一个名字# 配置编译选项set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 配置最终的可执行文件输出的路径set原创 2022-05-11 20:42:30 · 186 阅读 · 0 评论 -
191-MySQL环境搭建和编程和项目表的设计
1、MySQL环境安装设置ubuntu环境安装mysql-server和mysql开发包,包括mysql头文件和动态库文件,命令如下:sudo apt-get install mysql-server =》 安装最新版MySQL服务器sudo apt-get install libmysqlclient-dev =》 安装开发包ubuntu默认安装最新的mysql,但是初始的用户名和密码是自动生成的,按下面步骤修改mysql的root用户密码为123456;【step 3】重新用root和12原创 2022-05-11 19:30:38 · 153 阅读 · 0 评论 -
186-CMake构建集成编译环境
1、CMake简介使用简单方便,可以跨平台,构建项目编译环境。尤其比直接写Makefile简单(在构建大型工程编译时,需要写大量的文件依赖关系),可以通过简单的CMake生成负责的Makefile文件。2、CMake安装ubuntu上直接执行 sudo apt install cmake 安装完可以通过cmake -version查看其版本:3、CMake在Ubuntu的VScode安装插件4、CMake使用介绍cmake命令会执行目录下的CMakeLists.txt配置文件里面的配置原创 2022-05-10 23:49:32 · 396 阅读 · 0 评论 -
182-muduo网络库(陈硕)编程
1、muduo网络库编程muduo网络库的底层就是epoll加linux的pthread线程库。所以muduo库只能装在linux环境中。muduo网络库的安装:https://blog.youkuaiyun.com/QIANGWEIYUAN/article/details/89023980我们在做项目的时候,服务器一定要做到高并发,要用到muduo库。但是客户端只是向服务器请求服务,不需要高并发的性能要求。2、基于muduo的客户端服务器编程muduo网络库的编程很容易,要实现基于muduo网络库的服原创 2022-05-10 00:51:04 · 1779 阅读 · 0 评论 -
181-Json的介绍和使用
1、Json的介绍和使用Json是一种轻量级的数据交换格式(也叫数据序列化方式)。Json采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 Json 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。也就是说,客户端如果是C++写的,服务器是Java写的,没关系,大家都认识Json,虽然在整个网络中,不同的部件是不同的语言开发的,但是都认识Json,所以大家之间用Json交流就可以了,不管是什么语言开发的,你想把数据发给我,你原创 2022-05-10 00:06:21 · 574 阅读 · 1 评论 -
180-基于muduo和nginx的集群聊天服务器
项目的命名chatserver技术栈Json序列化和反序列化muduo网络库开发nginx源码编译安装和环境部署nginx的tcp负载均衡器配置redis缓存服务器编程实践基于发布-订阅的服务器中间件redis消息队列编程实践MySQL数据库编程CMake构建编译环境Github托管项目项目需求客户端新用户注册客户端用户登录添加好友和添加群组好友聊天群组聊天离线消息nginx配置tcp负载均衡集群聊天系统支持客户端跨服务器通信开发环境ubuntu18.原创 2022-05-09 21:00:27 · 304 阅读 · 0 评论
分享