问题汇总
项目问题汇总
一、客户端消息如何按序显示?
先讲用时间戳来解决的缺点,再讲用序列号实现。
每一条消息添加序列号seq
二、怎么保证消息的可靠传输
-
业务层实现消息确认机制
-
为什么tcp的消息确认机制不能保证消息可靠传输
三、这个项目中,除了使用redis,你还知道其它组件吗?能完成同样的功能吗?
首先redis是一种缓存数据库,基于key-value模式的,其次主要功能:
- 数据持久化
- 分布式锁
- 发布-订阅功能
其他服务器中间件:
- MQ消息队列
- kafka:高并发、高可用、
- zeromq
- rabbitmq
- rocketmq
- .......
四、为什么要用redis作为跨服务器通信的组件?为什么各个server不能相互直接进行通信呢?
假设用户登录在不同的服务器上,那么各个用户之间互相发送消息就需要服务器转发这个消息,这样每台服务器就需要和其他服务器保持一个心跳连接机制,来确认对方的状态,每台服务器既当客户端,又当服务器。当有一个新的服务器加入集群时,每台服务器都要与其建立心跳,当有一个服务器挂掉,每台服务器都要与其删除连接,这样的设计非常糟糕,整个网络拓扑非常复杂混乱。而解决的方法是引入一个中间件,这样每个服务器就不用感知其它服务器的状态,解耦了各个服务器之间的关系,网络拓扑关系简单明了。
五、如果网络拥堵,server端怎么感知客户端状态?
心跳机制
六、历史消息存储
本地消息存储
- 用账号作为文件夹,内容加密存储
- 按存储的数据大小分文件存储
- 按天存储
云消息存储
mysql存储,当数据过大时我们dump到一个文件服务器上,存到磁盘上
七、项目介绍
我的这个聊天集群服务项目是一个网络服务器的项目,它分为了四个模块。
第一个模块是网络层,这里我采用的是moduo库来设计的,它是一个性能非常不错的网络开源库,它的好处就是解耦了网络模块和业务模块的代码,能够让我更专注与业务的开发。
那第二个模块呢是服务层,服务层这块呢我用了一些C++11的技术,比如Map、bind绑定器,我主要是设计了一个消息id,以及这个消息发生以后的回调操作绑定,就是一个回调机制。当我的网络层的网络I/O吐出来一个消息请求的话,通过对这个消息请求进行json解析得到消息id,然后通过回调处理这个消息对应的事件。
第三个模块是数据存储层,我用了MySQL。对于我项目里的一些关键的数据,进行了一些的落地。比如说用户的账号啊、还有离线的消息,比如说一些好友的列表,还有群组的一些列表关系都是在MySQL里进行存储的。
最后一个模块是负载均衡层。单机服务下,主要就是这几个模块,但是单机服务下它的并发能力是有限的,所以这里我考虑了如何快速提升项目的并发能力 ,让项目能支持一个多机的拓展。要部署多台服务器的话我就需要支持nginx的负载均衡,因为我的这个项目主要是基于tcp私有协议自己搭建的C/S模型的通信,所以是基于nginx负载均衡,然后做一个长连接,因为我是消息聊天通信,客户端不仅仅要给服务器发消息,服务端也要主动给客户端推送消息 ,这样就必须是一个长连接,短连接它做不到,短连接它服务器没办法给客户端推消息。然后,另外呢在负载均衡里边呢,因为我是各个服务器它有不同的人注册,那不同服务器上注册的用户需要进行通信的话,我这里边主要是引入了redis作为一个MQ消息队列的功能,利用他的发布-订阅功能,实现了一个跨服务器的通信功能。
以上就是我的项目的大概介绍。
八、项目数据传输安全问题
如果是明文传输的话要考虑的肯定就是做密文传输,密文传输的话就要引入一种加密-解密的算法机制了,传输之前进行加密,接收以后进行解密。但是我之前呢,由于做项目的过程中对于加解密这一块没有考虑的非常完全,所以呢没有去自己实现引入过加密-解密算法在项目中,所以对于这一块的具体实现方案我应该是思路是没有问题的,但是具体怎么实现我可能还要去借鉴一些资料去,具体实现一些demo我才能够完全清楚。
- 对称加密
- 非对称加密
九、redis运行不稳定,挂了的话怎么办?
其实这个世界上没有哪个服务是绝对不会挂的,一般我们会配置一些参数阈值来防止其挂掉,比如说内存的使用量、消息的存储量。超过这个阈值的话我们就直接丢弃这些额外的处理不了的数据。就像哪些秒杀系统的话,短时间内会产生无数的订单,如果所有订单我们后端都要进行处理的话,那肯定是会让后端的Mq消息队列负载不过来的。因此一般系统也会规定一定的阈值,超过这个阈值,后续的订单就不处理了。不可能是个请求过来我就处理,那短时间、高并发、大流量的情况,我不能说是为了处理请求就把我后端个搞挂了,这是得不偿失的。
注意: