高并发webserver_interview
- 整体介绍一下项目
首先这个项目是基于⾼并发架构设计的⽂件存储与共享系统,项⽬有四层架构,分别为客户端-代理层-接⼝服务层-存储层。客户端这⼀层⾯,通过HTTP协议可以发起注册、登录、⽂件上传下载、分享列表等请求。代理层由Nginx + fastdfs-nginx-module的⽅式处理⽂件流和访问。接⼝服务层实现了多reactor多线程的⽹络模型,主reactor负责接收连接和分发连接给subReactor,subReactor通过封装好的epoll来对具体连接进⾏io处理,对客户端的请求进⾏反序列化解析,实现注册、登录、上传⽂件、⽂件列表展示、共享⽂件、下载⽂件,删除⽂件等功能。存储层中使⽤MySQL管理⽤户及⽂件元数据,redis缓存⽤户登录信息、排⾏榜等热点信息,⽂件内容则通过FastDFS分布式存储集群进⾏管理,由Tracker节点调度多个Storage节点实现⽂件的存储和同步。整个项⽬的后台存储层还通过连接池优化数据库访问,拥有⾼并发特性。
2.介绍一下项目架构
项⽬有四层架构:客户端,代理层,
客户端:客户端在⽹⻚可以发起HTTP协议,发起注册、登录、⽂件上传下载、分享列表等请求。
代理层:Nginx + fastdfs-nginx-module的⽅式处理⽂件流和访问
接⼝服务层:多reactor多线程的⽹络模型,主reactor负责接收连接和分发连接给subReactor,
subReactor通过封装好的epoll来对具体连接进⾏io处理,对客户端的请求进⾏反序列化解析,实
现注册、登录、上传⽂件、⽂件列表展示、共享⽂件、下载⽂件,删除⽂件等功能
存储层:使⽤MySQL管理⽤户及⽂件元数据,redis缓存⽤户登录信息、排⾏榜等热点信息;上传
的⽂件通过FastDFS分布式存储集群进⾏管理
3.你设计的网络框架需要考虑哪些接口,需要如何做到高效
4.项目中遇到什么问题,怎么解决的
①整体架构的设计:之前只做过⽹络编程的内容,想着真正做⼀个可以有功能的完整项⽬。这个项⽬能 够以⽹络编程,连接池,数据库的技术为基础,于是想到做⼀个可做到线上存储和共享的多⽤户系统。于是学习了nginx的如何使⽤,将其选择作为代理层,同时了解到fastdfs可以作为⽂件服务的站点,并且 有 fastdfs-nginx-module这个模块。于是以⽹络编程为基础,nginx和对应的fastdfs模块作为代理层,后端服务层做了具体的业务逻辑,mysql和redis作为存储层,设计了四层框架,每⼀层分配了具体的任务,最后完成了这样⼀个项⽬。
②接⼝的设计:
为了⽅便后端进⾏代码框架的构建,需要在设计功能的之前先想好前后端如何进⾏交互。客户端与服务 端的交互是基于HTTP协议的。HTTP API的设计基于json格式,因为构建起来简单,所以采⽤ HTTP + JSON的⽅式 通过客户端向服务器请求数据。然后接⼝直接以请求的具体⽅式来命名,例如注册就 ⽤/api/register,登录就⽤/api/login
断点续传的痛点:





6.项目中某个技术还有没有其他解决方案,你为什么使用这种解决方案


8.除了使用fastdfs做存储,还有没有其他方案
MINIO存储 腾讯COS存储
上传⽂件:先通过nginx-upload-module模块上传⽂件到临时⽬录->nginx-upload-module模块上

上传文件:

断点上传:


线程池 连接池 reactor模型
断点续传的痛点:




用户代码 → storage_factory → storage_backend ← fastdfs_backend/minio_backend/cos_backend(创建哪个后端) (统一接口) (具体实现)![]()
5.项目中某个技术点,业界是怎么做的

6.项目中某个技术还有没有其他解决方案,你为什么使用这种解决方案

7.项目中的技术是怎么使用的

