当我们发送消息的时候,会出现发送失败的情况,此时我们需要用到activemq为我们提供了消息重发机制,进行消息的重新发送。那么我们怎么知道消息有没有发送失败呢?activemq还有消息确认机制,消费者在接收到消息的时候可以进行确认。本节将确认机制和重发机制一起在原有的代码中学习。

消息确认机制有四种:定义于在session对象中

AUTO_ACKNOWLEDGE= 1 :自动确认

CLIENT_ACKNOWLEDGE= 2:客户端手动确认

UPS_OK_ACKNOWLEDGE= 3: 自动批量确认

SESSION_TRANSACTED= 0:事务提交并确认

但是在activemq补充了一个自定义的ACK模式:

INDIVIDUAL_ACKNOWLEDGE= 4:单条消息确认

首先在配置文件中定义重发机制ReDelivery:设置重发两次

 <!-- 定义ReDelivery(重发机制)机制 ,重发时间间隔是100毫秒,最大重发次数是3次 -->
<bean id="activeMQRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
<!--是否在每次尝试重新发送失败后,增长这个等待时间 -->
<property name="useExponentialBackOff" value="true"/>
<!--重发次数,默认为6次-->
<property name="maximumRedeliveries" value="2"/>
<!--重发时间间隔,默认为1秒 -->
<property name="initialRedeliveryDelay" value="1000"/>
<!--第一次失败后重新发送之前等待500毫秒,第二次失败再等待500 * 2毫秒,这里的2就是value -->
<property name="backOffMultiplier" value="2"/>
<!--最大传送延迟,只在useExponentialBackOff为true时有效(V5.5),假设首次重连间隔为10ms,倍数为2,那么第二次重连时间间隔为 20ms,
第三次重连时间间隔为40ms,当重连时间间隔大的最大重连时间间隔时,以后每次重连时间间隔都为最大重连时间间隔。 -->
<property name="maximumRedeliveryDelay" value="1000"/>
</bean>

在工厂中引用重发机制:

 <!--PooledConnectionFactory对session和消息producer的缓存机制而带来的性能提升-->
<bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<property name="connectionFactory">
<!--连接mq的连接工厂-->
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>tcp://127.0.0.1:61616</value>
</property>
<!-- 引用重发机制 -->
<property name="redeliveryPolicy" ref="activeMQRedeliveryPolicy" />
</bean>
</property>
<property name="maxConnections" value="100"></property>
</bean>

在监听容器中新增配置消息的确认机制:

 <!--配置 消息监听容器-->
<bean id="jmsContainer" class=" org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="queueDestination"/>
<property name="messageListener" ref="consumerMessageListener"/>
<!--应答模式是 INDIVIDUAL_ACKNOWLEDGE-->
<!--AUTO_ACKNOWLEDGE = 1 自动确认
CLIENT_ACKNOWLEDGE = 2 客户端手动确认
DUPS_OK_ACKNOWLEDGE = 3 自动批量确认
SESSION_TRANSACTED = 0 事务提交并确认
INDIVIDUAL_ACKNOWLEDGE = 4 单条消息确认-->
<property name="sessionAcknowledgeMode" value="4"/>
</bean>

发送者无需改动,正常发送即可,我们在消费者中进行改动,在消息接收到的时候调用确认方法(上面配置了4单挑消息确认),然后再接收消息做点手脚让其报错不能确认使其触发重发机制:

public class ConsumerMessageListener implements SessionAwareMessageListener<Message> {//消息确认需要session,需要实现SessionAwareMessageListener

    @Override
public void onMessage(Message message, Session session) throws JMSException {
if (message instanceof TextMessage){
String msg = ((TextMessage) message).getText(); System.out.println("------------------------------------------");
System.out.println("消费者收到的消息:" + msg);
System.out.println("------------------------------------------"); try {
if ("test2".equals(msg)) {
throw new RuntimeException("故意抛出的异常");
}
// 确认消息。只要被确认后 就会出队,接受失败没有确认成功,会在原队列里面
message.acknowledge();
} catch (Exception e) {
// 此不可省略 重发信息使用,如果不写此方法,将不会实现重发操作。失败的消息将会一直在队列中,因为没有进行消息确认。
// 下次还会监听到这条消息。效果将会是:第一次接受一个消息2。第二次接受2个,依次累加
session.recover();
}
}
}

发送4条消息:

