ActiveMQ消息签收机制代码实例详解

 更新时间:2020年02月21日 14:41:49   作者:流氓大队长  
这篇文章主要介绍了ActiveMQ消息签收机制代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

这篇文章主要介绍了ActiveMQ消息签收机制代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

消费者客户端成功接收一条消息的标志是:这条消息被签收。

消费者客户端成功接收一条消息一般包括三个阶段:

1、消费者接收消息,也即从MessageConsumer的receive方法返回

2、消费者处理消息

3、消息被签收

其中,第三阶段的签收可以有ActiveMQ发起,也可以由消费者客户端发起,取决于Session是否开启事务以及签收模式的设置。

在带事务的Session中,消费者客户端事务提交之时,消息自动完成签收。

在不带事务的Session中,消息何时以及如何被签收取决于Session的签收模式设置

非事务Session可以设置如下几种签收模式:

1.Session.AUTO_ACKNOWLEDGE

当消息从MessageConsumer的receive方法返回或者从MessageListener接口的onMessage方法返回时,会话自动确认消息签收

2.Session.CLIENT_ACKNOWLEDGE

需要消费者客户端主动调用acknowledge方法签收消息,这种模式实在Session层面进行签收的,签收一个已经消费的消息会自动的签收这个Session已消费的所有消息:

例如一个消费者在一个Session中消费了5条消息,然后确认第3条消息,所有这5条消息都会被签收

3.Session.DUPS_OK_ACKNOWLEDGE

这种方式允许JMS不必急于确认收到的消息,允许在收到多个消息之后一次完成确认,与Auto_AcKnowledge相比,这种确认方式在某些情况下可能更有效,因为没有确认,当系统崩溃或者网络出现故障的时候,消息可以被重新传递.

这种方式会引起消息的重复,但是降低了Session的开销,所以只有客户端能容忍重复的消息才可使用。(如果ActiveMQ再次传送同一消息,那么消息头中的JMSRedelivered将被设置为true)

带事务session的案例

  生产者

    必须在生产完数据之后手动提交session

package com.wn.ddd;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

public class Producter {
 public static void main(String[] args) throws JMSException {
  // ConnectionFactory :连接工厂,JMS 用它创建连接
  ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
    ActiveMQConnection.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616");
  // JMS 客户端到JMS Provider 的连接
  Connection connection = connectionFactory.createConnection();
  //启动连接
  connection.start();
  // Session: 一个发送或接收消息的线程 false:代表不带事务的session AUTO_ACKNOWLEDGE:代表自动签收
  Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
  // Destination :消息的目的地;消息发送给谁.
  // 获取session注意参数值my-queue是Query的名字
  Queue queue = session.createQueue("my-queue");
  // MessageProducer:创建消息生产者
  MessageProducer producer = session.createProducer(queue);
  // 设置不持久化 PERSISTENT:代表持久化 NON_PERSISTENT:代表不持久化
  producer.setDeliveryMode(DeliveryMode.PERSISTENT);
  // 发送消息
  for (int i = 1; i <= 5; i++) {
   sendMsg(session, producer, i);
  }
  System.out.println("发送成功!");
  session.commit();
  session.close();
  connection.close();
 }
 /**
  * 在指定的会话上,通过指定的消息生产者发出一条消息
  *
  * @param session
  *   消息会话
  * @param producer
  *   消息生产者
  */
 public static void sendMsg(Session session, MessageProducer producer, int i) throws JMSException {
  // 创建一条文本消息
  TextMessage message = session.createTextMessage("Hello ActiveMQ!" + i);
  // 通过消息生产者发出消息
  producer.send(message);
 }
}

  消费者

    消费完数据之后必须手动提交session

package com.wn.ddd;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsReceiver {
 public static void main(String[] args) throws JMSException {
  // ConnectionFactory :连接工厂,JMS 用它创建连接
  ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
    ActiveMQConnection.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616");
  // JMS 客户端到JMS Provider 的连接
  Connection connection = connectionFactory.createConnection();
  connection.start();
  // Session: 一个发送或接收消息的线程 true:表单开启事务 AUTO_ACKNOWLEDGE:代表自动签收
  Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
  // Destination :消息的目的地;消息发送给谁.
  // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
  Queue queue = session.createQueue("my-queue");
  // 消费者,消息接收者
  MessageConsumer consumer = session.createConsumer(queue);
  while (true) {
   //receive():获取消息
   TextMessage message = (TextMessage) consumer.receive();
   if (null != message) {
    System.out.println("收到消息:" + message.getText());
    session.commit();
   } else {
    break;
   }
  }
  //回收资源
  session.close();
  connection.close();
 }
}

不带事务session的案例

  1.自动签收

  2.手动签收

    生产者

package com.wn.ddd;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

