业务场景经常会出现高并发读写的场景,不考虑图片缓存等cdn技术,只从后台优化方面考虑,通常解决高并发读
的情况即是使用缓存,缓存下,放多个从库。
现在主要总结一下公司在解决高并发写的一些解决办法。
目前团队面对的几个高并发写的场景:
1,播客发红包,观众抢红包。
2,对全民主播点赞,掉会员
3,送礼,赞助加经验
4,零点守护神过期,抢购守护神
解决高并发写的三个最基本思路:
1,内存计算
2,异步处理
3,多consumer消费
公司上述场景中的抢红包,抢守护,点赞掉会员,都属于典型的库存<请求量类的秒杀场景。
其中抢红包流程图如下:
1,用户抢红包的消息是发送至IM服务器,再又IM服务器发送至相应的queue上,然后开启多台consumer进行抢红包消息处理,对于每一条抢红包消息,consumer消费过后,都会将结果再发送回IM服务器,再由IM服务器通知前端。当应用服务成为瓶颈时,可扩容IM服务器,以及consumer服务器来解决。
2,抢红包前,先进行身份验证,将不满足资格的用户过滤。
3,红包业务采用redis计算红包剩余数量,请求到来时,redis直接执行减库存,并返回剩余库存操作,若库存已为0,则不再走数据库处理,直接返回,若库存存在,再进行后续数据库落地操作,因为是依托于redis实现对库存实时修改与查询,故后续数据库落地失败
时,需要执行库存+1操作。采用redis做内存实时计算,可极大减轻高并发对库的冲击,基本落到库的写请求都是可成功的,不可成功的
请求多数在redis层判定后返回。这部操作也叫做用户请求预处理操作。
抢红包不涉及到扣钱,所有只要考虑库存问题,目前的实现比较简单,单纯的select ...for ...update
中规中矩的行级锁表,校验,更新,插记录,最后返回,并更新redis。
其实代码还是有可以优化的地方,执行行级锁之后,其他线程在执行这个方法时,则会处于等待状态,
所以,最好将判定时间段,判定用户是否抢过红包等一些组装操作,都放到select...for....update外。