1.消息队列解决什么问题?
a.异步处理,对于一些实时性要求不是很强的业务(短信,邮件)可以用消息队列来异步处理,提高系统响应效率。
b.应用耦合,减少应用的耦合性,比如订单系统和库存系统之间通过消息队列分离开来,即使库存系统暂时不可用,也不影响订单系统的使用。
c.流量削锋,秒杀系统等并发量比较高的情况,为了防止系统卡死,可利用消息队列来排队。如果队列过长,还可以控制不再写入队列。
b.消息通讯,实现点对点或者发布/订阅模式的消息通信。
2.消息模型。
a.P2P(Point to Point),三个角色,消息队列(Queue),消息发送者(Sender),消息接收者(Receiver)。
b.Publish/Subscribe(Pub/Sub),三个角色,主题(Topic), 发布者(Publisher),订阅者(Subscriber)。多个发布者将消息发布到主题,多个订阅者从主题中拿到订阅的消息。
3.常用的消息队列。
a.JMS(Java Message Service).
b.Active MQ
c.Rabbit MQ
d.Rocket MQ
f.Kafka
4.消息队列的几个关键问题。
a.消息的顺序问题
首先我们应该了解,大部分的业务是不需要保证消息的顺序的。如果一定要严格保证消息的顺序,不同的技术的实现方案大同小异。
需要保证顺序的消息放入同一个队列中并单一线程来消费消息,因为队列是先进先出的,从而保证消息的顺序性。比喻:创建订单,付款,订单完成,可按照订单号来放入同一队列,单一线程来按顺序执行消息。但这样会牺牲效率。
b.消息的重复问题
首先我们也应该了解,我们大多数情况应该保证消息的幂等性,这样就不用害怕消息的重复问题了。如果消息不能设计成幂等的,可按照下面的方案来。
保证每条消息有一个唯一的ID,消费成功的消息记录下来,每次消费消息的时候和成功的记录进行比较,如果消费过就不消费。
c.事务消息
大部分情况下,是不需要事务消息的,如果非要实现事务消息,可按照下面的方案来实现。
我们来看个例子,就已转账为例,A账户转100块钱到B账户分为三个步骤:1,A账户扣100 2,发送消息 3,B账户增加100。1步骤失败直接事务回滚,2步骤发送消息失败,同样直接事务回滚 3步骤增加失败,最好不回滚,人工解决,因为这个情况太少。