用户登录模块
登录模块主要就是基于springSecurity实现的,在登录后,会提供JWT生成对应的token。
我给您说一下JWT的实现流程吧,其主要分为三个部分,header,body(存放userId),签名。使用header + body基于base64生成签名。最终请求都会去携带该token。(token中不要存放非常重重要的信息,因为安全性不高)
在我们的微服务项目中,请求会先进入网关,网关会配置一个全局拦截器,去解析token,并将userId继续让请求携带到微服务中。
服务中涉及到远程调用,为了保证服务间能够正常的获取userId,我们是使用threadLocal进行存储的。同时给定义一个公共的全局拦截器,在每次进入服务的时候,先判断threadLocal中是否有数据,如果没有就会到请求中获取,最终放行。
片源观看模块
1.视频的播放方式和上传
使用腾讯的VOD来实现的,其有非常全面的视频任务流,我们只需要对任务流进行配置即可使用,包括视频的加密,视频封面图的生成,视频雪碧图的生成,视频的审核。
我们只需要实现视频的上传即可,我们无需视频文件上传到服务端,服务只需要生成对应的授权签名,使用VOD提供的JS的SDK并携带授权起名,提供文件上传工具即可实现在客户端的视频上传。
VOD也提供了视频播放器,无需提供视频的播放地址,而是提供授权签名和文件id给VOD,就可以实现视频的播放,在这个视频的传输过程都是加密的,可以做到防止视频被盗。
实现方式就前端的操作,引入SDK,生成签名,视频文件上传(返回file类型的数据)。
2.提交观看位置(合并写请求,减少99%的DB操作)
这里的业务需求,就是需要实现用户续看的功能,保证用户切换其他设备的时候也可以续看,并且误差要在30秒之内。
旧方案:在刚开始的时候,就是想直接去操作数据库,前端每隔15秒就提交一次观看位置的请求,因为视频的播放为用户主要的操作,所以就会存在高并发的场景,大量的访问DB最终会压垮数据库。(修改观看记录表)
新方案:合并写请求,我们会发现在这么多DB操作只有最后一次的观看位置有用,使用redis的hash结构,大key存储片源表的id(其关联了片源id和userId),小key存储集的id(一个片源如果是电影的话就1节,反之存在多节),value就存储观看位置mount。在每次请求进来后会修改hash结构中的数据,并且使用mq的死信队列发送一个20秒延迟消息(面试官有问的话,就稍微解释一下),消息中主要就是mount,监听器任务就是判断消息中的mount和redis中的mount是否相同,如果相同就说明20内没有继续观看,此时修改数据库中观看位置。反之则不进行操作。
片源话题及回复模块
在数据库的设计上主要就是两张表,分别是 话题表和回复表。
话题表 主要字段就是标题,内容,回复数,而在回复表中主要即使目标回复id和点赞数。
在展示话题的回复时,通过递归的获取对应的回复集合。
在里面比较难的就是点赞的实现,我给您介绍一下点赞回复/话题模块吧。
点赞回复/话题模块
旧方案:基于点赞记录表做点赞的记录并且每次进行点赞