一、ActiveMQ开发环境搭建
ActiveMQ是Apche的一个开源项目,各位同学各自去下载。
本博客使用的是ActiveMQ的5.15.4的window版本,下载以后,解压后的目录如下:
bin : 该文件下面是启动文件,以及服务安装卸载文件。
conf:是配置文件。
data:持久化的数据。
① 启动ActiveMQ
② 访问ActiveMQ
那么默认的密码和用户名是什么呢?
在conf目录下,有一个jetty-realm.properties文件,该文件中定义了用户名、密码、以及角色:
所以,登录的时候,admin,admin来登录:
③ MQ主页内容介绍
Topics:订阅消息
Subscribers:订阅者信息
Number Of Consumers 消费者 这个是消费者端的消费者数量
Number Of Pending Messages 等待消费的消息 这个是当前未出队列的数量。可以理解为总接收数-总出队列数
Messages Enqueued 进入队列的消息 进入队列的总数量,包括出队列的。 这个数量只增不减
Messages Dequeued 出了队列的消息 可以理解为是消费这消费掉的数量
二、针对ActiveMQ的第一个JAVA开发
在apache-activemq-xxx下面有一个activemq-all-5.15.4.jar的jar包,这个包里面包含所有开发需要用到的jar,当然你也可以根据自己的需要去选择jar包,在lib目录下,前提是你得了解每个jar包的作用。我这里直接使用all这个jia包。当然,要是我知道每个单独jar包的作用,我就写在这里显摆了
① 生产者的开发(Producre)
我的项目结构如下,这里提一下,在junit-4.10开始,junit的jar包里面就不在包含hamcrest-core这个jar包了,所以在使用junit的时候,需要自己导入哦!
下面是一个hello world 的程序实例:
/**
* ActiveMQ 创建生产者,并向MQ发送消息
* @throws JMSException
*/
@Test
public void activeMQProducer() throws JMSException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("root","root","tcp://127.0.0.1:61616");
//这里可以这样写
//ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
//connectionFactory.createConnection("root","root");
//创建连接
Connection connection = connectionFactory.createConnection();
//开启连接
connection.start();
//创建Session会话,不使用事务,采用自动签收模式。后面会讨论这个自动签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建消息队列
Destination queue = session.createQueue("myMessage1");
//创建消息
TextMessage textMessage = session.createTextMessage("hello ActiveMQ");
//创建生产者
MessageProducer producer = session.createProducer(queue);
//发送消息
producer.send(textMessage);
//关闭资源
session.close();
connection.close();
}
在程序运行运行之前,点击栏目中的queues,可以看见如下的内容:
这里有一个myMessage1,是我以前,创建的,如果没有使用过,那么下面应该什么都没有。接着运行程序之后可以发现:
已经成功的写入了一条消息。
Number of Pending Messages:待接收的消息1条
Messages Enqueued:进入队列的总消息数目1条
Messages Dequeued:已经消费的消息0条
② 消费者的开发(Consumer)
/**
* 消息接收
* @throws JMSException
*/
@Test
public void activeMQConsumer() throws JMSException {
//创建连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("root","root","tcp://127.0.0.1:61616");
//创建连接
Connection connection = connectionFactory.createConnection();
//开启连接
connection.start();
//创建Session会话,不使用事务,采用自动签收模式。后面会讨论这个自动签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建消息队列
Destination queue = session.createQueue("myMessage1");
//创建消息
TextMessage textMessage = session.createTextMessage("hello ActiveMQ");
//创建消费者
MessageConsumer consumer = session.createConsumer(queue);
//接收消息
TextMessage message = (TextMessage) consumer.receive();
//获取消息
String text = message.getText();
System.out.println(text);
//关闭资源
session.close();
connection.close();
}
输出:
运行程序之后,MQ的管理界面如下:
Number of Pending MEssages:待接收消息为0条
Messages Enqueued:入对列消息工1条
Messages Dequeued:接收消息1条
至此,一个hello版本的程序开发完成。
三、ActiveMQ 订阅消息Topic的java开发
/**
* topic消息创建者
*
* topic的生产者在发送消息的时候,如果消费者不在线,那么将不会在收到发送的消息
*/
@Test
public void topicProducer() throws JMSException {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = connectionFactory.createConnection("root","root");
connection.start();
//不开启事务,自动签收消息
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建订阅主题
Destination topic = session.createTopic("myTopic1");
MessageProducer producer = session.createProducer(topic);
TextMessage textMessage = session.createTextMessage();
int i = 0;
while(true) {
textMessage.setText("我是消息---->" + i++);
producer.send(textMessage);
//session.commit();
}
}
接收消息:
@Test
public void topicConsumer() throws JMSException {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = connectionFactory.createConnection("root", "root");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("myTopic1");
MessageConsumer consumer = session.createConsumer(topic);
//如果这里收不到消息,将会阻塞,直到收到消息
TextMessage message = (TextMessage) consumer.receive();
while(message != null) {
String text = message.getText();
System.out.println(message);
System.out.println(text);
message = (TextMessage)consumer.receive();
}
System.out.println("结束了...");
session.close();
connection.close();
}
实例说明:①在消费者开发完成之后,需要先启动一次,这样MQ才知道你订阅了这个消息。
②由于这个例子不是持久化的订阅模式,所以如果生产者有消息发送,而消费者不在线,那么以前的消息,消费者将不能收到。
四、持久化的消息订阅
消费者:在建立持久化的消费者的时候,请注意代码中的注意点。
/**
* 持久化的消息消费者
*
* 注意点: ① 需要在连接上设置ID,用来识别消费者。
* ② 需要创建TopicSubscriber来订阅消息。
* ③ 要将一切都设置好了之后,再来启动这个连接。
* ④ 一定要先运行一次,等于像消息服务中间件注册这个消费者,然后在运行
* 客户端发送消息,这个时候无论消费者是否在线,都会收到消息。如果不在
* 线的话,下次连接的时候,会把没有收到的消息全部接收下来。
*/
@Test
public void persistenceMessageConsumer() throws JMSException {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = connectionFactory.createConnection("root", "root");
//设置消费者ID,用来识别消费者
connection.setClientID("lwb");
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic destination = session.createTopic("myTopic1");
TopicSubscriber topicSubscriber = session.createDurableSubscriber(destination,"our");
//这里也是先设置好了之后,才能启动
connection.start();
TextMessage receive = (TextMessage) topicSubscriber.receive();
while(receive != null) {
System.out.println(receive.getText());
receive = (TextMessage) topicSubscriber.receive(2000);
}
//关闭资源
session.close();
connection.close();
}
生产者:在建立持久化的消费者的时候,请注意代码中的注意点。
/**
* 持久化的消息生产者
*
* 注意点: ① 在producer上设置发送模式为 DeliveryMode.persistent模式。
* ② 要在所有的设置完成之后,在启动这个连接。
*/
@Test
public void persistenceMessageProducer() throws JMSException, InterruptedException {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = connectionFactory.createConnection("root", "root");
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic("myTopic1");
MessageProducer producer = session.createProducer(destination);
//设置持久化消息模式
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//这里一定是在上面的模式设置了之后,在启动
connection.start();
for(int i = 0; i < 5; i++) {
TextMessage message = session.createTextMessage("我是消息:" + i);
Thread.sleep(1000);
producer.send(message);
}
//关闭资源
session.close();
connection.close();
}
运行之后的状态:为什么是10条消息,因为我在消费者在线和不在线的情况下分别运行了一次生产者,所以是10条消息。
输出结果,表示无论消费者是否在线,持久化的订阅消息,在消费者在线后,都会收到。