消息队列(mq)解读

什么是消息队列

消息队列,我们简称她为MQ(Message Queue)。
先来看队列(Queue)这个词,它是一种先进先出的数据结构。
在这里插入图片描述
Java里已经实现了很多的队列了,那为什么我们还要消息队列(mq)这种中间件呢,消息队列可以简单的理解为:把要传输的数据放在队列中。

(把数据放到消息队列中的叫做生产者)
(从消息队列中取数据的叫消费者)

为什么要用消息队列

即消息队列的好处:

  1. 解耦
    我最近真的是发现,所有厉害的技术或者设计模式的目的都不外乎 解耦 二字。
    举例:
    现有一个系统A,可以产生userId,系统B, C都需要userId来进行相关操作
    在这里插入图片描述
    伪代码:
public class SystemA {

    // 系统B和系统C的依赖
    SystemB systemB = new SystemB();
    SystemC systemC = new SystemC();

    // 系统A独有的数据userId
    private String userId = "Java3y";

    public void doSomething() {

        // 系统B和系统C都需要拿着系统A的userId去操作其他的事
        systemB.SystemBNeed2do(userId);
        systemC.SystemCNeed2do(userId);

    }
}

如果B和C过于频繁的更改需求(有时不要调用userId,有时需要调用userId),或者多了系统D, E, F, G来调用userId, 那么系统A就需要极其频繁的对自身进行更改。如果,将系统A的userId写到消息队列中,这样系统A就不用经常改动了,就像:
在这里插入图片描述
系统A将userId写到消息队列中,系统C和系统D从消息队列中拿数据。这样有什么好处?

  • 系统A只负责把数据写到队列中,谁想要或不想要这个数据(消息),系统A一点都不关心。
  • 即便现在系统D不想要userId这个数据了,系统B又突然想要userId这个数据了,都跟系统A无关,系统A一点代码都不用改。
  • 系统D拿userId不再经过系统A,而是从消息队列里边拿。系统D即便挂了或者请求超时,都跟系统A无关,只跟消息队列有关。

这样一来,系统A与系统B、C、D都解耦了

  1. 异步
    系统A还是直接调用系统BCD
    在这里插入图片描述
public class SystemA {

    SystemB systemB = new SystemB();
    SystemC systemC = new SystemC();
    SystemD systemD = new SystemD();

    // 系统A独有的数据
    private String userId ;

    public void doOrder() {

        // 下订单
        userId = this.order();
        // 如果下单成功,则安排其他系统做一些事  
        systemB.SystemBNeed2do(userId);
        systemC.SystemCNeed2do(userId);
        systemD.SystemDNeed2do(userId);

    }
}

假设系统A运算出userId具体的值需要50ms,调用系统B的接口需要300ms,调用系统C的接口需要300ms,调用系统D的接口需要300ms。那么这次请求就需要50+300+300+300=950ms

并且我们得知,系统A做的是主要的业务,而系统B、C、D是非主要的业务。比如系统A处理的是订单下单,而系统B是订单下单成功了,那发送一条短信告诉具体的用户此订单已成功,而系统C和系统D也是处理一些小事而已。

这里只有三个其他的系统,如果是真正的下单流程涉及的系统绝对在10个以上(主流电商),越大的越多。

那么此时,为了提高用户体验和吞吐量,其实可以异步地调用系统B、C、D的接口。所以,我们可以弄成是这样的:

在这里插入图片描述
系统A执行完了以后,将userId写到消息队列中,然后就直接返回了(至于其他的操作,则异步处理)。

本来整个请求需要用950ms(同步)
现在将调用其他系统接口异步化,只需要100ms(异步)

  1. 削峰/限流
    假如,现在我们每个月要搞一次大促,大促期间的并发可能会很高的,比如每秒3000个请求。假设我们现在有两台机器处理请求,并且每台机器只能每次处理1000个请求。
    在这里插入图片描述
    那多出来的1000个请求,可能就把我们整个系统给搞崩了…所以,有一种办法,我们可以写到消息队列中:
    在这里插入图片描述
    系统B和系统C根据自己的能够处理的请求数去消息队列中拿数据,这样即便有每秒有8000个请求,那只是把请求放在消息队列中,去拿消息队列的消息由系统自己去控制,这样就不会把整个系统给搞崩。

使用消息队列需要考虑的问题

  1. 数据丢失问题
    我们将数据写到消息队列上,系统B和C还没来得及取消息队列的数据,就挂掉了。如果没有做任何的措施,我们的数据就丢了。
    在这里插入图片描述

  2. 消费者怎么得到消息队列的数据

    消费者怎么从消息队列里边得到数据?有两种办法:

  • 生产者将数据放到消息队列中,消息队列有数据了,主动叫消费者去拿(俗称push)
  • 消费者不断去轮训消息队列,看看有没有新的数据,如果有就消费(俗称pull)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值