8.除了使用fastdfs做存储,还有没有其他方案
MINIO存储 腾讯COS存储
9.http上传逻辑是怎么样的,怎么实现断点上传,断点下载?
秒传⽂件:客户端在上传⽂件之前将⽂件的MD5码上传到服务器->服务器端判断是否已存在此MD5 码,如果存在,说明该⽂件已存在,则此⽂件⽆需再上传,在此⽂件的计数器加1,说明此⽂件多了 ⼀个⽤户共⽤->如果服务器没有此MD5码,说明上传的⽂件是新⽂件,则真正上传此⽂件
上传⽂件:先通过nginx-upload-module模块上传⽂件到临时⽬录->nginx-upload-module模块上
传完⽂件后通知/api/upload后端处理程序->后端处理程序ApiUpload函数解析⽂件信息(⽂件类型、
⽂件⼤⼩、⽂件路径、⽤户名、⽂件md5、后缀名),然后将临时⽂件上传到fastdfs->fast返回
fileid->根据fileid拼接完整url->更新数据库记录

上传文件:

断点上传:

10.排行榜如何实现的, 除了使用redis做排行榜,有没有其他方案

线程池 连接池 reactor模型
这都是subreactor完成
“数据搬运”本质上就是网络I/O操作,具体来说就是 recv
和 send
这两个系统调用。
是的,Subreactor线程 严格来讲就干这两件事:
监测: 阻塞地监视所有被注册的连接,等待I/O事件(如可读、可写)发生。
返回就绪列表: 一旦有事件发生,就返回一个包含所有就绪文件描述符的列表。
事件检测 = epoll_wait
事件处理 = recv
+ 业务逻辑
线程池的作用:将业务逻辑继续分离
连接池:
注册:解析请求,得知是注册请求->从mysql连接池⾥获取可⽤的连接->通过获取的连接查询数据
库的user_info表⾥是否存在请求注册的⽤户->如果user_info⾥不存在就写⼊数据库->返回结果
连接池:提前建⽴连接,复⽤连接;mysql和redis 的c++驱动(⾥⾯要实现⽹络编程中的connect,
read/recv,write/send,close;阻塞io)
4.熟悉mysql 索引最左匹配原则
5.熟悉Redis和mysql联合使用要点
mysql与redis联合使⽤回答
1. ⻆⾊定位
MySQL:作为主要的持久化数据存储,负责存储所有业务数据,处理复杂的事务,以及⻓期的数据 保留。Redis:作为⾼速缓存和消息代理,负责处理⾼频读写操作,减轻MySQL的负担,提⾼系统响应速 度。
2. 数据⼀致性
两者联合使⽤通常追求最终⼀致性,⽽⾮实时⼀致性。这意味着redis中数据在某些情况下会稍微落 后于mysql 旁路缓存模式:在读操作时,先从Redis缓存中读取数据;如果缓存未命中,则从MySQL中读取, 并更新Redis缓存。在写操作时,先更新MySQL,然后删除Redis中的对应缓存,以确保下⼀次读操 作能够从MySQL中获取最新的数据。
3. 数据同步
解析binlog:通过解析MySQL的binlog⽇志,可以将数据变更实时同步到Redis,但这可能会增加系 统的复杂性。 使⽤UDF(⽤户定义函数):通过MySQL的UDF来同步数据到Redis,但需要谨慎使⽤,因为这可 能会影响数据库性能
6.熟悉fastdfs水平扩展,如何保证可靠性,如何提升上传下载能力,上传下载性能测试方法(不同文件大小 性能测试)
7.http api + json,图床功能api设计思路
8. http多线程下载原理、断点下载原理、断点续传、大文件如何上传或者下载
wrk+lua如何做性能测试
- 同一个group里的storage如何做同步,不同group里的storage能否做同步
FastDFS上传和下载的核心流程
FastDFS数据同步核心机制:
7.项⽬⾥⾯的表设计
user_info:
user_name:⽤户名称
password:保存md5后的加密值
file_info
md5:⽂件md5
file_id:⽂件id 类似group1/M00/00/00/xxx.png
file_url:类似192.168.1.2:80/group1/M00/00/00/xxx.png
type:⽂件类型
7count:⽂件引⽤计数
user_file_list
user:⽂件所属⽤户
md5:⽂件MD5
file_name:⽂件名字
share_status:共享状态
pv:⽂件下载量
⽤户⽂件数量表
user:⽂件所属⽤户
count:拥有⽂件数量
共享⽂件列表share_file_list
user:⽂件所属⽤户
pv:⽂件下载量
md5:⽂件md5值
file_name:⽂件名字
共享图⽚列表、
user:⽂件所属⽤户
file_name:⽂件名字
fiilemd5:⽂件md5
urlmd5:图床urlmd5
pv:访问量
9.架构;特点;其他⽅案;分布式在哪
10. ⾼可⽤?项⽬是怎么做到⾼可⽤的
11. 分布式?项⽬是如何做到分布式的
数据分布的分布式和请求处理的分布式
讲⼀下内部业务的实现逻辑
