持久化
持久化可以在创建生产者之后再开启:
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
DeliveryNode的源码如下:
package javax.jms;
public interface DeliveryMode {
//非持久化
static final int NON_PERSISTENT = 1;
//持久化
static final int PERSISTENT = 2;
}
1 参数设置说明
- 持久化:当服务器宕机后,消息依然存在,当服务器再次启动,消息就会被消费
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
- 非持久化:当服务器宕机,消息不存在
messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
2 queue模式
默认持久化,此模式保证这些消息只被传送一次和成功使用一次,对于这些消息,可靠性是优先考虑的因素。
3 topic模式
一定要先运行一次消费者,等于向MQ注册,类似于我订阅了这个主题。
然后再运行生产者发送消息。
此时无论消费者是否在线,都会接收到,不在线的话,下次连接的时候,会把没有收过的消息接收下来。
非持久订阅状态下,不能恢复或重新派送一个未签收的消息。
持久订阅才能恢复或者重新派送一个未签收的消息。
事务
事务是在创建session的时候选择是否开启,connection.createSession方法的第一个参数为 true 则开启事务。
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
需在session关闭之前手动提交.session.commit();
try{
//ok
session.commit();//提交
}catch(Exception e){
//printStackTrace()
//error
Session.rollback(); //回滚
}finally{
if(null!=session){
session.close();
}
}
生产者中开启事务,session.commit()提交之后发布的消息才会入队。
消费者中开启事务,session.commit()提交之后消费的消息才会出队。
开启事务的意义
事务开启的意义在于,如果对于多条必须同批次传输的消息,可以使用事务,如果一条传输失败,可以将事务回滚,再次传输,保证数据的完整性。
对于消息消费者来说,开启事务的话,可以避免消息被多次消费,以及后台和服务器数据的不一致性。举个栗子:如果消息消费的 createSession 设置为 ture ,但是没有 commit ,此时就会造成非常严重的后果,那就是在后台看来消息已经被消费,但是对于服务器来说并没有接收到消息被消费,此时就有可能被多次消费。
签收
非事务
Session.AUTO_ACKNOWLEDGE 自动签收,默认
Session.CLIENT_ACKNOWLEDGE 手动签收
手动签收需要acknowledge
textMessage.acknowledge();
事务
对于开启事务时,设置手动签收和自动签收没有多大的意义,都默认自动签收,也就是说事务的优先级更高一些。但是开启事务没有commit就会重复消费。
Broker
Broker 就是实现了用代码形式启动 ActiveMQ 将 MQ 内嵌到 Java 代码中,可以随时启动,节省资源,提高了可靠性。就是将 MQ 服务器作为了 Java 对象。
把小型 activemq 服务器嵌入到 java 代码: 不在使用linux 的服务器
需要的包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
代码实现
public class Embebroker {
public static void main(String[] args) throws Exception {
// broker 服务
BrokerService brokerService = new BrokerService();
// 把小型 activemq 服务器嵌入到 java 代码
brokerService.setUseJmx(true);
// 原本的是 192.…… 是linux 上的服务器,而这里是本地windows 的小型mq 服务器
brokerService.addConnector("tcp://localhost:61616");
brokerService.start();
}
}