ActiveMQ知识点(复习用,待整理)

作用;

1、异步:异步化提升整体系统的吞吐能力
2、解耦:新模块接入时,可以做到最小代码的改动;
3、削峰:设置流量缓冲池,让后端系统按照自身吞吐能力消费,不被冲垮

Queue两种消费方式:

1、同步阻塞方式(receive()):接收者调用MessageConsumer的receive()方式接收消息,receive在接收到消息之前将一直阻塞
2、异步非阻塞方式(onMessage):接受者调用MessageConsumer的setMessageListenerz注册一个消息监听器, 当消息到达后,系统自动调用监听器MessageLister的onMessage()方法

1、先生产1条消息,只启动1号消费者,
问题:1号消费者能消费消息吗?
yes。
2、先生产1条消息,先启动1号消费者再启动2号消费者,
问题:2号消费者能消费消息吗?
1号消费者可以消费,2号消费者不能。
3、先启动2个消费者,再生产6条消息,
问题:请问消费情况如何?
一人一半。

Topic(发布订阅):

1、生产者将消息发送到topic中,每个消息可以有多个消费者
2、生产者和消费者之间有时间上的相关性,订阅某一个topic的消费者只能消费订阅后发布的消息;
3、生产者生产时,topic不保存消息,假如无消费者就去生产,那就是一条废消息,一般先启动消费者再启动生产者;

queue模式队列和topic模式队列
1、工作模式:
queue是负载均衡模式,如果当前没有消费者,消息也不会丢失,如果有多个消费者,一条消息也只会发送给其中一个消费者;
topic是订阅发布模式,如果当前没有消费者,消息会丢失,如果有多个订阅者,订阅者都会接收到消息 ;
2、有无状态:
queue数据默认在MQ服务器上默认是文件形式保存,也可配置成DB存储;
topic是无状态的;
3、传递的完整性:
queue消息不会丢弃;
topic如果没有消费者,消息会被丢弃 ;
4、获取消息的方式:
queue是pull模式,消费者先发送个请求给broker是否有消息,有消息拉取消息;
topic是push,不需要消费者询问,broker会主动把消息发送给订阅者;

拉模式与推模式

a.点对点消息,如果没有消费者在监听队列,消息将保留在队列中,直至消息消费者连接到队列为止
这种消息传递模型是传统意义上的懒模型或轮询模型
在此模型中,消息不是自动推动给消息消费者的,而是要由消息消费者从队列中请求获得(拉模式)

b.pub/sub消息传递模型是一个推模型。在该模型中,消息会自动广播,消息消费者无须通过主动请求或轮询主题的方法来获得新的消息

ActiveMQ消息类型

1、TextMessage 文本消息:携带一个java.lang.String作为有效数据(负载)的消息,可用于字符串类型的信息交换
2、ObjectMessage 对象消息:携带一个可以序列化的Java对象作为有效负载的消息,可用于Java对象类型的信息交换
3、MapMessage 映射消息:携带一组键值对的数据作为有效负载的消息,有效数据值必须是Java原始数据类型(或者它们的包装类)及String
即:byte , short , int , long , float , double , char , boolean , String
4、BytesMessage 字节消息 :携带一组原始数据类型的字节流作为有效负载的消息
5、StreamMessage 流消息:携带一个原始数据类型流作为有效负载的消息,它保持了写入流时的数据类型,写入什么类型,则读取也需要是相同的类型

持久化:

queue持久化:messageProdecer.setDeliveryMode(DeliveryMode.Persistent),默认是持久化。

本地事务:transaction事务偏生产者,acknowledge签收偏消费者
false: 只要执行send,消息就进入到队列中。关闭事务,那第二个参数acknowledge的设置需要有效。
true: 先执行send再执行commit,消息才被真正的提交到队列中。消息需要批量发送,需要缓冲区处理。
事务性消息不管设置何种消息确认模式,都会自动被确认。

注意:生产者 —> broker 和 broker —> 消费者 完全是两个操作,
他们的的事务、acknowledge一点关系也没有,因为他们的生产者和消费者的session一点关系也没有啊!

生产者的事务是保证批量发送给broker,要么一起成功要么一起失败。
消费者的事务保证brokee发送的消息到达消费者。。

事务消息重发机制:

重新传递消息的情况:
1、consumer使用了事务,且在session中调用了rollback();
2、consumer使用了事务,且在调用commit之前关闭;
3、consumer在client_acknowledge模式下,在session中调用了recover();
4、消费者消费消息的时候down了,消息自动转入其他消费者。
默认重发次数为6,重发的时间间隔为1秒;

acknowledge消息确认机制:

