什么是消息队列?
就是消息的传输过程中保存消息的容器。
消息队列都解决了什么问题?
异步,并行,解耦,排队
消息模式?
订阅,点对点
重复消费
Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。
丢消息
- 用持久化消息
- 非持久化消息及时处理不要堆积
- 启动事务,启动事务后,commit()方法会负责等待服务器的返回,也就不会关闭连接导致消息丢失。
消息重发
消息被重新传递给客户端:
- 使用事务会话,并调用滚退()。
- 在调用commit()之前关闭事务会话。
- 会话使用CLIENT_ACKNOWLEDGE签收模式,并Session .recover()重发被调用。
- 客户端连接超时(也许正在执行的代码要比配置的超时周期更长)。
什么是ActiveMQ?
activeMQ是一种开源的,面向消息的中间件,用来系统之间进行通信的
activemq的原理
原理就是生产者生产消息, 把消息发送给activemq。 Activemq 接收到消息, 然后查看有多少个消费者, 然后把消息转发给消费者, 此过程中生产者无需参与。 消费者接收到消息后做相应的处理和生产者没有任何关系
对比RabbitMQ
RabbitMQ的协议是AMQP,而ActiveMQ使用的是JMS协议。顾名思义JMS是针对Java体系的传输协议,队列两端必须有JVM,所以如果开发环境都是java的话推荐使用ActiveMQ,可以用Java的一些对象进行传递比如Map、Blob(二进制大数据)、Stream等。而AMQP通用行较强,非java环境经常使用,传输内容就是标准字符串。另外一点就是RabbitMQ用Erlang开发,安装前要装Erlang环境,比较麻烦。ActiveMQ解压即可用不用任何安装。
对比KafKa
Kafka性能超过ActiveMQ等传统MQ工具,集群扩展性好。
弊端是:
- 在传输过程中可能会出现消息重复的情况,
- 不保证发送顺序
- 一些传统MQ的功能没有,比如消息的事务功能。
- 所以通常用Kafka处理大数据日志。
对比Redis
其实Redis本身利用List可以实现消息队列的功能,但是功能很少,而且队列体积较大时性能会急剧下降。对于数据量不大、业务简单的场景可以使用。
如何解决消息重复问题
所谓消息重复,就是消费者接收到了重复的消息,一般来说我们对于这个问题的处理要把握下面几点,
- 消息不丢失
- 消息不重复执行
一般来说我们可以在业务段加一张表,用来存放消息是否执行成功,每次业务事物commit之后,告知服务端,已经处理过该消息,这样即使你消息重发了,也不会导致重复处理,大致流程如下:业务端的表记录已经处理消息的id,每次一个消息进来之前先判断该消息是否执行过,如果执行过就放弃,如果没有执行就开始执行消息,消息执行完成之后存入这个消息的id