Bootstrap

集群聊天服务器面试问题

数据明文安全问题

可以对数据库进行加密。如果是明文传输,就要用密文传输,传输之前要做加密,对端接收要做解密。但是做项目的时候没有引入加密解密的一个算法,具体实现还需要借鉴资料。
加密解密一种是对称加密,还有一种是非对称加密。对称加密算法就是客户端随机生成了一个密钥key,把login账号密码加密成密文,这样网络上有人抓包就不能破解。然后服务端解密需要密钥。用的是同一个钥匙,那就是对称加密。密钥不能在网络上传输,因为也会被抓取。所以使用密钥的对称加密,也存在安全问题。主要还是效率比较高(AES加解密算法)。非对称加密(xxxx.pub公钥、xxxx.pri私钥)公钥只能由私钥解出来。加密复杂效率慢,但是很安全。(RSA加解密算法)

历史消息存储

好友的qq号作为文件夹,好友的QQ号作为文件夹,给文件夹规定一个大小,或者按天存储。
这个文件夹id设计在数据库中。存储文件的时候做一个加密操作。具体表的设计
而且消息不能都往Mysql里存,因为存的越来越多,mysql会变慢。所以半年前的需要拿出来放到文件服务器上,换机器存储,因为不会频繁访问。

简要说一下项目

准备一个2-3分钟的项目简介
我这个项目是一个网络服务器的项目,他分为了四个模块,网络模块,我采用的是Muduo库,他的好处就是能够解耦了网络模块与业务模块的代码,能够让开发者专注于业务代码的开发。然后传输层用了C++11的技术,比如map、绑定器、消息发送以后的回调机制,从消息中取得消息Id,通过回调来处理消息。数据存储层用了mysql,比如用户账号、群组id、聊天消息、离线消息。单机服务下就是这几个模块,但是他的并发能力是有限的,所以在这里考虑了快速地能够提升服务器的整个项目的并发能力,能够支持项目的扩展,要支持多台服务器的话,首先需要挂一个nginx的负载均衡,因为主要是基于TCP的长连接。在负载均衡中,因为不同服务器有不同的人进行注册,如果不同服务器上的人需要进行通信的话,主要是引入了redis的MQ消息队列的一个功能,能够发布订阅,来完成跨服务器的通信。

自我介绍

上来要先做一个2-5分钟的自我介绍,看语言表达能力。开发工作中,只有20%的时间在做开发,其他时间都在开会议讨论方案。1、基本情况()。2、喜欢开发(看什么书,C++ Primer、计算机网络、操作系统原理),然后我还经常上github、csdn、bilibili这些技术类的网站看或者去提问题。而且我喜欢边学习边在CSDN写博客。我对于开发工作,希望自己能够积累工作经验和技术经验,能够在公司岗位上发挥自己的价值,希望能越走越高。
表达逻辑、自学能力的介绍、未来工作计划这三个方面

怎么保证消息的可靠传输

如果收不到,客户要显示发送失败。需要在业务层实现消息的确认机制。基于TCP实现,那为什么TCP的消息确认机制不能保证消息的可靠传输。业务上的可靠传输不能通过协议上的超时重传来实现,
面试官的问题不一定都是正确的,不要有学生心态,和面试官是对等的,讨论问题的。先看看问题有没有提的道理。用户不能知道底层的情况,所以还得在业务上实现。
心跳机制,01之间徘徊,发送1,收到ACK就减1为0。心跳给了客户端与服务器的一个状态,心跳失败,就说明服务器不可用了,直接显示发送失败。

如何实现消息在客户端按序显示

消息添加时间戳,然后排序,这种排序是有瑕疵的。排序需要规定一个时间周期,只能在这个时间周期内进行排序。
解决方法是给每一个消息都添加一个序列号,查找本地缓存中序列号,找到一条就加一查找下一条。序列号不仅仅可以保证消息的按序到达,还可以实现其他功能,消息撤回。甲的撤回请求,要撤回seq多少的消息,然后发给服务器,然后服务器推送撤回消息的请求,找到seq那个消息。而且每一台服务器时间不一样。用时间戳不可靠。

除了redis,还有哪些组件,能完成

redis:缓存数据库 key-value、数据持久化,
分布式锁,发布订阅功能 channel
服务器中间件:带有发布订阅的MQ消息队列,
kafka、zeromq、rebbitmq、rocketmq这些都能实现高并发的消息队列

redis运行不稳定,挂了的话怎么办?

流量,后续的订单直接不处理了,不能因为订单请求把自己的服务搞挂了,肯定是得不偿失的。不要潜意识认为redis不稳定的,

为什么用redis作为跨服务器的组件,为什么各个server不能直接通信呢?

这种网络拓扑设计耦合性太高,这样的业务实现问题很大而且不稳定。新增加一个服务器就要和其他所有服务器直连。服务器就和客户端差不多。如果用redis,服务器就不需要感知其他服务器的状态。增加服务器也不需要别人知道你来了,

如果网络拥塞严重,服务端如何感知客户端在线还是掉线了。

connect成功的client分配一个心跳计数。服务端启动一个心跳计时器,超时1s,把所有账号的心跳计数+1。如果账号的心跳计数超过5,就判定client已经掉线了。超过5的话就拆除这个client所有的连接以及其它资源。服务端接收到一次客户端的消息(MSG_TYPE:heartbeat),就会把计数减1。如果网络拥塞严重,心跳机制超过5就会感知到下线了。
传输层keepalive的功能,每隔7200s会发送一个探测的报文段,如果对方回复了,那说明对方在线,如果并没有响应,那就延迟75s继续发送探测包。依旧没有响应,最多重新探测9次,如果都没有响应,拆除连接。传输层的上边是应用层(心跳机制),应用层已经死锁了,应用层的socket,传输层依然可以和对方发送keepalive。应用层死锁无法交互消息,客户端死锁,传输层有可能还是会发送消息的。所以说只有传输层的TCP的keepalive是没有办法保持长连接的,要保证业务,所以在应用层需要有心跳机制。TCP的超时重传,可能业务层还是因为别的原因无法执行业务。

;