秒杀项目之项目最大的难点/挑战点是什么?

我觉得比较有挑战的点是判断订单是否超时这块的设计。
刚开始的时候我是想到了数据库的轮询,就是通过一个线程定时的取扫描数据库,通过订单时间来判断是不是有超时的订单,然后进行update或者delete操作,这种方案虽然简单易行,但是这种方案对服务器的内存消耗特别大,对服务器的消耗也特别大,并且这样得到的数据不是及时性的,很可能产生延迟,所以我又想到了使用队列。
就是用jdk自带的delayQueue类实现,这是一个无界的阻塞队列,这种队列就是只有在延迟期满的时候才能从队列里面获取元素,他里边有两个方法,一个是poll(),可以获取并移除队列的超时元素,没有的话返回空,还有一个是take(),也是获取并移除队列的超时元素,如果没有的话就wait当前线程,一直到有元素满足超时条件,再返回结果。这种方案的优点是效率高,任务触发的时间延迟低,但是缺点是代码复杂度过高,而且如果下单未付款的订单数太多,就很容易出现OOM异常,并且如果服务器重启以后,数据会全部消失。所以我又想到了第三种方式,使用redis缓存,首先想到的是redis缓存中的zset,zset是一个有序的集合,每一个元素都关联了一个score,通过score排序可以来取集合中的值。我先将订单超时时间戳和订单号分别设置成score和member,系统扫描第一个元素判断是否超时,但是这样又存在一个问题,就是在高并发条件下,线程不安全。最后我又想到了用rabbitMQ的延时队列。
rabbitMQ针对queue和message设置x-massage-tt,来控制消息的生存时间,如果超时的话,消息会变成dead letter,这样处理的效率比较高,并且可以利用rabbitmq的分布式特性轻易的进行横向扩展,而且消息支持持久化,增加了可靠性。所以这也是我最后选择实现的方案。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务