青训营项目--极简版抖音总结
采用 MVC 结构,使用 Gin 作为 Web 框架,Redis 作为缓存框架,MySQL 作为持久层框架。
项目开发介绍
团队分工
小组一共七个人,可能年后大家都比较忙,只有我一人参与实际开发。
项目简介
本项目是第五届字节跳动青训营后端基础班大作业,在该项目之前只实现过简单的接口服务器,没有接触过golang,因此在实现的过程中借鉴了一些往届优秀作品。本项目采用 MVC 分层设计模型分离模型层、视图层和控制层,从而降低代码的耦合度,提高项目的可维护性。
1 |
|
极简版抖音项目划分为两大方向,互动方向和社交方向,两个方向均包含基础功能内容,在扩展功能上有所不同,具体内容如下:
- 视频:视频推送、视频投稿、发布列表
- 用户:用户注册、用户登录、用户信息
- 点赞:点赞操作、点赞列表
- 评论:评论操作、评论列表
- 关注:关注操作、关注列表、粉丝列表
- 消息:聊天操作(暂未实现)
技术速览
1. 使用redis加速点赞和关注过程
简单分析抖声项目可知,整个抖声app,点赞和关注是很明显的性能热点。
为此我将点赞和关注对数据库的变化用redis来做一些数据的缓存,比如该视频是否被点赞以及该用户是否被关注等等过程。
2. 使用gorm建表
数据库需要额外建立中间表实现多对多关系,gorm可以自动给多对多关系建立中间表,只需要互相持有对方的切片类型,然后再指定many2many字段即可。
3. gin框架中间件复用代码
使用gin框架的中间件实现 JWT鉴权、密码加密存储和userId的解析验证。具体有以下中间件:
- JWTMidWare:从JWT中解析出user_id
- SHAMiddleWare:使用SHA1算法加密密码
- UserIdVerify:解析并验证user_id
4. 安全防御措施
具体措施主要有以下几点:
- 规范使用gorm操作sql语句,可防止sql注入。
- 用户密码进行SHA1加密,这个过程设置在中间件中。
- 使用JWT用户鉴权,并加入到中间件过程中。
- 文件合法性检验,主要是对视频的文件格式是否支持的校验。
- 保持文件的唯一性,主要保持每次上传文件名称的唯一性,通过用户id和用户上传的视频数量进行捆绑得到一个唯一的文件名称。
- 所有的参数均在service层的第一个阶段完成校验。
5. ffmpeg切片得到封面
首先应安装ffmpeg,并添加到系统路径。我使用ffmpeg-go从视频中截取封面的函数GetSnapshot,添加ffmpeg-go依赖:
1 |
|
GetSnapshot函数默认生成格式未jpg的封面图片,该函数有三个参数:
- videoPath: 视频文件地址
- snapshotPath: 生成图片的地址
- frameNum: 获取第几帧
6. 高度定制化的配置
整个项目的环境依赖的配置均通过config文件夹里面的config.toml文件进行管理,这样增加了环境配置的灵活性,配置如下,注释也写的很清楚。
1 |
|
项目说明
1. 架构说明
以用户登录模块为例共需要经过以下过程
- 首先进入中间件SHAMiddleWare内的函数逻辑,得到password明文加密后调用gin.Context的Set方法设置到context对象中。随后调用next()方法继续下层路由。
- 接着进入handler层UserLoginHandler函数逻辑,该函数负责从请求参数和context对象中读取username和password参数,并将得到的数据以规定的格式传给前端,获取相关数据的具体操作在service层中的QueryUserLogin函数中实现。
- 进入service层QueryUserLogin函数逻辑,执行三个过程:checkNum,prepareData,packData。也就是检查参数、准备数据、打包数据,准备数据的过程中会调用model层的UserLoginDAO,从数据持久层中获取数据。
- 进入service层UserLoginDAO的逻辑,执行最终的数据库请求过程,返回给上层。
2. 数据库说明
3. 遇到的问题
4. 可改进的地方
- 很多执行逻辑可以通过并行优化。
- 未增加日志系统。
- 未用到集群、微服务等架构。
- 未使用对象存储来进行视频的存储。
- 密码的加密没有进行加盐处理。
- 使用gorm时,使用了原始的sql命令。
5. 项目运行
本项目运行不需要手动建表,项目启动后会自动建表。
运行所需环境:
- mysql 5.7及以上
- redis 5.0.14及以上
- ffmepg(已放入lib自带,用于对视频切片得到封面
- 需要gcc环境(主要用于cgo,windows请将mingw-w64设置到环境变量
运行需要更改配置:
进入config目录更改对应的mysql、redis、server、path信息。
- mysql:mysql相关的配置信息
- redis:redis相关配置信息
- server:当前服务器(当前启动的机器)的配置信息,用于生成对应的视频和图片链接
- path:其中ffmpeg_path为lib里的文件路径,static_source_path为本项目的static目录,这里请根据本地的绝对路径进行更改
完成config配置文件的更改后,需要再更改conf.go里的解析文件路径为config.toml文件的绝对路径,内容如下:
if _, err := toml.DecodeFile(“你的绝对路径\config.toml”, &Info); err != nil { panic(err) }
运行所需命令:
1 |
|
个人收获
由于第一次接触到这类项目,本科期间主要做的前端后端只做过简单的API服务器,所以有很多东西之前没有接触过,这次的项目可以说是边学习边coding的过程,阅读往届优秀作品的源码也让我受益良多。
- 学会对整个项目进行MVC分层处理。
- 学会以更合理的方式组织代码(项目结构划分 函数名规范等),提高代码可读性。
- 学会使用gin框架,使用gin框架实现路由分发。
- 学会使用gorm框架,该框架可以自动完成整个建表过程,按照规范使用gorm能够防止sql注入。
- 学会使用JWT鉴权,并利用gin框架提供的中间件实现鉴权模块。
- 学会MySQL中的多对多关系映射以及一对多等等关系的映射。
- 学会Redis的使用。