消息的成功消费分为三个阶段:
1、consumer从broker接收消息;2、consumer处理消息;3、consumer向broker确认消息已经消费。
有三种策略:
1、默认的自动签收(Session.auto_acknowledge):consumer成功从messageListener.onMessage方法返回,session自动确认消息,broker删除消息。
2、手动签收(Session.client_acknowledge):consumer需要手动调用message.acknowledge()方法确认消息,broker才会删除消息。
3、允许重复消息(Session.dups_ok_acknowledge):不是必须确认,消息可能重复发送。

传输协议:

默认使用的是TCP协议,tcp的默认端口是61616。
推荐使用NIO协议,是基于Tcp协议进行了扩展和优化,具有更好的扩展性。
配置修改:conf目录下的activemq.xml文件的transportConnetors节点下的transportConnector节点name属性改成auto+nio,uri属性改成auto+nio。

可持久化:

1、默认的是kahaDB:基于日志文件。配置在persistenceAdapter节点配置日志文件目录。(默认是${activemq}/data/kahadb/)
2、jdbc:基于第三方数据库,比如mysql,在persistenceAdapter节点,改成jdbc的配置,并配置DataSource。
3、levelDB

kahadb存储使用的是事务日志加索引文件来存储它的所有地址。
db-1.log、db.data、db.free、db.redo、lock
db-num.log: 储存数据到预定义的文件大小中,默认每个文件32M,当数据文件满时一个新的文件会随之创建。当文件中不再有索引引用的数据,文件会被删除。
db.data: 消息的索引文件,使用BTree作为索引指向db-num.log里面存储的消息。
db.redo:用来进行消息恢复的,如果kahaDb消息储存在强制退出后启动,用于恢复BTree索引。
lock: lock文件表示锁,表示获得当前kahadb读写权限的broker。

jdbc存储模式:

有三张表:
1、activemq_msgs: 用于存储消息的表;
2、activemq_acks: 存储订阅关系;
3、activemq_lock: 集群环境中使用,同一时间只能有一个master broker;

如果是queue的话,在没有消费者的情况下会将消息存储在activemq_msgs表中,只要有任何一个消费者消费过了,消费之后这些消息将被清除。
如果是topic的话,普通订阅不会持久化消息,持久化订阅需要先启动生产者再生产消息,之后无论订阅者是否在线,最终都会接收到消息。
不在的话,等到再次连接的时候会将没有收到的消息全部接收处理。

开发注意:

  1. 数据库jar包放到activemq lib目录下;
  2. createTableOnStartup属性启动完成后去掉,或者改为false;
  3. 数据库编码使用latin格式;

可以使用jdbc with journal模式,使用了高速缓存写入技术,大大提高了性能,先写入journal文件再写入数据库。

高可用:

引入消息队列之后该如何保证其高可用?
使用zookeeper + replicated-leveldb-store的主从集群。是基于zookeeper和levelDB搭建的activeMQ集群。
集群提供主备方式的高可用集群功能,避免单点故障。
原理:使用zookeeper集群注册所有的activeMq,但只有其中的一个broker可以提供服务被视为master,
其他broker处于待机状态,被视为slave。如果master不能提供服务,zookeeper会从slave选举一个充当master,
slave连接master并同步它的存储状态,slave不接受客户端的请求。

异步投递:

对于慢的consumer,使用同步发送消息可能造成producer阻塞情况,慢消费者适合异步投递。
activeMQ默认使用的是异步发送的模式,除非明确指定同步发送或在没有使用事务的情况下发送持久化消息,这两个情况是同步的。
使用场景:允许在失败的情况下有少量的数据丢失、发送消息量在比较密集的情况下。
配置:
1、connection uri
2、connectionFactory
3、connection

异步消息如何确定发送成功?
异步发送方式是需要接收回调的。

同步发送和异步发送的区别。
同步发送等send不阻塞了就表示一定发送成功,
异步发送需要接收回调并又client再判断一次是否发送成功。

延时投递:

需要在activemq conf 目录下的activemq.xml文件的broker节点配置 schedulersupport = true;
有四大参数:
amq_scheduler_delay: 延迟投递的时间;
amq_scheduler_period: 重复投递的时间间隔;
amq_scheduler_repeat;重复投递的次数;
amq_scheduler_cron: cron表达式;

死信队列:

有毒消息poison ack:
一个消息超过最大的重发次数(默认为6次)时,消费端会给broker发送“poison ack”,表示这个消息有毒,告诉broker不要再发了
这个时候broker会把这个消息放到死信队列(dead letter queue)
将所有的deadletter保存在一个共享队列中,共享队列默认为ActiveMQ.DLQ

如何保证消息不被重复消费?

准备一个第三方服务来做消费记录,以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以k-v键值对形式存入redis, 那消费者在开始消费之前,先去redis查询有没有消费记录即可

发布了15 篇原创文章 · 获赞 0 · 访问量 67

猜你喜欢

转载自blog.csdn.net/xrzi2015/article/details/105604123
今日推荐