ActiveMQ--消息传递点对点方式及其可靠性机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fangxinde/article/details/88244070

JMS消息之后被确认后,才会认为是被成功消费,消费者的消费包含三个阶段:客户端接受消息、客户端处理消息、消息被确认

消息传递域:

      点对点:

1.每个消息只能有一个消息者

2.消息的生产者和消费者之间没有时间上的相关性。生产者在发送消息时,无论消费者是否处在运行状态,都可以提取消息。

事务性会话:

  消息提供方、消息消费方 createSession()方法中第一个参数设置为true,(此时第二个参数不起作用),表示生成的session为事务性会话。

Session session = connection.createSession(Boolean.TRUE, Session.CLIENT_ACKNOWLEDGE);

消息提供方、消息消费方都需对session进行提交:

session.commit();

若消费提供者不commit,消息不能进入队列,消息服务方不commit,队列中消息不能签收。

消息提供方:提供10条消息


public class JmsSender {
    public static void main(String[] args) {
         ConnectionFactory connectionFactory = new                                              ActiveMQConnectionFactory("tcp://192.168.70.66:61616");
         Connection connection=null;
        try {
            connection = connectionFactory.createConnection();
            connection.start();
            //Boolean.TRUE时,createSession方法第二个参数不起作用
            //生成和消费消息的单线程上下文
            Session session = connection.createSession(Boolean.TRUE, Session.CLIENT_ACKNOWLEDGE);
            Destination destination = session.createQueue("first-queue1");
            MessageProducer producer = session.createProducer(destination);
            for (int i = 0; i < 10; i++) {
                TextMessage textMessage = session.createTextMessage("hello,菲菲我是帅帅的mic"+i);
                textMessage.setStringProperty("song","fangyiming");
                textMessage.setStringProperty("dauger","fangyifei");
                producer.send(textMessage);
            }
            session.commit();
            session.close();

        } catch (JMSException e) {
            e.printStackTrace();
        }finally {
            if (connection!=null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

 消息消费方:

 
public class JmsReceiver {
    public static void main(String[] args) {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.70.66:61616");
        Connection connection=null;
        TextMessage textMessage=null;
        try {
            connection = connectionFactory.createConnection();
            connection.start();

            Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
            //获取连接时的凭证
            Destination destination= session.createQueue("first-queue1");
            MessageConsumer consumer = session.createConsumer(destination);
            for (int i = 0; i < 10; i++) {
                textMessage=(TextMessage)consumer.receive();
                System.out.println(textMessage.getText()+""+textMessage.getStringProperty("song"));

            }
            //textMessage.acknowledge();
            session.commit();
            session.close();
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (connection!=null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 消费端启动后,运行结果

hello,菲菲我是帅帅的mic0fangyiming
hello,菲菲我是帅帅的mic1fangyiming
hello,菲菲我是帅帅的mic2fangyiming
hello,菲菲我是帅帅的mic3fangyiming
hello,菲菲我是帅帅的mic4fangyiming
hello,菲菲我是帅帅的mic5fangyiming
hello,菲菲我是帅帅的mic6fangyiming
hello,菲菲我是帅帅的mic7fangyiming
hello,菲菲我是帅帅的mic8fangyiming
hello,菲菲我是帅帅的mic9fangyiming

ActiveMQ管理器观察消息的变化:

 非事务性会话:

主要是消息消费端进行设置:

createSession()方法中第一个入参设置为FALSE,第二个参数可设置为:

AUTO_ACKNOWLEDGE

CLIENT_ACKNOWLEDGE

DUPS_OK_ACKNOWLEDGE

(1)session设置为AUTO_ACKNOWLEDGE时:

 Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

 当客户端成功从receive()方法返回后以后,会话会自动确认该消息

(2)session设置为CLIENT_ACKNOWLEGE时:

客户端通过调用消息的textMessage.acknowledge()方法确认消息(或签收消息,消息从消息队列中出栈)

在这种模式中,如果一个消息消费者消费一共是10个消息,那么消费了5个消息,然后在第五个消息上进行textMessage.acknowledge()操作,那么前五条会被签收,后五条不会,需继续留在队列中。

Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

 第五条消息消费时,消息进行acknowledge()操作:

消费端代码:


public class JmsReceiver {
    public static void main(String[] args) {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.70.66:61616");
        Connection connection=null;
        TextMessage textMessage=null;
        try {
            connection = connectionFactory.createConnection();
            connection.start();

            Session session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
            //获取连接时的凭证
            Destination destination= session.createQueue("first-queue1");
            MessageConsumer consumer = session.createConsumer(destination);
            for (int i = 1; i <=10; i++) {
                textMessage=(TextMessage)consumer.receive();
                if (i==5){
                    textMessage.acknowledge();
                }
                System.out.println(textMessage.getText()+"====>"+textMessage.getStringProperty("song"));

            }
            //textMessage.acknowledge();
            //session.commit();
            session.close();
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (connection!=null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 第一次运行后:

管理系统队列中消息处理情况

 其控制台的结果为:

hello,菲菲我是帅帅的mic0====>fangyiming
hello,菲菲我是帅帅的mic1====>fangyiming
hello,菲菲我是帅帅的mic2====>fangyiming
hello,菲菲我是帅帅的mic3====>fangyiming
hello,菲菲我是帅帅的mic4====>fangyiming
hello,菲菲我是帅帅的mic5====>fangyiming
hello,菲菲我是帅帅的mic6====>fangyiming
hello,菲菲我是帅帅的mic7====>fangyiming
hello,菲菲我是帅帅的mic8====>fangyiming
hello,菲菲我是帅帅的mic9====>fangyiming

第二次运行消费端:

控制台打印结果为:

hello,菲菲我是帅帅的mic5====>fangyiming
hello,菲菲我是帅帅的mic6====>fangyiming
hello,菲菲我是帅帅的mic7====>fangyiming
hello,菲菲我是帅帅的mic8====>fangyiming
hello,菲菲我是帅帅的mic9====>fangyiming

可以看到前五条消息已被签收(消息已出栈),而后五条还存在队列中,故第二次运行还能打印出来。

(2)session设置为DUPS_OK_ACKNOWLEDGE时:延迟签收

猜你喜欢

转载自blog.csdn.net/fangxinde/article/details/88244070