ActiveMQ学习笔记(上)

来源:互联网 发布:java需要英语基础吗 编辑:程序博客网 时间:2024/05/29 14:36


公司做智能硬件的,使用ActiveMQ做消息队列,我接手这块,学习了一下,记点笔记,供大家参考


一、ActiveMQ简介

ActiveMQ,名字上看是一种MessageQueue,其实是支持Queue(队列)和Topic(广播)两种模式。

他本身是一种异步的处理机制,所以主要的应用场景主要是对大应用解耦合,做异步处理,他所支持的mqtt协议还可以用作移动端与服务器的通讯处理。

ActiveMQ是支持JMS规范的,我们知道JMS有两种消息模型(Point-to-Point(点对点)和Publish/Subscribe Message(消息广播)),虽然他们的父类都可以实现Queue和Topic,但是基于规范,建议基于p2p模型实现Queue模式,基于Pub/Sub实现Topic。


二、Queue消息

Queue是点对点的消息模型,一个Sender虽然可以有多个Receiver,但是Sender发出的消息只会由一个并且是保证有且只有一个Receiver接收,接收后mq会收到通知把这条消息删除,如果暂时没有Receiver,Queue默认在mq服务器上以文件形式保存,直到有一个Receiver连线接收。

1.Queue发送

            // 创建链接工厂            QueueConnectionFactory factory = new ActiveMQConnectionFactory(null, null, "tcp://127.0.0.1:61616");            // 通过工厂创建一个连接            connection = factory.createQueueConnection();            // 启动连接            connection.start();            // 创建一个session会话            session = connection.createQueueSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);//①            // 创建一个消息队列            Queue queue = session.createQueue("test.queue");            // 创建消息发送者            javax.jms.QueueSender sender = session.createSender(queue);            // 设置持久化模式            sender.setDeliveryMode(DeliveryMode.PERSISTENT);//②            MapMessage map = session.createMapMessage();            map.setString("text", message);                   sender.send(map);            // 提交会话            session.commit();


2.Queue接收

     // 创建链接工厂            QueueConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD, "tcp://127.0.0.1:61616");            // 通过工厂创建一个连接            connection = factory.createQueueConnection();            // 启动连接            connection.start();            // 创建一个session会话            session = connection.createQueueSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);//①            // 创建一个消息队列            Queue queue = session.createQueue("test.queue");            // 创建消息制作者            javax.jms.QueueReceiver receiver = session.createReceiver(queue);                        receiver.setMessageListener(new MessageListener() {                public void onMessage(Message msg) {                     if (msg != null) {                        MapMessage map = (MapMessage) msg;                        try {                            System.out.println(map.getLong("time") + "接收#" + map.getString("text"));                            msg.acknowledge();//③                        } catch (JMSException e) {                            e.printStackTrace();                        }                    }                }             });             // 提交会话            session.commit();


①connection.createQueueSession(A, B):

如果A为true,为支持事务,则B只能为SESSION_TRANSACTED,这种情况下,在事务开启之后,和session.commit()之前,所有消费的消息,要么全部正常确认,要么全部redelivery,由于Session是共享的,使用此种方式时,需要对每一个请求创建新的session,以为造成业务处理错误;

如果A为false,则不支持事务则,B可以为AUTO_ACKNOWLEDGE、CLIENT_ACKNOWLEDGE或DUPS_OK_ACKNOWLEDGE。AUTO_ACKNOWLEDGE为自动确认(择机确认具有不确定性);CLIENT_ACKNOWLEDGE为客户端手动确认,如Queue接收实例中的③,该确认有两种方式,message.acknowledge()将当前session中所有consumer中尚未ACK的消息都一起确认,而ActiveMQMessageConsumer.acknowledege()只会对当前consumer中那些尚未确认的消息进行确认;DUPS_OK_ACKNOWLEDGE只对Topic消息起作用,当consumer故障重启后,那些尚未被MQ确认的消息会重新发送过来;

②queue消息未被消费或者手动清除的情况下是会保存的,在P2P类型中当DeliveryMode设置为NON_PERSISTENCE时,消息被保存在内存中,而当DeliveryMode设置为PERSISTENCE时,消息保存在broker的相应的文件或者数据库中。而且P2P中消息一旦被Consumer消费就从broker中删除。

MessageListener是异步模式,B不能为SESSION_TRANSACTED。


三、Topic消息

Topic是Publish-Subscribe-Message的消息模型,数据是无状态不落地的,所以publisher发出的每条消息不能保证subscriber都能收到,只有监听该publisher的subscriber才能收到,如果没有customer在监听,该消息就相当于消失了,Topic是一对多的,所有监听publisher的subscriber都可以收到消息。

1.Topic发送

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(null, null, "failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)");//①        TopicConnection connection = factory.createTopicConnection();          connection.start();          TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);                TopicPublisher producer = session.createPublisher(new ActiveMQTopic("test.topic"));        TextMessage message = session.createTextMessage();message.setText("message_" + System.currentTimeMillis());producer.send(message);session.commit();



2.Topic接收

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD, "failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)");TopicConnection connection = factory.createTopicConnection();  connection.start();  TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);Topic topic = session.createTopic("test.topic");  TopicSubscriber consumer = session.createSubscriber(topic);     consumer.setMessageListener(new MessageListener() {  public void onMessage(Message message) {  ActiveMQBytesMessage tm = (ActiveMQBytesMessage) message;  System.out.println("Received message: " + tm.getMessage());   }  });session.commit();


①ActiveMQ支持断线重连

后记:先写到这儿,写一写对自己来说也收获颇多,下一篇涉及到mqtt的内容


1 0
原创粉丝点击