分布式-信息方式-JMS可靠性机制

                    JMS的可靠性机制
1.消息接收确认
        JMS消息只有在被确认之后,才认为已经被成功地消费了。
消息的成功消费通常包含三个阶段:客户接收消息、客户处理消息和消息被确。
        在事务性会话中,当一个事务被提交的时候,确认自动发生。在非事务性会话
中,消息何时被确认取决于创建会话时的应答模式( acknowledgement mode)。该参
数有以下三个可选值:
         Session.AUT0 ACKNOWLEDGE:当客户成功的从 receive方法返回的时候,或者从
Messagelistener. onMessage方法成功返回的时候,会话自动确认客户收到的消息。
         Session. CLIENT ACKINOWLEDGE:客户通过调用消息的 acknowledge方法确认消
息。需要注意的是,在这种模式中,确诙是在会话层上进行,确认一个被消费的消息
将自动确认所有已被会话消费的消息。例如,如果一个消息消费者消费了10个消
息,然后确认第5个消息,那么所有10个消息都被确认。

session.AUTO_ACKNOWLEDGE

session的提交和不提交现象

package test.mq.helloword;

import java.util.Enumeration;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.ConsumerBrokerExchange;

public class Receiver {
    
    public static void main(String[] args) throws JMSException {
        ConnectionFactory   ConnectionFactory=new ActiveMQConnectionFactory(
                "tcp://localhost:61616"
                );
        Connection connection=ConnectionFactory.createConnection();
        connection.start();
        Enumeration names=connection.getMetaData().getJMSXPropertyNames();
        while(names.hasMoreElements()){
            String name=(String) names.nextElement();
            System.out.println("jmsx name==="+name);
        }
        Session session=connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); 
        Destination destination=session.createQueue("my_queue");
        MessageConsumer Consumer=session.createConsumer(destination);
        int i=0;
        while(i<3){
            
             MapMessage msg=(MapMessage) Consumer.receive();
             //当session不提交时, 信息会不确认签收,信息就一直可以接受到。
             session.commit();
             System.out.println("接收信息:"+msg.getString("message"+i)+",property=="+msg.getStringProperty("extra"+i));
             i++;
         }
         
        session.close();
        connection.close();
    
    }
}

Session.CLIENT_ACKNOWLEDGE的使用

信息发送者

package test.mq.helloword;

 

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;
 

import org.apache.activemq.ActiveMQConnectionFactory;

public class Sender {
       public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory   ConnectionFactory=new ActiveMQConnectionFactory(
                "tcp://localhost:61616"
                );
        Connection connection=ConnectionFactory.createConnection();
        connection.start();
    
        Session session=connection.createSession(Boolean.TRUE, Session.CLIENT_ACKNOWLEDGE);
        Destination destination=session.createQueue("my_queue");
        MessageProducer Producer=session.createProducer(destination);
     
        for(int i=0;i<3;i++){
             MapMessage Message=session.createMapMessage();
             Message.setStringProperty("extra"+i, "okok");
             Message.setString("message"+i, "my map---->"+i);
             Producer.send(Message);
        }
         session.commit();
         session.close();
         connection.close();    
    }
}

信息消费者

package test.mq.helloword;

import java.util.Enumeration;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.ConsumerBrokerExchange;

public class Receiver {
    
    public static void main(String[] args) throws JMSException {
        ConnectionFactory   ConnectionFactory=new ActiveMQConnectionFactory(
                "tcp://localhost:61616"
                );
        Connection connection=ConnectionFactory.createConnection();
        connection.start();
        Enumeration names=connection.getMetaData().getJMSXPropertyNames();
        while(names.hasMoreElements()){
            String name=(String) names.nextElement();
            System.out.println("jmsx name==="+name);
        }
        Session session=connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE); 
        Destination destination=session.createQueue("my_queue");
        MessageConsumer Consumer=session.createConsumer(destination);
        int i=0;
        while(i<3){
            
             MapMessage msg=(MapMessage) Consumer.receive();
             if(i==2){
                 //当 msg.acknowledge()不提交时, 信息会不确认签收,信息就一直可以接受到。
                 msg.acknowledge();
             }
             System.out.println("接收信息:"+msg.getString("message"+i)+",property=="+msg.getStringProperty("extra"+i));
             i++;
         }
         
