成长计划方案

1.  需求简介算法

根据用户的测试状况,给他推荐相应的课程,而后根据学习时长能够得到勋章数据库

2.  效果图缓存

 

3.  功能拆解异步

3.1.  测试题分布式

【要点】学习

一、 须要一个题库,配好题目和答案选项;测试

二、须要根据用户的答题状况(分数)抽取必定量的各类类型的题目大数据

三、本次抽取的题目与上一次的题目重复率不得超过50%spa

四、提交答案3d

【难点】

这个功能最复杂的地方在于重复率不得超过50%,能够用两次的题目去交集来判断,也能够排除上一次的题目后再随机,没有用什么高深的算法(主要是不懂)这里我用的后者,再也不赘述。

3.2.  生成计划

【要点】

一、从大数据那里获取推荐内容

二、上一个计划未完成不容许开启下一个计划

三、同种勋章只能得到一次

四、保存数据(计划、计划详情、勋章、消息)

【难点】

一、调大数据的接口时要考虑到失败的状况,即便大数据的服务挂了,我们也不能挂,为此加上try...catch,超时时间等等都是必要,这还不够。万一调大数据失败了,返回保底数据。

二、考虑到重复提交的状况,需加分布式锁

3.3.  计划首页

【要点】

一、内容展现,包括分已购未购、免费付费、会员非会员、标签等等

二、学习时长展现,包括时长、天数、当前阶段、勋章等等

【难点】

一、查数据库想都不要想,首选直接查Redis,可是Redis查的次数多了综合起来也有可能慢,必要时可考虑本地缓存(内存缓存)

二、时长、天数等均从在Redis总累计,可直接获取

3.4.  学习时长

【要点】

一、实时记录

【难点】

一、线上相似的接口高峰时段可达到1分钟84万次请求,所以想都不用想,必须异步,咱们采用MQ

二、尽管消费者是一条一条的消费,然而这并不意味着一秒钟只消费一条,据观察,线上其它相似MQ消费者平均一秒钟消费300条

三、时长最终是要更新到MySQL数据库中的,可是如此频繁的写数据,风险比较大,想来想去,最终选择用定时任务在夜深人静的时候从Redis同步到MySQL

四、学习时长是一个特别重要的参数,关系到挑战任务,关系到勋章,所以以秒为单位,累计至1分钟再写入

五、在压测的时候,我发现基于Redis的分布式锁彷佛并不能保证彻底100%锁住,虽然几率极低,但我好像碰到了

3.5.  楼层

【要点】

一、根据用户计划的状态展现不一样的按钮及背景图

二、连续关闭两次楼层后再也不出现,新开启计划后再次出现

【难点】

一、用户关闭楼层的行为直接记到Redis中,没必要存数据库

3.6.  弹窗

【要点】

一、每一个挑战任务对应一个勋章,再加上最后一个奖励勋章。任务是有顺序的,所以弹窗也是,为此须要知道任务先后的关系

二、每一个弹窗只弹一次,所以须要记录用户是否查看过

【难点】

一、用双向链表将挑战任务串联起来,这样就能够根据当前所处阶段快速找到上一个或下一个任务

二、在Redis缓存结构上,我犯了一个错误。缘由我想的是既然是有顺序的要不就用List类型,可是后来发现更新的时候极其不方便,要把全部的元素先删除(LTRIM命令),而后修改后从新插入,在一次压测过程当中发现里面大量重复数据,还没删完就已经插入了,因而越插入越多,这就是偷懒的代价,最终紧急改为Hash类型,这样即便有重复也会被覆盖。

3.7.  通知消息

【要点】

一、APP消息和站内信都要发

二、不用的阶段的消息文案不同

【难点】

一、定时任务扫描

二、异步发送,保证互不影响

4.  压测

全部的Redis查询都是批量查询,即便是这样,响应时间依然很长,平均响应时间400ms左右。用PinPoint分析排查:

后来,加上了本地缓存Caffeine,感受快了不少

顺便看下其它指标

相关文章
相关标签/搜索