消息队列

161 阅读2分钟

参考/转载

什么是消息队列

Message Queue. 简称MQ. 顾名思义, 一种盛放消息的队列.

好处

解耦

分析下面一个场景. 系统A, B, C. A生产userId, B, C消费userId.

public class Client {
	public static void main(String[] args) {
    	A a = new A();
        B b = new B();
        C c = new C();
        
        String userId = a.generateUserId();
        b.doSomethingWithUserId(userId);
        c.doSomethingWithUserId(userId);
    }
}

这叫B, C与A系统紧密耦合. 使用消息队列后:

	MQ mq = new MQ();
    mq.push(a.generateUserId());
    String userId = mq.pop();
    for (SystemClient client : who is interested in userId) {
    	client.doSomethingWithUserId(userId);
    }

此时对userId感兴趣的系统只从MQ中获取数据, 不关系数据从哪里来的. 在A系统的概念里, 也就只有MQ一个客户, 他只管把生产的userId放到MQ里面即可.

对MQ来说, 有一个生产者和消费者的概念. 生产者, 就是向MQ增加数据的, 即A; 消费者, 就是从MQ拿数据的, 即B, C.

所谓解耦, 就是MQ作为一个中间件, 将生产者和消费者解耦. 这是设计模式里的中介者.

异步

在某些场景下, A根本不关心自己的货物是被谁消耗的, 当然也不关心货物的消耗是否出现了异常.

比如消费者成功下订单, 那么如果A系统是订单系统的话, A就会生产出一个订单. 而B可能是基于成功的订单发短信的业务. 这个业务是十分耗时的, 而且A根本就不关心发短信业务的成功与否. 退一万步说, 就算B的短信业务没发成功, 难道还会影响订单业务吗? 难道订单系统还要把这个订单退回去不成? 所以说这个场景下, 对订单的生产者来说, 是很适合异步处理的.

异步最大的好处是响应速度. 对A而言, A写完消息队列之后立即返回, 响应时间仅仅是写队列的时间. 不会有串行的B的发短信的业务处理时间.

当然, 如果业务需要知道货物的消费结果, 那就不是非常适用于异步的场景. 但是可以用回调来解决.

削峰

B系统只能承受1000的qps, 但是A系统太给力了, 生产的速度可以达到2000qps. 那么B系统自然会被打跪.

但我们有MQ, 这里MQ的作用是缓冲. 在速度相差很大的IO系统中缓冲和缓存是很常见的. MQ类似. 这时B系统就可以根据自己的需要来从MQ中拉取消息. 当然, 这里也有缓冲满了之后怎么办的问题. 但有MQ做缓冲, 总比B直接承受A的输出要好很多.