        session.close();
        connection.close();
    
    }
}

消息持久性,JM支持以下两种消息提交模式:
        PERSISTENT:指小JMSp1 ovider持久保存消息,以保证消息不会因为JMS
provider的失败而丢失
       NON PERS ISTENT:不要求JMSp1 ovider持久保存消息
消息优先级
       可以使用消息优先级来指旨小丶 JMS provide首先提交紧总的消息。优先级分
10个级别,从0(最低)到9(最高)。如果不指定优先级,默认级别是1。需要
注意的是,JMSp1 ovide1并不一定保证按照优先级的顺序提交消息
消息过期
       可以设置消息在一定时间后过期,默认是水不过期
消息的临时目的地
       可以通过会话上的 createTemporaryQueue方法和 create Temporary Topic
方法来创建临时目|的地。它们的存在时简!限于创建它们的连接所保持的时间
只有创建该临时目的地的连接上的消息消赍者才能够从临时目的地中提取消息

 

JMS的PTP模型
 JMS PTF( Point-to- Point)模型定义了客户端如何向队列发送消息,从队列接收
消息,以及浏览队列中的消息。
          PTP模型是基于队列的,生产者发消息到队列,消费者从队列接收消息,队
列的存在使得消息的异步传输成为可能。和邮件系统中的邮箱一样,队列可以包
含各种消息,JMP1 ovider提供工具管理队列的创建、删除。
PTP的一些特点
       1:如果在 Session关闭时∫,有一些消息凵经被收到,但还没有被签收
         ( acknoledged),那么,当消费者下次连接到相同的队列时,这些消息还会被再
        次接收
        2:如果用户在 receive方法中设定了消息选择条件,那么不符合条件的消息会留在
        队列中,不会被接收到
        3:队列可以长久地保存消息直到消费者收到消息。消费者不需要因为担心消息会丢
        失而时刻和队列保持激活的连接状态,允分体现了异步传输模式的优势

 

JMS的Pub/Sub模型
JMS Pub/Sub模型定义了如何向一个内容节点发布和订阅消息,这些节点被称作 topic
             主题可以被认为是消息的传输中介,发布者(pub1 isher)发布消息到主题,订阅者
( subscribe)从主题订阅消息。主题使得消息订阅者和消息发布者保持互相独立,不需要
接触即可保证消息的传送。
Pub/Sub的一些特点
          1:消息订阅分为非持久订阅和持久订阅
          非持久订阅只有当客户端处于激活状态,也就是和 JMS Provider保持连接状态才能
          收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会
          丢失,永远不会收到。
          持久订阅时,客户端向JMS注册一个识别自已身份的ID,当这个客户端处于离线
           时, JMS Provi der会为这个ID保存所有发送到主题的消息,当客户再次连接到]M
           Provider时,会根据自己的ID得到所有当自己处于离线时发送到主题的消息
           2:如果用户在 receive方法中设定了消息选择条件,那么不符合条件的消息不会被接收
           3:非持久订阅状态下,不能恢复或重新派送一个未签收的消息。只有持久订阅才能恢复或重
           新派送一个未签收的消息。
           4:当所有的消息必须被接收,则用持久订阅。当丢失消息能够被容忍,则用非持久订阅

 

 

 

 

 

 

个JMS应用的基木步骤
JMS开发的基本步骤
1:创建一个 JMS connection factory
2:通过 connection factory米创建 JMS connection
3:启动 JMS connection
1:通过 connection创建 JMS session
5:创建 JMS destination
6:创建JMSp1 oducer,或者创建 JMS message,并设置 destinatio
7:创建 JMS consumer,或者是注册一个 JMS essage listene1
8:发送或者接受 JMS essage(s)
9:关闭所有的JMS资源( connection, session, producer, con sumel等)

 

posted @ 2018-07-19 11:11  曹英杰  阅读(290)  评论(0编辑  收藏  举报