  //发送字符串
for (int i = 0; i < 4; i++) { service.sendMessage("test" + i);
}

结果

由结果可见,test2由于抛出异常,未能进行消息确认,所有重发了两次,共三次。

代码地址:https://github.com/MrLiu1227/ActiveMQ

学习ActiveMQ(六):JMS消息的确认与重发机制的更多相关文章

  1. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  2. 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...

  3. ActiveMQ的JMS消息可靠机制

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

  4. JMS开发(三):JMS消息的确认方式

    这里单独列出来我也是觉得有点必要的,毕竟JMS总体知识点并不多,这点可能被很多人所忽视. 首选定义:消息的确认是指消息接受者接到消息,并做出了对应的处理之后,它将回送一个确认消息. 对于非事务性会话, ...

  5. 使用ActiveMQ实现JMS消息通信服务

    PTP(点对点的消息模型) 在点对点模型中,相当于两个人打电话,两个人独享一条通信线路.一方发送消息,一方接收消息. 在p2p的模型中,双方通过队列交流,一个队列只有一个生产者和一个消费者. 1.建立 ...

  6. 使用Tomcat、JNDI与ActiveMQ实现JMS消息通信服务

    前言 之所以使用JNDI 是出于通用性考虑,该例子使用JMS规范提供的通用接口,没有使用具体JMS提供者的接口,这样可以保证我们编写的程序适用于任何一种JMS实现(ActiveMQ.HornetQ等) ...

  7. 学习ActiveMQ(七):JMS消息的事务管理

    Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.JmsTransactio ...

  8. ActiveMQ学习笔记(二) JMS与Spring

    上文可见,JMS Native API使用起来不是特别方便.好在Spring提供了很好的JMS支持. (一)配置ConnectionFactory 如果使用连接池的话,不要忘记activemq-poo ...

  9. JMS学习(三)JMS 消息结构之属性及消息体详解

    一.前言 通过上一篇的学习我们知道了消息分为三个部分,即消息头,属性及消息体,并对消息头的十个属性进行了详细的介绍,本文再对消息属性及消息体进行详细的介绍. 二.属性介绍 消息属性的主要作用是可以对头 ...

随机推荐

  1. 使用工具intellij idea 进行java web开发简介

    一.工具下载及安装准备 1.首先下载工具  Intellij idea ,下载地址:https://www.jetbrains.com/ 2.破解 百度下载一个 JetbrainsCrack-2.7- ...

  2. tengine2.2.3报错502的The proxy server received an invalid response from an upstream server问题处理

    tengine2.2.3报错502的The proxy server received an invalid response from an upstream server问题处理 现象:访问订单的 ...

  3. js实现拖动验证码

    效果图: Index.html <!DOCTYPE html> <html lang="en"> <head> <meta http-eq ...

  4. Android开发之字体设置

    默认字体 Android SDK自带了四种字体:"normal"“monospace",“sans”, “serif”,如下:   字体 看这四兄弟长的还是蛮像,我是看不 ...

  5. Linux /etc/sudoers 文件详解

    [root@test ~]# cat /etc/sudoers## Sudoers allows particular users to run various commands as## the r ...

  6. liunx 修改ssh 端口22

    vim  /etc/ssh/sshd_config 找到Port  22  添加 Port 5002 重启sshd /bin/systemctl restart sshd.service 防火墙释放5 ...

  7. spring+redis的集成,使用spring-data-redis来集成

    1.参考:https://www.cnblogs.com/qlqwjy/p/8562703.html 2.首先创建一个maven项目.然后加入依赖的jar包就行了.我加入的jar包很多,反正加入了也没 ...

  8. Postgresql/Greenplum中将数字转换为字符串TO_CHAR函数前面会多出一个空格

    -- 问题1..Postgresql中将数字转换为字符串前面多出一个空格. SELECT TO_CHAR(, '); -- 解决1.使用如下,参数二前面加上fm就可以去掉空格了,如下: SELECT ...

  9. 如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样)

    如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样) python标准库中的subprocess可以解决这个问题. from subprocess ...

  10. Java运行原理、三大体系、jdk构成

    一.java运行原理: 二.Java分为三个体系: JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版) JavaEE(J2EE)(Java ...