每个人的feed就是一个list,存储到redis;
用户前端产生的所有事件 发送到消息队列 RabbitMQ,
Server 根据 业务逻辑将新的item插入到下游用户的feed里面;
在线推,推给活跃在线用户,离线拉;
任务调度 :选用了Celery;
每个用户都有一个收件箱 和 发件箱;保存自己发过的动态以及Feed动态;
用户A关注了用户B , 用户B发布动态则将动态推进用户A的feed,这里使用redis的zset实现,sort为time(记得以毫秒为时间戳,秒级在数据量达到一定程度后,会有读取不到的问题,比如以时间戳为分页页码),value为具体的动态 ID(为什么是动态ID, 其实很简单, 就是因为动态的内容可以进行缓存,在redis里面全部走ID,修改动态内容也需要修改一处,动态内容可以保存在hash结构里), 每个用户维护一个zset保存我发布的动态,一个zset保存我的feed动态,过期时间3~7天看情况而定。
全局维护一个在线用户列表,怎么设计这个就自己琢磨了,为了防止用户挂后台导致与服务端为离线状态,所以最好是1~3小时未操作或者离线时间不大于3小时的,都当做在线处理,
那么,当用户发了一条动态后,后台会有以下这些操作:
在线推: 异步遍历在线的粉丝,将动态ID,添加到粉丝的Feed中。
离线拉: 离线用户打开APP后,我们是会请求一个公共的入口接口,主做统计以及其他初始化操作,在这里,我们也开了一个异步线程,对用户进行Feed更新操作,防止用户进入APP后等待拉取时间过长,毕竟关注成千上万的人肯定有(其实万单位以下遍历都很快)。拉取过程其实就是把自己最后一条Feed的时间戳取出,去遍历关注的人的feed,将大于该时间的ID全部拉取回来。用户进入APP后,刷新即可看到最新操作。