类似秒杀等项目用消息队列的话, 一般通过什么方式通知用户结果

2019-12-09 22:53:05 +08:00
 aoscici2000

假设我使用的方式如下:

10000 名用户发送请求数据, 一律由 nginx 直接送到消息队列里去, 先进队列的前 100 个直接扔给 celery 之类处理写入数据库, 这种情况下一般怎么通知用户结果? 直接查询数据库貌似会出现秒杀成功了但还没完成写入的情况

5544 次点击
所在节点    Java
9 条回复
neoblackcap
2019-12-09 23:09:28 +08:00
我问你一个问题,你是如何保证消息队列只放了前 100 个请求?
假如你可以保证消息队列只放前 100 个请求,后面的直接返回秒杀失败不就可以了?
opengps
2019-12-09 23:20:58 +08:00
直接在内存查询,不要走数据库
aoscici2000
2019-12-09 23:36:49 +08:00
@neoblackcap 不是只放 100 个,是把前 100 个扔给 celery,通过个 redis 计数器之类的吧?到了 100 以后的队列就不处理了。或者直接删除队列说不定是个好选择?
neoblackcap
2019-12-09 23:39:33 +08:00
@aoscici2000 那你现在不就回答出来了?多问自己几个为什么就好了
billlee
2019-12-09 23:47:44 +08:00
秒杀失败也要写记录。查不到就退避后重试。
lihongming
2019-12-10 02:02:16 +08:00
秒杀哪有查库的?不说性能了,就是同步问题也够你喝的了。

一个最简单的单前段架构,也得是前段先查自己内存里的计数,小于 0 直接返回失败,大于 0 再尝试往队列里插。这里会有线程安全问题,但可以先不管,性能优先。

由于队列并不管订单处理情况,所以入队成功也不意味着订单创建成功,所以入队成功的订单状态可以改为待定,然后给用户显示个等待状态,每隔几秒用 ajax 查询一下,这时压力就不大了,可以直接查库。

至于入队失败的,直接返回失败即可。

另外你需要一个前端服务与实时库存同步的机制,比如每 5 秒同步一次,这样后端有了失败的订单以后,前端也可以接受新订单了。
jss
2019-12-10 08:57:57 +08:00
我的实现很简单,消息列队都没用。锁+并发=秒杀
securityCoding
2019-12-10 09:39:32 +08:00
库存用 redis 或者直接写在内存里面 , 这一步拦住基本问题不大,查询详情页什么直接内存过期缓存就行
qinfensky
2019-12-10 13:03:18 +08:00
用个单例在内存中统计好不好?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/627439

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX