ActiveMQ消息签收机制:

客戶端成功接收一条消息的标志是一条消息被签收,成功应答。

消息的签收情形分两种:

1、带事务的session

如果session带有事务,并且事务成功提交,则消息被自动签收。如果事务回滚,则消息会被再次传送。

2、不带事务的session

不带事务的session的签收方式,取决于session的配置。

Activemq支持一下三種模式:

Session.AUTO_ACKNOWLEDGE  消息自动签收

Session.CLIENT_ACKNOWLEDGE  客戶端调用acknowledge方法手动签收

textMessage.acknowledge();//手动签收

Session.DUPS_OK_ACKNOWLEDGE 不是必须签收,消息可能会重复发送。在第二次重新传送消息的时候,消息

只有在被确认之后,才认为已经被成功地消费了。消息的成功消费通常包含三个阶段:客户接收消息、客户处理消息和消息被确认。 在事务性会话中,当一个事务被提交的时候,确认自动发生。在非事务性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement mode)。该参数有以下三个可选值:

Number Of Consumers  消费者 这个是消费者端的消费者数量

Number Of Pending Messages 等待消费的消息 这个是当前未出队列的数量。可以理解为总接收数-总出队列数 
Messages Enqueued 进入队列的消息  进入队列的总数量,包括出队列的。 这个数量只增不减 
Messages Dequeued 出了队列的消息  可以理解为是消费这消费掉的数量

默认JMS默认自动签收,消费者获取到消息之后,不管消费者对该消息处理业务逻辑是否成功,都会默认已经消费的。

手动签收模式,消息中间件将消息推送给消费者,消费者接收到消息之后,必须手动发送命令告诉消息中间件已经消费成功

当消息被消费了,消息中间件依然还存在着呢

需要调用:

textMessage.acknowledge();//手动签收

手动签收

生产者依然:  Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);    //自动签收

但是消费者 :Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);  //手动签收

  textMessage.acknowledge();  //告诉中间件 已经消费了

完整代码

package com.toov5.producer;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class producerTest {
// mq通讯地址
private static String url = "tcp://192.168.91.6:61616";
// 队列名称
private static String queueName = "toov5_queue"; public static void main(String[] args) throws JMSException {
// 先创建连接工厂 密码默认采用admin admin
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);
// 创建连接
Connection connection = activeMQConnectionFactory.createConnection();
// 启动连接
connection.start();
// 创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 是否需要事务方式提交 消费方式默认自动签收
// 拿到session 创建目标 创建队列
Queue queue = session.createQueue(queueName);
// 创建生产者
MessageProducer producer = session.createProducer(queue); // 生产者生产的消息 是放在这个queue里面的
producer.setDeliveryMode(DeliveryMode.PERSISTENT); //默认非持久化的 设置持久化
for (int i = 0; i < 10; i++) {
// 拿到队列 创建消息
TextMessage textMessage = session.createTextMessage("消息内容" + i);
// 发送消息
producer.send(textMessage);
}
// 关闭连接
connection.close();
System.out.println("消息发送完毕");
} }
package com.toov5.producer;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class consumerTest {
// mq通讯地址
private static String url = "tcp://192.168.91.6:61616";
// 队列名称
private static String queueName = "toov5_queue"; public static void main(String[] args) throws JMSException {
// 先创建连接工厂 密码默认采用admin admin
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);
// 创建连接
Connection connection = activeMQConnectionFactory.createConnection();
// 启动连接
connection.start();
// 创建会话
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); // 是否需要事务方式提交 消费方式默认自动签收
// 拿到session 创建目标 创建队列
Queue queue = session.createQueue(queueName); //创建消费者
MessageConsumer consumer = session.createConsumer(queue);
//启动监听 监听消息
consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) {
//强制转换
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("consumer 消费 producer:"+textMessage.getText());
textMessage.acknowledge(); //告诉中间件 已经消费了
} catch (JMSException e) { e.printStackTrace();
}
}
});
//监听时候 不要关闭连接 关闭就不监听了 一只处于监听状态 (长连接) } }

以事务形式发送或者签收 (要不中间件是没有这些消息的)

producer:

package com.toov5.producer;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class producerTest {
// mq通讯地址
private static String url = "tcp://192.168.91.6:61616";
// 队列名称
private static String queueName = "toov5_queue"; public static void main(String[] args) throws JMSException {
// 先创建连接工厂 密码默认采用admin admin
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);
// 创建连接
Connection connection = activeMQConnectionFactory.createConnection();
// 启动连接
connection.start();
// 创建会话
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); // 以事务方式提交 消费方式默认自动签收
// 拿到session 创建目标 创建队列
Queue queue = session.createQueue(queueName);
// 创建生产者
MessageProducer producer = session.createProducer(queue); // 生产者生产的消息 是放在这个queue里面的
producer.setDeliveryMode(DeliveryMode.PERSISTENT); //默认非持久化的 设置持久化
for (int i = 0; i < 10; i++) {
// 拿到队列 创建消息
TextMessage textMessage = session.createTextMessage("消息内容" + i);
// 发送消息
producer.send(textMessage);
session.commit(); //提交事务
}
// 关闭连接
connection.close();
System.out.println("消息发送完毕");
} }

consumer

