持久化

持久化可以在创建生产者之后再开启:

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();
    }
}