一、两种模式
- 点对点的消息模式:
- 点对点的模式主要建立在一个队列上面,当连接一个列队的时候,发送端不需要知道接收端是否正在接收,可以直接向ActiveMQ发送消息,发送的消息,将会先进入队列中,如果有接收端在监听,则会发向接收端,如果没有接收端接收,则会保存在activemq服务器,直到接收端接收消息,点对点的消息模式可以有多个发送端,多个接收端,但是一条消息,只会被一个接收端给接收到,哪个接收端先连上ActiveMQ,则会先接收到,而后来的接收端则接收不到那条消息
- 订阅模式:
- 订阅/发布模式,同样可以有着多个发送端与多个接收端,但是接收端与发送端存在时间上的依赖,就是如果发送端发送消息的时候,接收端并没有监听消息,那么ActiveMQ将不会保存消息,将会认为消息已经发送,换一种说法,就是发送端发送消息的时候,接收端不在线,是接收不到消息的,哪怕以后监听消息,同样也是接收不到的。这个模式还有一个特点,那就是,发送端发送的消息,将会被所有的接收端给接收到,不类似点对点,一条消息只会被一个接收端给接收到
二、测试需要的jar包
三、点到点形式发送、接收消息测试
package cn.e3mall.activemq; import org.apache.activemq.ActiveMQConnectionFactory; import org.junit.Test; import javax.jms.*; /** * @author Mr.Li * @version 1.0 * @Description: Queue点到点形式发送、接收消息测试 * @Modified By: * @date 2018/12/11 15:50 */ public class ActiveMqTest { /** * 生产者:生产消息,发送端。 * @throws Exception */ @Test public void testQueueProducer() throws Exception{ //创建一个连接工程对象,需要指定服务的IP以及端口 ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.0.107:61616"); //使用工程对象创建一个Connection对象 Connection connection=connectionFactory.createConnection(); //开启连接,调用Connection对象的start方法 connection.start(); //创建一个Session对象 /** * 第一个参数:是否开启事务。如果true开启事务那么第二个参数没有意义。一般不开启事务false * 【如果消息没有发出去那就重发,一般和分布式的事务配合使用,数据库的分布式事务:同时提交多个数据库,保证这些事务都在一个事务中完成】 * 第二个参数:应答模式。一般是自动应答 * 【接受到了之后是自动应答,还是手动应答】 * CLIENT_ACKNOWLEDGE: 手动应答 * AUTO_ACKNOWLEDGE: 自动应答 */ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //使用Session对象创建一个Destination【目的地对象】对象,两种形式:queue,topic,现在应该使用queue Queue queue = session.createQueue("my-queue"); //使用Session对象创建一个producer对象 MessageProducer producer = session.createProducer(queue); //创建一个Message对象,可以使用TextMessage /** * TextMessage textMessage=new ActiveMQTextMessage(); * textMessage.setText("hello ActiveMQ"); */ for (int i=0;i<3;i++){ TextMessage textMessage = session.createTextMessage("hello ActiveMQ"+i); //发送消息,发送给服务端:tcp://192.168.1.111:61616 producer.send(textMessage); } //关闭资源 producer.close(); session.close(); connection.close(); } /** * 消费者:接收消息。 * @throws Exception */ @Test public void testQueueConsumer() throws Exception{ //创建一个ConnectionFactory对象连接MQ服务器 ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.0.107:61616"); //创建一个连接对象 Connection connection = connectionFactory.createConnection(); //开启连接 connection.start(); //使用Connection对象创建一个Session对象 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //创建一个Destination对象。queue对象 Queue queue = session.createQueue("my-queue"); //使用Session对象创建一个消费者对象 MessageConsumer consumer = session.createConsumer(queue); //接受消息 // consumer.setMessageListener(new MessageListener() { // @Override // public void onMessage(Message message) { // //打印结果 // TextMessage textMessage= (TextMessage) message; // String text = null; // try { // text = textMessage.getText(); // System.out.println(text); // } catch (JMSException e) { // e.printStackTrace(); // } // } // }); for (int i=0;i<3;i++) { TextMessage textMessage = (TextMessage) consumer.receive(); System.out.println(textMessage.getText()); } // 这里可以更改设置不同的消费端 System.out.println("Queue的消费端。。。。。"); //等待接受消息 System.in.read(); //关闭资源 consumer.close(); session.close(); connection.close(); } }
- 运行生产者生产消息后,在配置好的ActiveMQ网页中查看
- 运行消费者接受消息后
注意:
- 消息发送者只有一个,那么只能有一个消息消费之接受消息,接收完消息,那么这个消息就消失了
- 如果再发布,那么只要一发布,就会接收到消息【前提是不关闭接收端的测试】
- 一个消息只能由一个消费者接收,如果有多个消费者,那么会根据队列的入队顺序按照顺序接收消息
- Queue持久化
四、订阅模式发送、接收消息测试
package cn.e3mall.activemq; import org.apache.activemq.ActiveMQConnectionFactory; import org.junit.Test; import javax.jms.*; /** * @author Mr.Li * @version 1.0 * @Description: 订阅模式发送、接收消息测试 * @Modified By: * @date 2018/12/11 22:49 */ public class ActiveMqTopicTest { /** * 生产者:生产消息,发送端。 * @throws Exception */ @Test public void testTopicProducer() throws Exception { // 第一步:创建ConnectionFactory对象,需要指定服务端ip及端口号。 // brokerURL服务器的ip及端口号 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.111:61616"); // 第二步:使用ConnectionFactory对象创建一个Connection对象。 Connection connection = connectionFactory.createConnection(); // 第三步:开启连接,调用Connection对象的start方法。 connection.start(); /** * 第四步:使用Connection对象创建一个Session对象。 * 第一个参数:是否开启事务。true:开启事务,第二个参数忽略。 * 第二个参数:当第一个参数为false时,才有意义。消息的应答模式。1、自动应答2、手动应答。一般是自动应答。 */ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); /** * 第五步:使用Session对象创建一个Destination对象(topic、queue),此处创建一个topic对象。 * 参数:话题的名称。 */ Topic topic = session.createTopic("test-topic"); // 第六步:使用Session对象创建一个Producer对象。 MessageProducer producer = session.createProducer(topic); // 第七步:创建一个Message对象,创建一个TextMessage对象。 /** * TextMessage message = new ActiveMQTextMessage(); message.setText( * "hello activeMq,this is my first test."); */ TextMessage textMessage = session.createTextMessage("hello activeMq,this is my topic test"); // 第八步:使用Producer对象发送消息。 producer.send(textMessage); // 第九步:关闭资源。 producer.close(); session.close(); connection.close(); } /** * 消费者:接收消息。 * @throws Exception */ @Test public void testTopicConsumer() throws Exception { // 第一步:创建一个ConnectionFactory对象。 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.1.111:61616"); // 第二步:从ConnectionFactory对象中获得一个Connection对象。 Connection connection = connectionFactory.createConnection(); // 第三步:开启连接。调用Connection对象的start方法。 connection.start(); // 第四步:使用Connection对象创建一个Session对象。 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 第五步:使用Session对象创建一个Destination对象。和发送端保持一致topic,并且话题的名称一致。 Topic topic = session.createTopic("test-topic"); // 第六步:使用Session对象创建一个Consumer对象。 MessageConsumer consumer = session.createConsumer(topic); // 第七步:接收消息。 consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; String text = null; // 取消息的内容 text = textMessage.getText(); // 第八步:打印消息。 System.out.println(text); } catch (JMSException e) { e.printStackTrace(); } } }); System.out.println("topic的消费端。。。。。"); // 等待接受消息 System.in.read(); // 第九步:关闭资源 consumer.close(); session.close(); connection.close(); } }
- 运行生产者生产消息后,在配置好的ActiveMQ网页中查看
- 运行消费者接受消息后
注意:
- topic消息是不缓存到服务端的,不保存,所以没有人接收就没有人就收,topic只管发送,不管接收
- 一个消息可以被当前开启的所有消费者接收
- Topic不持久化