假设我使用的方式如下:
10000 名用户发送请求数据, 一律由 nginx 直接送到消息队列里去, 先进队列的前 100 个直接扔给 celery 之类处理写入数据库, 这种情况下一般怎么通知用户结果? 直接查询数据库貌似会出现秒杀成功了但还没完成写入的情况
1
neoblackcap 2019-12-09 23:09:28 +08:00
我问你一个问题,你是如何保证消息队列只放了前 100 个请求?
假如你可以保证消息队列只放前 100 个请求,后面的直接返回秒杀失败不就可以了? |
2
opengps 2019-12-09 23:20:58 +08:00 via Android
直接在内存查询,不要走数据库
|
3
aoscici2000 OP @neoblackcap 不是只放 100 个,是把前 100 个扔给 celery,通过个 redis 计数器之类的吧?到了 100 以后的队列就不处理了。或者直接删除队列说不定是个好选择?
|
4
neoblackcap 2019-12-09 23:39:33 +08:00
@aoscici2000 那你现在不就回答出来了?多问自己几个为什么就好了
|
5
billlee 2019-12-09 23:47:44 +08:00
秒杀失败也要写记录。查不到就退避后重试。
|
6
lihongming 2019-12-10 02:02:16 +08:00 via iPhone 1
秒杀哪有查库的?不说性能了,就是同步问题也够你喝的了。
一个最简单的单前段架构,也得是前段先查自己内存里的计数,小于 0 直接返回失败,大于 0 再尝试往队列里插。这里会有线程安全问题,但可以先不管,性能优先。 由于队列并不管订单处理情况,所以入队成功也不意味着订单创建成功,所以入队成功的订单状态可以改为待定,然后给用户显示个等待状态,每隔几秒用 ajax 查询一下,这时压力就不大了,可以直接查库。 至于入队失败的,直接返回失败即可。 另外你需要一个前端服务与实时库存同步的机制,比如每 5 秒同步一次,这样后端有了失败的订单以后,前端也可以接受新订单了。 |
7
jss 2019-12-10 08:57:57 +08:00 via iPhone
我的实现很简单,消息列队都没用。锁+并发=秒杀
|
8
securityCoding 2019-12-10 09:39:32 +08:00
库存用 redis 或者直接写在内存里面 , 这一步拦住基本问题不大,查询详情页什么直接内存过期缓存就行
|
9
qinfensky 2019-12-10 13:03:18 +08:00 via iPhone
用个单例在内存中统计好不好?
|