您当前的位置: 首页 > 

Dongguo丶

暂无认证

  • 0浏览

    0关注

    472博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

ActiveMQ消息的可靠性

Dongguo丶 发布时间:2017-12-08 12:42:59 ,浏览量:0

这篇我们学习一下,ActiveMQ事务会话,应答模式(事务会话和应答模式是有关联的),发送持久化消息,下面我们从两个方面来学习一下即消息接受确认和发送持久化消息。

一、消息接收确认

1、jms消息只有在被确认之后才认为成功消费了这条消息。消息的成功消费通常包括三个步骤:(1)、client接收消息 (2)、client处理消息 (3)、消息被确认(也就是client给一个确认消息)

不管是事务性会话还是非事务性会话,第一步和第二步都一样但第三步有所不同

2、在事务性会话中当一个事务被提交的时候,确认自动发生,和应答模式没关系,这个值可以随便写。(这里多提一句异步消息接收中不能使用事务性会话)

3、在非事务性会话中消息何时被确认取决于创建的session中设置的消息应答模式(acknowledge model)该参数有三个值:

(1)、Session.AUTO_ACKNOWLEDGE:当client端成功的从receive方法或从onMessage(Message message) 方法返回的时候,会话自动确认client收到消息。

(2)、Session.CLIENT_ACKNOWLEDGE: 客户单通过调用acknowledge方法来确认客户端收到消息。但需要注意在这种应答模式下,确认是在会话层上进行的,确认一个被消费的消息将自动确认所有已消费的其他消息。比如一个消费者已经消费了10条消息,然后确认了第5条消息被消费,则这10条都被确认消费了。

acknowledge()通知方法是在Message对象上

同步接收,调用acknowledge()方法进行确认:

[java] view plain copy
print ?
  1. consumer = session.createConsumer(queue); // 消息消费者  
  2.             Message message = consumer.receive(); //同步方式接收  
  3.             message.acknowledge(); //消息消费确认通知  
consumer = session.createConsumer(queue); // 消息消费者
            Message message = consumer.receive(); //同步方式接收
            message.acknowledge(); //消息消费确认通知
异步接受,调用acknowledge()方法进行确认:

[java] view plain copy
print ?
  1. consumer.setMessageListener(new MessageListener() {  
  2.                 @Override  
  3.                 public void onMessage(Message message) {  
  4.                     TextMessage textMessage = (TextMessage) message;  
  5.                     try {  
  6.                         String value = textMessage.getText();  
  7.                         System.out.println(”value: ” + value);  
  8.                         message.acknowledge(); //消息消费确认通知  
  9.                     } catch (JMSException e) {  
  10.                         e.printStackTrace();  
  11.                     }  
  12.                 }  
  13.             });  
consumer.setMessageListener(new MessageListener() {
                @Override
                public void onMessage(Message message) {
                    TextMessage textMessage = (TextMessage) message;
                    try {
                        String value = textMessage.getText();
                        System.out.println("value: " + value);
                        message.acknowledge(); //消息消费确认通知
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            });
(3)、Session.DUPS_ACKNOWLEDGE:不是必须签收,消息可能会重复发送。在第二次重新传送消息的时候,消息头的JmsDelivered会被置为true标示当前消息已经传送过一次,客户端需要进行消息的重复处理控制。 小结:

1.transacted事务,事务成功commit,才会将消息发送到mom中  2.acknowledgeMode消息确认机制       1)、带事务的session                 如果session带有事务,并且事务成功提交,则消息被自动签收。如果事务回滚,则消息会被再次传送。       2)、不带事务的session                 不带事务的session的签收方式,取决于session的配置。                  Activemq支持一下三種模式:                  Session.AUTO_ACKNOWLEDGE  消息自动签收                  Session.CLIENT_ACKNOWLEDGE  客戶端调用acknowledge方法手动签收                  Session.DUPS_OK_ACKNOWLEDGE 不是必须签收,消息可能会重复发送。在第二次重新传送消息的时候,消息                  头的JmsDelivered会被置为true标示当前消息已经传送过一次,客户端需要进行消息的重复处理控制。 

二、发送持久化消息

这里发送持久化消息和消息的持久化是有点联系,但不是一回事,发送持久化消息的意思是要不要将发送的消息持久化到磁盘或数据库中而消息的持久化是指将消息持久化到磁盘还是数据库,一个是要不要将消息持久化一个是将消息怎么持久化。

这里要写的当然是要不要将消息持久化,activemq给我们提供了两种两个选择即持久化或不持久化。

1、PERSISTENT:指示JMS Provider持久保存消息,会把消息持久化到磁盘以保证消息不会因为JMS provider、JMS Server 的失败而丢失。

2、NON_PERSISTENT:不要求JMS Provider持久保存消息。如果JMS Server 重启则消息就丢死了,消费端也就会失去这条消息。

3、消息的持久化设置:

[java] view plain copy
print ?
  1. MessageProducer producer = session.createProducer(queue);  
  2.             // 消息是否为持久性的,如果不设置默认是持久化的。  
  3.             // producer.setDeliveryMode(DeliveryMode.PERSISTENT);  
  4.             //非持久化消息,消息是不会持久化到磁盘的,发送后如果服务关闭再次开启则消息会丢失。  
  5.              producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  
MessageProducer producer = session.createProducer(queue);
            // 消息是否为持久性的,如果不设置默认是持久化的。
            // producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            //非持久化消息,消息是不会持久化到磁盘的,发送后如果服务关闭再次开启则消息会丢失。
             producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
持久化的设置是很简单的是吧,但是消息是否持久化对应用的性能影响还是很大的,而且在消息量很大的时候则更要慎重是否要对消息进行持久化。

关注
打赏
1638062488
查看更多评论
立即登录/注册

微信扫码登录

0.0352s