设计一个社区系统
1 | //todo 将用户评论、点赞、收藏、系统消息发送到 RabbitMQ,统效率和服务稳定性;实现消息的异步解耦. (点赞、收藏 业务优化) |
点赞、收藏
点赞收藏其实业务基本相同、一整个流程就是:
1、判断用户是否已经点赞
2、关系表插入数据
3、点赞数+1
取消点赞也是类似,以上代码不加锁会有并发问题
优化:
1、关系表插入数据(关键字段添加索引)
2、点赞数+1
当用户已经点赞了,第一步就会抛出异常,优化的方案相对于第一版方案的优点如下:
1、不需要添加锁
2、减少了与数据库通信的次数
排行榜(实时)
常规:使用zset来维护,zset中保存所有的数据,然后维护好这个zset就行了。
缺点:这个方案需要redis保存所有的数据
优化:
我们可以根据网站的qps来保存部分数据,实现实时排行榜(百人)的功能
举例:假设我的网站每分钟最多有900个score add 的操作,
那么我们可以每分钟获取数据库中前1000的数据,之后用户add score的时候,如果此条记录在redis中没有就更新数据库中的记录
如果redis中有的话就俩个都更新
这样能实时吗?
因为我们的每分钟访问量为900,那么就算你这一分钟一直在add排行第1001的记录,他也不可能进入到前100的排行榜中,他最多从第1001提升到第101
房间人数上限维护
由于redis没有 set and if 的原子操作,那么 set 一个数字 并判断是否超过某个数字的话就需要加锁或者使用lua脚本,非常的不优雅,
那么有什么办法可以不加锁也不使用lua脚本呢?
思路:
我们知道redis 中 整数的最大值是int64来进行保存的,而且incr num 超过最大值会返回0,那么我们可以使用这一特性来完成房间人数上限的维护
1、在我们初始化房间时,人数设置为 int64能保存的最大值 - 房间人数上限
2、用户加入房间的时候判断incr 的返回值 看是否成功执行
2、
3、
4、
5、
6、
7、
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yuechu`blog!