消息队列---ActiveMQ

ActiveMQ       java语言写的和java系统紧密结合

RabbitMQ       Erang写的,天生支持并发,非java系统的首选,优于ActiveMQ

ZeroMQ          内存中使用,不支持持久化,多用于金融场景

RocketMQ      阿里开源中间件   专门为java系统定制   现已捐赠给Apache

Kafka              天生设计为分布式,很方便扩展,超高并发   推荐java使用

 

MQ的消息可靠性传输

ACK机制  ACKONWLEDGE   通知确认

  

producer发送destination,broker收到之后会返回一个ACK,如果producer没有收到ACK那么会重新发送消息,一般会限制一个重试次数。(默认是6次)

如果做了集群的话,broker之间传输也会有ACK机制。

同样Consumer也有ack机制,成功接受消息之后返回ACK,Broker成功接收ACK之后删除消息,否则同样发起重试。

 

AUTO_ACKNOWLEDGE = 1               自动确认

CLIENT_ACKNOWLEDGE = 2            客户端手动确认                    (如果使用了JMS那么即是设置了客户端手动确认,那也是自动确认源码中实现了)

DUPS_OK_ACKNOWLEDGE = 3        自动批量确认

SESSION_TRANSACTED = 0             事务提交并确认

此外ActiveMQ补充了一个自定义的ACK

INDIVIDUAL_ACKNOWLEDGE = 4     单条消息确认

 

问题:broker成功收到消息而且向下执行成功,但是发送ACK的时候出现问题(例如网络问题)导致ACK没有发送成功,那么producer又重新请求了一次,又产生了新的业务逻辑。

幂等:多次调用或者说消息多次发送和一次调用结果一致。(这是一个宏观的概念不仅限于消息队列)

    实现:例如一条消息对应一个messageId存入broker。

Consumer去消费消息有两种 方式:

  push:当broker收到消息之后主动将消息推送给Consumer    消息比较及时实现代价比较大     设置perfetch 0

  pull:Consumer去拉取消息(轮询)    轮询消耗资源  有延迟

 

消息持久化

在配置文件activemq.xml中的 persistenceAdapter 标签实现持久化

<persistenceAdapter>
  <kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>

持久化默认是打开的!(可以配置,也可以在代码中设置)重要消息持久化,不重要的可以考虑不持久化  

所有的发送数据会有一个Data Logs,为了提高访问速率为Data Logs提供了一个BTree的索引(Metadata Store)有一份索引是在内存中的(Metadata Cache)。

持久化发生在什么时候?

  在broker接受到消息之后,会先将消息进行持久化(可靠介质,MySQL、kahaDB[默认]),持久化成功之后才会返回ACK。

 

还有另一种持久化:

topic模式:

  持久化订阅者:一直保持链接,服务挂了之后也可以接受消息。

  非持久化订阅者:服务挂了就不接受消息。

 

ActiveMQ高可用

 


高可用配置(主从):

kahaDB目录中有一个lock文件,谁抢到锁谁就是master,修改activemq.xml配置文件的openwire端口号,修改jetty配置文件的端口号,然后 两个配置文件的kahaDB文件目录要一致

高可用配置(集群负载均衡):

  缺点:当消息刚刚发送到node1但是Consumer还没来得及消费,node1就挂掉造成消息丢失。

posted @ 2018-08-13 20:23  Gggoblin  阅读(199)  评论(0编辑  收藏  举报