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的内容
- ActiveMQ学习笔记(上)
- Jms---ActiveMQ学习笔记
- activeMQ学习笔记一
- ActiveMQ学习笔记
- activeMQ学习笔记
- Activemq学习笔记--Queue
- ActiveMQ学习笔记
- ActiveMQ学习笔记(中)
- JMS-ActiveMQ学习笔记
- 学习笔记-ActiveMQ
- ActiveMQ入门学习笔记
- ActiveMQ学习笔记-入门教程
- ActiveMQ学习笔记01
- ActiveMQ学习笔记
- ActiveMQ开篇学习笔记
- activeMQ 学习笔记
- ActiveMQ学习笔记
- ActiveMQ学习笔记(二)
- java反射获取属性值
- CF665E Beautiful Subarrays字典树
- java抽象类和接口
- android 画虚线,显示实心解决方法
- http状态码
- ActiveMQ学习笔记(上)
- 利用cpdetector获取文件编码格式,同时得到网页内容。增加http/https通用方式
- iOS端阿里云推送报错:ALBB OneSDK init failure Code=100 "(null)"
- html meta中的viewport指令
- 打字比赛
- Android进程管理详解
- java注解 @
- Django Mode: Cannot delete or update a parent row, a foreign key constraint fails
- linux系统Ubuntu下简易安装mqtt