package com.toov5.producer;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class consumerTest {
// mq通讯地址
private static String url = "tcp://192.168.91.6:61616";
// 队列名称
private static String queueName = "toov5_queue"; public static void main(String[] args) throws JMSException {
// 先创建连接工厂 密码默认采用admin admin
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);
// 创建连接
Connection connection = activeMQConnectionFactory.createConnection();
// 启动连接
connection.start();
// 创建会话
final Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); // 是否是以事务方式提交 消费方式默认自动签收 启动事务
// 拿到session 创建目标 创建队列
Queue queue = session.createQueue(queueName); //创建消费者
MessageConsumer consumer = session.createConsumer(queue);
//启动监听 监听消息
consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) {
//强制转换
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("consumer 消费 producer:"+textMessage.getText());
// textMessage.acknowledge();
session.commit(); //提交事务
} catch (JMSException e) { e.printStackTrace();
}
}
});
//监听时候 不要关闭连接 关闭就不监听了 一只处于监听状态 (长连接) } }

以上所用到的pom依赖

    <dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
</dependencies>

  

如果生产者事务形式提交消息,消费者以事务形式接受消息

消费者 第一次运行, 但是没有标记已消费

第二次运行,如果生产者有先的消息继续发送,消费者接收每个消息都commit,标记为已消费。  (自己试玩玩把)

手动签收比较推荐下哈~

JMS消息可靠机制的更多相关文章

  1. ActiveMQ的JMS消息可靠机制

    JMS消息可靠机制 ActiveMQ消息签收机制: 客戶端成功接收一条消息的标志是一条消息被签收,成功应答. 消息的签收情形分两种: 1.带事务的session 如果session带有事务,并且事务成 ...

  2. JMS消息传输机制

    JMS消息传送模型: 消息传送机制, 是基于拉取(pull)或者轮询(polling)的方式.  JMS具备两种"消息传送模型": P2P和Pub/sub. (1) P2P:点对点 ...

  3. Storm消息可靠机制

    一:介绍 1.介绍 默认情况是,Spout每获取一条数据,封装后发送给后面的组件,不再管后面是否处理完成或成功接收,不再考虑. 这种的情况是不用太精确,没有启用可靠性消息机制. 2.方面的体现 spo ...

  4. 学习ActiveMQ(六):JMS消息的确认与重发机制

    当我们发送消息的时候,会出现发送失败的情况,此时我们需要用到activemq为我们提供了消息重发机制,进行消息的重新发送.那么我们怎么知道消息有没有发送失败呢?activemq还有消息确认机制,消费者 ...

  5. Storm消息可靠处理机制

    在很多应用场景中,分布式系统的可靠性保障尤其重要.比如电商平台中,客户的购买请求需要可靠处理,不能因为节点故障等原因丢失请求:比如告警系统中,产生的核心告警必须及时完整的知会监控人员,不能因为网络故障 ...

  6. Rabbitmq可靠消息投递,消息确认机制

    前言 我们知道,消息从发送到签收的整个过程是 Producer-->Broker/Exchange-->Broker/Queue-->Consumer,因此如果只是要保证消息的可靠投 ...

  7. Activemq消息确认机制 --转载

      转自:http://blog.csdn.net/czp11210/article/details/47022639 ActiveMQ消息传送机制以及ACK机制详解 AcitveMQ是作为一种消息存 ...

  8. JMS消息通信服务

    什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中 ...

  9. ActiveMQ的几种消息持久化机制

    为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制. ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式 ...

随机推荐

  1. url 传中文

    if (null == keyword || keyword.equals("关键字")) keyword = ""; if(keyword.length()& ...

  2. vscode Python Pylint(代码检测插件)

    暑假刚开始想了解一下Python,使用vscode进行编写,根据vscode 的提示安装了一些不知道干啥的插件,编写过程中提示说  "Linter pylint is not install ...

  3. 转 FreeBSD通过PORTS安装软件的几个常用命令

    1.怎样找到我想安装的包路径:# cd /usr/ports# make search name=mysql2.仅仅下载源码包,而不安装:# cd /usr/ports/directory# make ...

  4. Android组件间通信库EventBus学习

    项目地址:   https://github.com/greenrobot/EventBus EventBus主要特点 1. 事件订阅函数不是基于注解(Annotation)的,而是基于命名约定的,在 ...

  5. 菜鸟运维笔记:配置Apache二级域名及WWW訪问

    事实上www訪问也能够理解为二级域名的一种. 域名 比方.com..org..edu..gov..info..net等等都是一级域名,或称顶级域名. 其详细格式是 *.顶级域名,比方csdn.net. ...

  6. (LeetCode)两个链表的第一个公共节点

    LeetCode上面的题目例如以下: Write a program to find the node at which the intersection of two singly linked l ...

  7. Dell 刀片服务器CentOS6.5mini开机20~30分钟宕机

    今天查看系统日志发现大量的nf_conntrack: table full, dropping packet. 错误 cat /var/log/messages | moreJun  7 09:52: ...

  8. POJ 1787 Charlie&#39;s Change

    多重背包 可行性+路径记录 题意是说你要用很多其它的零钱去买咖啡.最后输出你分别要用的 1,5 ,10 .25 的钱的数量. 多重背包二进制分解.然后记录下 这个状态.最后逆向推就可以. #inclu ...

  9. Git 自己的一些工作中的总结

    这个网址很重要:https://gitee.com/progit/2-Git-%E5%9F%BA%E7%A1%80.html#2.4-%E6%92%A4%E6%B6%88%E6%93%8D%E4%BD ...

  10. python知识点导图(搜集)

    第一章 基本环境 第二章 内置类型 第三章 表达式 第四章 函数 第五章 迭代器 第六章 模块 第七章 类 第八章 异常 第九章 装饰器 第十章 描述符 第十一章 元类 第十二章 标准库 Re模块 附 ...