ActiveMq 入门
ActiveMqAPI http://activemq.apache.org/maven/apidocs/index.html
1 JMS编程模版
Destination
Destination是一个客户端用来指定生产消息目标和消费消息来源的对象。在PTP模式中,Destination被称作Queue即队列;在Pub/Sub模式,Destination被称作Topic即主题。在程序中可以使用多个Queue和Topic。
创建api:
Destination destination = session.createQueue("my_queue");
Destination destination = session.createTopic("my_topic");
MessageProducer 消息生产者
MessageConsumer 消息消费者
Message 消息
2 pom.xml
<dependencies>
<!-- activemq 所需要的jar 包-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.x</version>
</dependency>
<!-- activemq 和 spring 整合的基础包 -->
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>3.16</version>
</dependency>
</dependencies>
3入门实例---队列
生产者
package springboot.activeMQ;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class Producer {
private static final String url="tcp://127.0.0.1:61616";//服务地址,端口默认61616
private static final String queueName="my_queue";//消息队列名称
public static void main(String[] args) throws JMSException {
//1.创建ConnectiongFactory,绑定地址
ConnectionFactory factory=new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection= factory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination=session.createQueue(queueName);
//6.创建一个生产者
MessageProducer producer=session.createProducer(destination);
for (int i = 0; i < 10; i++) {
//7.创建消息
TextMessage textMessage=session.createTextMessage("我是消息生产者:"+i);
//8.发送消息
producer.send(textMessage);
System.out.println("发送消息:"+i);
}
// 9 关闭资源
messageProducer.close();
session.close();
connection.close();
System.out.println(" **** 消息发送到MQ完成 ****");
}
}
消费者: 以Listener的方式实现消费
package springboot.activeMQ;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class Consumer {
private static final String url="tcp://127.0.0.1:61616";//端口默认
private static final String queueName="my_queue";//消息队列名称
public static void main(String[] args) throws JMSException {
//1.创建ConnectiongFactory,绑定地址
ConnectionFactory factory=new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection= factory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination=session.createQueue(queueName);
//6.创建一个消费者
MessageConsumer consumer=session.createConsumer(destination);
//7.创建一个监听器
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message arg0) {
TextMessage textMessage=(TextMessage)arg0;
try {
System.out.println("接收消息:"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
// 让主线程不要结束。因为一旦主线程结束了,其他的线程(如此处的监听消息的线程)也都会被迫结束。
// 实际开发中,我们的程序会一直运行,这句代码都会省略。
System.in.read();
messageConsumer.close();
session.close();
connection.close();
/** //同步阻塞方式(receive)
while(true){
// reveive() 一直等待接收消息,在能够接收到消息之前将一直阻塞。 是同步阻塞方式 。和socket的accept方法类似的。
// reveive(Long time) : 等待n毫秒之后还没有收到消息,就是结束阻塞。
// 因为消息发送者是 TextMessage,所以消息接受者也要是TextMessage
TextMessage message = (TextMessage)messageConsumer.receive();
if (null != message){
System.out.println("****消费者的消息:"+message.getText());
}else {
break;
}
}
messageConsumer.close();
session.close();
connection.close();
**/
}
}
两种消费方式
同步阻塞方式(receive)
订阅者或接收者抵用MessageConsumer的receive()方法来接收消息,receive方法在能接收到消息之前(或超时之前)将一直阻塞。
异步非阻塞方式(监听器onMessage())
订阅者或接收者通过MessageConsumer的setMessageListener(MessageListener listener)注册一个消息监听器,当消息到达之后,系统会自动调用监听器MessageListener的onMessage(Message message)方法。
4入门实例--主题
生产者:
package springboot.activeMQ;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class TipicProducer {
private static final String url="tcp://127.0.0.1:61616";//服务地址,端口默认61616
private static final String topicName="my_topic";//主题名称
public static void main(String[] args) throws JMSException {
//1.创建ConnectiongFactory,绑定地址
ConnectionFactory factory=new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection= factory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination=session.createTopic(topicName);
//6.创建一个生产者
MessageProducer producer=session.createProducer(destination);
for (int i = 0; i < 10; i++) {
//7.创建消息
TextMessage textMessage=session.createTextMessage("我是消息生产者:"+i);
//8.发送消息
producer.send(textMessage);
System.out.println("发送消息:"+i);
}
producer.close();
session.close();
connection.close();
System.out.println(" **** TOPIC_NAME消息发送到MQ完成 ****");
}
}
消费者
package springboot.activeMQ;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class TipicConsumer {
private static final String url="tcp://127.0.0.1:61616";//端口默认
private static final String topicName="my_topic";//主题名称
public static void main(String[] args) throws JMSException {
//1.创建ConnectiongFactory,绑定地址
ConnectionFactory factory=new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection= factory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5.创建一个目标
Destination destination=session.createTopic(topicName);
//6.创建一个消费者
MessageConsumer consumer=session.createConsumer(destination);
//7.创建一个监听器
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message arg0) {
TextMessage textMessage=(TextMessage)arg0;
try {
System.out.println("接收消息:"+textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read();
consumer.close();
session.close();
connection.close();
}
}
特点:
(1)队列模式的消费者在运行后也能收到之前的消息,消息只会被某个消费者消费一次
(2)生产者将消息发布到topic中,每个消息可以有多个消费者,属于1:N的关系;
(3)生产者和消费者之间有时间上的相关性。订阅某一个主题的消费者只能消费自它订阅之后发布的消息。
(4)生产者生产时,topic不保存消息它是无状态的不落地,假如无人订阅就去生产,那就是一条废消息,所以,一般先启动消费者再启动生产者。
5队列与主题的对比