ActiveMQ学习(二)
文章目录
什么是JMS(Java Message Service)
JMS,Java消息服务,是JavaEE中的一个技术。指的是两个应用程序之间异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于指出Java应用程序的开发。在JavaEE中,当两个应用程序使用JMS进行通信时,他们之间并不是直接相连的,而是通过一个共同的消息收发服务组件关联起来,以达到解耦/异步/削峰的效果。
JMS组成的四大元素
JMS provider
实现JMS接口和规范的消息中间件,也就是我们的MQ服务器
JMS producer
消息生产者,创建和发送JMS消息的客户端应用
JMS consumer
消息消费者,接收和处理JMS消息的客户端应
JMS message(由三部分组成,消息头、消息体、消息属性)
- 消息头
- JMSDestination:消息发送的目的地,主要是指Queue和Topic
- JMSDeliveryMode:持久模式和非持久模式
一条持久性的消息:应该被传送“仅仅一次”,这就意味着如果JMS提供者出现故障,该消息并不会丢失,他会在服务器恢复后再次传递
一条非持久的消息:最多会传送一次,这意味着这服务器出现故障,该消息将永远丢失- JMSExpiration:消息过期时间,可以设置消息在一定时间后过期,默认是永不过期
消息过期时间,等于Destination的send方法中的timeToLive值加上发送时刻的GMT时间值。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则消息被清除。
- JMSPriority:消息优先级,从0-9是个级别,0到4是普通消息,5到9是加急消息,JMS不要求MQ严按照这十个优先级发送消息,但必须保证加急消息要先与普通消息到达。默认是4级。
- JMSMessageID:唯一识别每个消息的标识由MQ产生
消息头的设置,可以像上图DeliveryMode设置一样,通过Message调用set**()方法设置,也可以在send()方法中一起设置
- 消息体
- 封装具体的消息数据
- 5种消息体格式
- TextMessage:普通的字符串消息,包含一个String
- MapMessage:一个Map类型的消息,key为String,值为Java的基本类型
- BytesMessage:二进制数组消息,包含一个byte[]
- StreamMessage:Java数据流,用标准流操作来顺序填充和读取
- ObjectMessage:对象消息,包含一个可序列化的Java对象
- 发送和接收的消息体类型必须一致对应
- 消息属性
- 如果需要除消息头字段以外的值,那么可以使用消息属性。识别/去重/重点标注等操作非常有用的方法
- 如果需要除消息头字段以外的值,那么可以使用消息属性。识别/去重/重点标注等操作非常有用的方法
JMS的可靠性
一、持久化
持久化和非持久化,当服务器宕机后,持久化的消息在服务器重启后依然可以消费得到,而非持久化的消息则会永远丢失了
queue的持久化
- 可以通过textMessage.setDeliveryMode(DeliverryMode.PERSISTENT)来设置
- queue 默认是持久化的
topic的持久化
topic持久化的代码和queue不一样,要进行修改。
生产者:
创建生产者之后,设置持久化策略
MessageProducer producer = session.createProducer(topic);
producer.setDeliveryMode(DeliveryMode.PERSISTENT)
连接启动放在持久化之后
connection.start();
消费者(订阅者):
通过连接工厂,获得连接并设置clientId,不设置无法创建消费者(订阅者)
Connection connection = connectionFactory.createConnection();
connection.setClientID("z3");
得到topic后,创建持久化的消费者(订阅者),再启动连接,启动连接放在持久化之后
TopicSubscriber durableSubscriber = session.createDurableSubscriber(topic, "xixi");
connection.start();
测试:
先启动消费者(订阅者),在启动生产者,观察控制台
- 首先在topic中,会产生一个消费者,并且与之前的topic的消费者不同,不会随着消费者断开连接而消失(就是框中的1,一直存在)
- 其次在subscribers中,产生了一条记录,当消费者在线时,记录在Active Durable Topic Subscribers那一栏中,离线时,在Offline Durable Topic Subscribers中。
- 在第一次启动消费者之后,即使当消费者在离线状态下,生产者发送了消息,当消费者上线后,会把之前的消息接收到
这里的消息是指,从消费者第一次启动后,没有接收到的消息
总结:
- 第一次消费者启动后,就相当于向MQ注册了,所以topic中会一直存在这个消费者,因此存在消费者在线离线的状态。
- 无论消费者是否在线,都会接收到,不在线的话,下次连接的时候,会把没有收到的消息接收下来。
- topic默认是非持久化的,在ActiveMQ学习(一)中讲过。
二、事务
事务偏生产者
producer
两个参数,第一个叫事务,第二个叫签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
false:关闭事务,那第二个签收参数的设置需要有效,只要执行了send方法,就进入到队列中。
producer.send(textMessage);
true:消息需要批量发送,需要缓存区处理。先执行send,再执行commit,消息才真正提交到队列中
try {
session.commit();
}catch (Exception e){
session.rollback();
}finally {
if (session!=null)
session.close();
}
consumer:
两个参数,第一个叫事务,第二个叫签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
用法与生产者一样.
三、签收
签收偏消费者 , 对生产者的设置意义不大,但是由于creatSession方法必须要传两个参数,所以生产者一般设置Session.AUTO_ACKNOWLEDGE
四种签收方式,常用的是前面两种,自动签收AUTO_ACKNOWLEDGE和手动签收CLIENT_ACKNOWLEDGE
非事务签收
若是AUTO_ACKNOWLEDGE , 则不需要人为去操作,收到消息后自动签收;
若是开启了手动签收
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
则必须在收到消息后,手动签收, 否则消息会重复消费
textMessage.acknowledge();
事务签收
假如开启了事务, 则无论是自动签收还是手动签收, 只要没有session.commit(), 即事务没有提交 , 则消息都会重复消费 .粗略地来讲 ,就是事务地作用范围大于签收
总结
JMS的点对点总结
JMS的发布订阅总结
按照配置文件启动activemq
命令 : 在bin下 , 执行 ./activemq start xbean:file:**(activemq的安装路径)/conf/active02.xml (配置文件的存放路径)
上一篇: 矩阵Gauss消除法解线性方程