导入 maven 依赖
<dependency>
<groupId>org.apache.activemqgroupId>
<artifactId>activemq-allartifactId>
<version>5.16.2version>
dependency>
现在的消息队列大概分为队列模型和发布订阅模型
队列模型:
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.util.Date;
public class JmsProduce {
private static final String DEFAULT_BROKER_HOST = "tcp://IP:61616";
public static void main(String[] args) throws JMSException {
// 创建连接工厂
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(DEFAULT_BROKER_HOST);
// 获取 connection
final Connection connection = connectionFactory.createConnection("admin", "admin");
// 启动
connection.start();
// 创建会话 session,参数第一个是事务,第二个是签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建目的地,queue 或者 topic
Queue queue = session.createQueue("queueName");
// 创建消息的生产者
MessageProducer producer = session.createProducer(queue);
// 创建消息
TextMessage textMessage = session.createTextMessage("这是一条消息" + new Date());
// 发送消息给 mq
producer.send(textMessage);
// 关闭
session.close();
connection.close();
System.out.println("消息发送成功~");
}
}
1、同步阻塞,使用 receive() 方法进行消费,receive() 方法不带参数会一直等待,receive(Long timeout) 会等待指定时间后退出等待
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class JmsConsumer {
public static void main(String[] args) throws JMSException {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://IP:61616");
Connection connection = connectionFactory.createConnection("admin", "admin");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queueName");
// 创建消费者
MessageConsumer consumer = session.createConsumer(queue);
while (true) {
// 同步阻塞方式使用 receive(),超时之前一直等待
// receive() 方法不带参数会一直等待
// receive(Long timeout) 会等待指定时间后退出等待
TextMessage receive = (TextMessage) consumer.receive();
if (receive != null) {
System.out.println("接收到消息:" + receive);
}else {
break;
}
}
consumer.close();
session.close();
connection.close();
}
}
2、异步阻塞,使用监听方式消费消息,订阅者或接收者通过 MessageConsumer 的 setMessageListener(MessageListenner listener) 注册一个消息监听器,消息到达后自动调用监听器的 MessageListener 的 onMessage(Message message) 方法
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
public class JmsConsumer {
public static void main(String[] args) throws JMSException, IOException {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://82.156.227.150:61616");
Connection connection = connectionFactory.createConnection("admin", "admin");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queueName");
// 创建消费者
MessageConsumer consumer = session.createConsumer(queue);
// 通过监听方式消费消息
consumer.setMessageListener((message) -> {
if (null != message && message instanceof TextMessage) {
TextMessage message1 = (TextMessage) message;
try {
System.out.println("消费者接收到消息:" + message1.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read(); // 保证控制台存活状态
consumer.close();
session.close();
connection.close();
}
}
订阅-发布模式
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.util.Date;
public class JmsProduceTopic {
public static void main(String[] args) throws Exception{
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://IP:61616");
Connection connection = connectionFactory.createConnection("admin", "admin");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("topicName");
MessageProducer producer = session.createProducer(topic);
TextMessage textMessage = session.createTextMessage("message--" + new Date());
producer.send(textMessage);
producer.close();
session.close();
connection.close();
System.out.println("消息发送成功~");
}
}
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.util.Date;
public class JmsConsumerTopic {
public static void main(String[] args) throws Exception{
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://IP:61616");
Connection connection = connectionFactory.createConnection("admin", "admin");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("topicName");
MessageConsumer consumer = session.createConsumer(topic);
consumer.setMessageListener((message) -> {
if (message != null && message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("消费者接收到消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
System.in.read();
consumer.close();
session.close();
connection.close();
}
}
Topic 模式队列 | Queue 模式队列 |
---|---|
订阅,发布模式,当前没有订阅者,消息会被放弃,如果有多个订阅者,所有订阅者都会收到消息 | 如果没有消费者,消息也不会丢弃,多个消费者,消息只会发送给其中一个消费者,并且要求消费者 ACK 信息 |
无状态 | 默认在 mq 服务器上以文件形式保存,也可以配置成 DB 存储 |
没有订阅者消息丢弃 | 消息不会丢弃 |
消息按照订阅者数量进行赋值,性能随着订阅者数量增加降低 | 每个消息只发送个一个消费者,性能不会明显降低 |
Broker 相当于一个 ActiveMQ 实例
ActiveMQ 实现了用代码的形式启动 ActiveMQ 将 MQ 嵌入到 Java 代码中
导入 maven 依赖
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.12.3version>
dependency>
启动 Broker 代码
public static void main(String[] args) throws Exception {
BrokerService brokerService = new BrokerService();
brokerService.setUseJmx(true);
brokerService.addConnector("tcp://localhost:61616");
brokerService.start();
}