什么是消息队列
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的输出要好很多.