简介
项目第一季完结了,本文做一个整理,介绍面试将被问到的相关问题和技术难点,以及第二季将涉及的开发内容。
下面先介绍项目如何描述。
项目如何描述
按照HR搜索简历的方式,基本都是采用关键字搜索,所以要在简历中暴露项目中的技术亮点。
为了让面试官通过简历快速的了解项目和采用的技术,需在项目介绍时融入技术细节,让项目描述更饱满一点。
可增加个人业绩或者个人成长,让面试官了解到项目的意义等。
所以综上所述,简单做个总结,一个项目的描述需包含如下几点:
- 项目描述
- 技术亮点
- 项目价值
项目描述
这是一个全栈的即时通讯项目,前端基于QT实现气泡聊天对话框,通过QListWidget
实现好友列表,利用GridLayout
和QPainter
封装气泡聊天框组件,基于QT network
模块封装http
和tcp
服务。支持添加好友,好友通信,聊天记录展示等功能,仿微信布局并使用qss
优化界面
后端采用分布式设计,分为GateServer
网关服务,多个ChatServer
聊天服务,StatusServer
状态服务以及VerifyServer
验证服务。
各服务通过grpc
通信,支持断线重连。GateServer
网关对外采用http
服务,负责处理用户登录和注册功能。登录时GateServer
从StatusServer
查询聊天服务达到负载均衡,ChatServer
聊天服务采用asio
实现tcp可靠长链接异步通信和转发, 采用多线程模式封装iocontext
池提升并发性能。数据存储采用mysql服务,并基于mysqlconnector
库封装连接池,同时封装redis
连接池处理缓存数据,以及grpc
连接池保证多服务并发访问。
经测试单服务器支持8000连接,多服务器分布部署可支持1W~2W活跃用户。
技术点
asio 网络库,grpc,Node.js,多线程,Redis, MySql,Qt 信号槽,网络编程,设计模式
项目意义
关于项目意义可结合自身讨论,比如项目解决了高并发场景下单个服务连接数吃紧的情况,提升了自己对并发和异步的认知和处理能力等。
考察点
1 如何利用asio实现的tcp服务
利用asio 的多线程模式,根据cpu核数封装iocontext连接池,每个连接池跑在独立线程,采用异步async_read
和assync_write
方式读写,通过消息回调完成数据收发。整个项目采用的网络模式是Proactor模式,每个连接通过Session类管理,通过智能指针管理Session,b保证回调之前Session可用,底层绑定用户id和session关联,回调函数可根据session反向查找用户进行消息推送。客户端和服务器通信采用json, 通过tlv方式(消息头(消息id+消息长度
)+消息内容)封装消息包防止粘包。通过心跳机制检测连接可用性。
2 如何保证服务高可用
- 故障检测与自动恢复:
- 实施监控系统,实时检测服务的健康状况。
- 配置自动重启或故障转移机制,确保在故障发生时能够迅速恢复服务。
- 分布式架构:
- 采用微服务架构,将应用拆分为多个独立的服务,降低单个服务故障对整体系统的影响。
- 数据备份与恢复:
- 定期备份数据,并进行恢复演练,确保在数据丢失或损坏时能够快速恢复。
- 多活部署:
- 在不同地理位置部署多个活跃的数据中心,确保在某个数据中心发生故障时,其他数据中心可以继续提供服务。
3 为何封装Mysql连接池
首先多个线程使用同一个mysql连接是不安全的,所以要为每个线程分配独立连接,而连接数不能随着线程数无线增加,所以考虑连接池,每个线程想要操作mysql的时候从连接池取出连接进行数据访问。
Mysql连接池封装包括Mgr管理层和Dao数据访问层,Mgr管理层是单例模式,Dao层包含了一个连接池,采用生产者消费者模式管理可用连接,并且通过心跳定时访问mysql保活连接。
4 如何测试性能
测试性能分为三个方面:
压力测试,测试服务器连接上限
测试一定连接数下,收发效率稳定性
- 采用pingpong协议,收发效率稳定在10ms下,连接数上限
压力测试,看服务器性能,客户端初始多个线程定时间隔连接,单服务节点连接上限2w以上稳定连接,并未出现掉线情况
测试稳定性,单服务节点连接数1W情况下,收发稳定未出现丢包和断线,并且延迟稳定在10ms
保证10ms延迟情况下,增加连接数,测下连接数上限,这个看机器性能,8000~2W连接不等。
5 用到哪些设计模式和思想
- Acto模式,逻辑解耦
- 生产者消费者模式(涉及线程池)
- 单例模式(网络管理和数据库管理类)
- RAII思想(defer 回收连接)
- 代理模式(数据库,redis等通过代理对接应用层调用,底层线程池隐藏技术细节)
- MVC控制思想,客户端通过MVC三层结构设计
- 线程分离,网络线程,数据处理线程,以及UI渲染线程分离
- 心跳服务
- 数据序列化压缩发送(Protobuf,Json)
- 队列解耦合,服务器采用发送队列保证异步顺序,通过接受队列缓存收到数据,通过逻辑队列处理数据。
- 分布式设计,多服务通过grpc通信,支持断线重连
- C++11 现代化技术,智能指针,伪闭包,模板类型推导,线程池,future, promise等
6 描述线程池封装
描述线程池封装,线程池采用C++ 11 风格编写,整体来说线程池通过单例封装,内部初始化N个线程,采用生产者消费者方式管理线程,包含任务队列,任务队列采用package_task打包存储,提供对外接口commit提交任务,采用bind语法实现任务提交在commit内部自行绑定,通过智能指针伪闭包方式保证任务生命周期。同时使用C++ 11 future特性,允许外部等待任务执行完成。
7 为什么要设计心跳?
在网络情况下,会出现各种各样的中断,有些是网络不稳定或者客户端主动断开连接,这种服务器是可以检测到的。
PC拔掉网线,还有一种情况客户端突然崩溃,有时候服务器会检测不到断开连接,那么你这个用户就相当于僵尸连接。
当服务器有太多僵尸连接就会造成服务器性能的损耗。
另外心跳还有一个作用,保证连接持续可用,比如mysql,redis这种连接池,如果不设计心跳,
时间过长没有访问的时候连接会自动断开。
第二季待完成内容
第二季半年后开发并更新视频
待开发内容
未实现资源服务器及断点续传
客户端和聊天服务的心跳机制
实现断线重连和踢人操作(未完全实现,目前仅支持客户端重新登录,服务器重新绑定连接,原连接未踢掉)
未完整实现用户离线后数据清空操作
客户端未实现用户信息编辑,头像上传等UI和逻辑
未实现文件,图片,语音等信息传输
未实现语音,视频实时通信,涉及音视频编程
赞赏
感谢支持