public class Producter {
 public static void main(String[] args) throws JMSException {
  // ConnectionFactory :连接工厂,JMS 用它创建连接
  ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
    ActiveMQConnection.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616");
  // JMS 客户端到JMS Provider 的连接
  Connection connection = connectionFactory.createConnection();
  //启动连接
  connection.start();
  // Session: 一个发送或接收消息的线程 false:代表不带事务的session AUTO_ACKNOWLEDGE:代表自动签收
  /* Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);*/
  Session session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
  // Destination :消息的目的地;消息发送给谁.
  // 获取session注意参数值my-queue是Query的名字
  Queue queue = session.createQueue("my-queue");
  // MessageProducer:创建消息生产者
  MessageProducer producer = session.createProducer(queue);
  // 设置不持久化 PERSISTENT:代表持久化 NON_PERSISTENT:代表不持久化
  producer.setDeliveryMode(DeliveryMode.PERSISTENT);
  // 发送消息
  for (int i = 1; i <= 5; i++) {
   sendMsg(session, producer, i);
  }
  System.out.println("发送成功!");
  session.close();
  connection.close();
 }
 /**
  * 在指定的会话上,通过指定的消息生产者发出一条消息
  *
  * @param session
  *   消息会话
  * @param producer
  *   消息生产者
  */
 public static void sendMsg(Session session, MessageProducer producer, int i) throws JMSException {
  // 创建一条文本消息
  TextMessage message = session.createTextMessage("Hello ActiveMQ!" + i);
  // 通过消息生产者发出消息
  producer.send(message);
     message.acknowledge();  //手动提交
  } 
}

    消费者

package com.wn.ddd;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import sun.plugin2.os.windows.SECURITY_ATTRIBUTES;

import javax.jms.*;

public class JmsReceiver {
 public static void main(String[] args) throws JMSException {
  // ConnectionFactory :连接工厂,JMS 用它创建连接
  ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
    ActiveMQConnection.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616");
  // JMS 客户端到JMS Provider 的连接
  Connection connection = connectionFactory.createConnection();
  connection.start();
  // Session: 一个发送或接收消息的线程 true:表单开启事务 AUTO_ACKNOWLEDGE:代表自动签收
  /*Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);*/
  Session session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
  // Destination :消息的目的地;消息发送给谁.
  // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
  Queue queue = session.createQueue("my-queue");
  // 消费者,消息接收者
  MessageConsumer consumer = session.createConsumer(queue);
  while (true) {
   //receive():获取消息
   TextMessage message = (TextMessage) consumer.receive();
   if (null != message) {
    System.out.println("收到消息:" + message.getText());
    message.acknowledge();  //手动提交
   } else {
    break;
   }
  }
  //回收资源
  session.close();
  connection.close();
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot内部外部配置文件加载顺序解析

    SpringBoot内部外部配置文件加载顺序解析

    这篇文章主要介绍了SpringBoot内部外部配置文件加载顺序解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • @RefreshScope 自动刷新配置文件的实例讲解

    @RefreshScope 自动刷新配置文件的实例讲解

    efreshScope(org.springframework.cloud.context.scope.refresh)是spring cloud提供的一种特殊的scope实现,用来实现配置、实例热加载,这篇文章主要介绍了@RefreshScope 自动刷新配置文件,需要的朋友可以参考下
    2022-11-11
  • java使用RestTemplate封装post请求方式

    java使用RestTemplate封装post请求方式

    这篇文章主要介绍了java使用RestTemplate封装post请求方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • java 数据类型有哪些取值范围多少

    java 数据类型有哪些取值范围多少

    这篇文章主要介绍了java 数据类型有哪些取值范围多少的相关资料,网上关于java 数据类型的资料有很多,不够全面,这里就整理下,需要的朋友可以参考下
    2017-01-01
  • Java集合包中的fail fast机制详解

    Java集合包中的fail fast机制详解

    这篇文章主要介绍了Java集合包中的fail fast机制详解,当我们使用iterator迭代器遍历一个集合的过程中,如果其它线程,或者它自己向这个集合新增或删除了一个key-value,那么当前线程就会抛出ConcurrentModificationException异常,需要的朋友可以参考下
    2023-12-12
  • 基于Mybatis-Plus的CRUD的实现

    基于Mybatis-Plus的CRUD的实现

    这篇文章主要介绍了基于Mybatis-Plus的CRUD的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • java通过实例了解值传递和引用传递

    java通过实例了解值传递和引用传递

    这篇文章主要介绍了java通过实例了解值传递和引用传递,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • SpringBoot+Mybatis实现登录注册的示例代码

    SpringBoot+Mybatis实现登录注册的示例代码

    这篇文章主要介绍了SpringBoot+Mybatis实现登录注册的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 云IDE:Eclipse Che:Eclipse下一代IDE(推荐)

    云IDE:Eclipse Che:Eclipse下一代IDE(推荐)

    这篇文章主要介绍了云IDE:Eclipse Che:Eclipse下一代IDE,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Spring MVC 图片的上传和下载功能

    Spring MVC 图片的上传和下载功能

    SSM 框架是一种基于Java的Web开发框架,其中Spring作为控制层、SpringMVC作为视图层、MyBatis作为持久层,这个框架非常适合Web应用程序的开发,这篇文章主要介绍了Spring MVC 图片的上传和下载功能,需要的朋友可以参考下
    2023-03-03

最新评论