redis简单:消息队列-高并发-超抢/卖 一边 lpush() 另一边 rpop()。
redis简单:消息队列-高并发-超抢/卖
一边 lpush() 另一边 rpop()。
、消息队列
什么是消息队列?
是一个消息的链表,是一个异步处理的数据处理引擎。
用途有哪些?
邮件发送、手机短信发送,数据表单提交、图片生成、视频转换、日志储存等。
有什么好处?
不仅能够提高系统的负荷,还能够改善因网络阻塞导致的数据缺失。
有哪些软件?
ZeroMQ、Posix、SquirrelMQ、Redis、QDBM、Tokyo Tyrant、HTTPSQS等(linux平台下)。
怎么实现?
顾名思义,先入队,后出队;先把数据丢到消息队列(入队),后根据相应的key来获取数据(出队)。
首先,redis设计用来做缓存的,但是由于它自身的某种特性使得它可以用来做消息队列,它有几个阻塞式的API可以使用,正是这些阻塞式的API让其有能力做消息队列;另外,做消息队列的其他特性例如FIFO(先入先出)也很容易实现,只需要一个list对象从头取数据,从尾部塞数据即可;redis能做消息队列还得益于其list对象blpop brpop接口以及Pub/Sub(发布/订阅)的某些接口,它们都是阻塞版的,所以可以用来做消息队列。
简单的代码实例:
二、redis简单并发处理
这里模拟下10000用户处理
这段代码解决瞬间处理10000个用户同时操作数据库,我们就可以在redis中获取到成功用户的id,只对这100个用户做相应的操作,
上面的情况正常情况下会有列表中只会存100个用户,但实际情况中不是while循环,而是多用户同时访问这样的代码:
在高并发的情况下,在使用jmeter工具模拟用户并发请求时总会发现多出几个用户,也就是出现超卖/超抢,问题代码:
在抢购进行到一定程度,假如现在已经有99个人抢购成功,又来了3个用户同时抢购,这时if条件将会被绕过(条件同时被满足了),这三个用户都能抢购成功。而实际上只剩下一件库存可以抢了。
在高并发下,很多看似不大可能是问题的,都成了实际产生的问题了。要解决“超抢/超卖”的问题,核心在于保证检查库存时的操作是依次执行的,再形象的说就是把“多线程”转成“单线程”。即使有很多用户同时到达,也是一个个检查并给与抢购资格,一旦库存抢尽,后面的用户就无法继续了。
比如这里我先把库存(可用库存,这里我强调下哈,一般都是商品详情页抢购,后来者进来看到的库存可能不再是后台系统配置的10个库存数了)放入redis队列:
抢购开始
接下来处理list中的user就可以了,上面只是简单模拟高并发下的抢购思路,真是场景会比这复杂多
再如上面的会导致一个用户抢多个,思路:
需要一个排队队列(比如:queue:1,以user_id为值的列表)和抢购结果队列(比如:order:1,以user_id为值的列表)及库存队列(比如上面的goods_store:1)。高并发情况,先将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在则已抢购,否则未抢购,接着执行库存减1,写入数据库,将此user_id用户同时也进入结果队列。