消息队列一|从秒杀活动开始聊起消息队列

削峰填谷,异步处理

秒杀活动中为何要使用到消息队列?

先说结论,秒杀活动并不是常规的活动,因此考虑到资源成本,以及服务稳定性,使用消息队列更佳。

假设某电商平台开办一场秒杀活动,活动有1000个性价比高的商品。参与该场活动的用户会在活动开始前的几分钟进入页面。

频繁的刷新,以及后面开始的秒杀活动,都需要查询商品的库存信息,绝大多数是读请求,因此我们需要使用缓存来扛住。

这边说的缓存,包括使用CDN缓存和nosql缓存。

一些静态的图片和视频,可以通过CDN的方式缓存,CDN 即内容分发网络,部署在距离终端用户最近的网络服务商,用户的网络请求总是先到达他的网络服务商那里,在这里缓存一些静态图片和视频,可以就近以最快的速度返回给用户。

消息队列一|从秒杀活动开始聊起消息队列_第1张图片

一些商品信息的查询请求,可以使用nosql的缓存,如果不希望请求到对应的web 服务,可以通过在网关代理层直接请求到nosql缓存。

消息队列一|从秒杀活动开始聊起消息队列_第2张图片

秒杀成功的请求,进入下单流程,这部分请求相比日常的请求量,也是一个瞬时的高峰写请求,这样高峰的写请求,对于数据库来说,也是比较大的压力,同时也使得响应延迟加剧。可能有的人会说,可以通过分库分表来解决。没错,分库分表一种解决方式,只不过这种方式增加了数据维护的复杂度,分库分表之后,想通过非分库分表字段去查询数据库,就要遍历所有库和表。如果需要批量查询,也要跨库跨表去查询,性能也是个问题,另外即使分库分表,如果平时没有预留多几倍的分库和分表,遇到这样的活动,还是要考虑扩展更多的分库来处理写流量,这样的扩展,还需要考虑数据迁移的问题。

因此,分库分表大多时候是一个最后的兜底方案。在这个场景下,比较好的方式,我们可以通过消息队列来扛住下单的高峰写请求,这也是消息队列的一个很常用的使用场景,削峰。即通过异步处理,将短时间高并发产生的食物消息存储在消息队列中,从而削平高峰期的并发事务。使用消息队列后,用户请求的数据发送给消息队列后立即返回,由于消息队列服务器的处理速度远快于数据库,因此用户的响应延迟也能得到有效的改善。同时消费消息的的服务也是可控的服务数量,因此不会对数据库有过大的压力。

消息队列一|从秒杀活动开始聊起消息队列_第3张图片

解藕合

除了削峰和异步处理,消息队列还有一个使用场景是解耦。

很多公司都有大数据团队专门用于分析用户群体的喜好,活动促销的效果等,以便后续做一些推荐和更好的促销。

那就需要把用户下单相关的数据推送给这些团队,一种方式是这些团队提供同步接口来接收数据,但是这种方式耦合度高,会有两个问题:

1 一旦接口出现故障,直接影响到下单服务,从而影响用户的购买。

2 如果数据系统需要新的数据字段,下单系统也要跟着调整接口参数。

这种场景我们可以直接使用消息队列来降低下单系统和大数据系统的耦合度,下单系统可以把完整的数据发送到消息队列,大数据团队可以按需获取,这样即使大数据系统出现问题,也不会影响到下单系统,另外也可以按需获取需要的数据。

消息队列一|从秒杀活动开始聊起消息队列_第4张图片

引入消息队列带来的问题

上面通过秒杀活动介绍了消息队列的几个作用:削峰,异步处理,解耦合。可以用来提升系统的稳定性和性能。但是引入了消息队列,系统的流程变长,复杂度也跟着变高,因此也带来一些新的问题,如何做到消息不丢失?如何做到消息不重复?消息堆积了,处理就延迟了,要怎么解决?消费者如果扩容,消息还能保证被顺序消费么?另外我们常听到的消费者扩容,会重平衡,那什么是重平衡,重平衡会带来什么问题呢?在后面的文章中,我们会继续讨论这些问题。

欢迎关注我的技术公众号:
消息队列一|从秒杀活动开始聊起消息队列_第5张图片

 

你可能感兴趣的:(java,消息队列,高并发)