简介
发送者将消息发送给消息服务器,消息服务器将消息存放到若干队列中,在合适的时候再将消息转发给消息接受者。
这种情况下,发送和接收是异步的,发送者无需等待,发送消息的时候,接受者不一定运行。接收消息的时候,发送者也不一定运行。一对多通讯,对于一个消息,可以有多个接受者。
应用场景
作者:青莲键仙
来源:CSDN
原文:https://blog.csdn.net/qinweili751/article/details/80620104
Java的消息服务JMS
消息模型分为两种:
- 点对点通讯。
每个消息只能让一个消费者进行消费,尽管会有多个消费者。 - 发布订阅
发布者发布主题,多个订阅者订阅主题,订阅者都能接收到消息。
点对点模式(生产者,消费者)
生产者代码
package com.itmayiedu.producer;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.support.ManagedArray;
//生产者 消息
public class Producer {
private static String BROKERURL = "tcp://127.0.0.1:61616";
private static String QUEUE = "my-queue";
static public void start() throws JMSException {
System.out.println("生产者已经启动....");
// 创建ActiveMQConnectionFactory 会话工厂
ActiveMQConnectionFactory activeMQConnectionFactory =
new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKERURL);
Connection connection = activeMQConnectionFactory.createConnection();
// 启动JMS 连接
connection.start();
// 第一个参数为是否开启事务(需要提交事务:session.commit();),第二个参数 为签收模式
(自动签收:Session.AUTO_ACKNOWLEDGE(消息会被重复消费,无法保证数据幂等性)
手动签收:Session.CLIENT_ACKNOWLEDGE 消费者需要 textMessage.acknowledge();
手动签收 保证数据不被重复消费)
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
// 创建一个队列
Queue queue = session.createQueue(QUEUE);
// 指定生产者
MessageProducer producer = session.createProducer(queue);
//发送消息
send(producer, session);
System.out.println("发送成功!");
connection.close();
}
//生产消息
static public void send(MessageProducer producer, Session session)
throws JMSException {
for (int i = 1; i <= 5; i++) {
System.out.println("我是消息" + i);
TextMessage textMessage = session.createTextMessage("我是消息" + i);
producer.send(textMessage);
}
//事务提交
session.commit();
}
//启动生产者
public static void main(String[] args) throws JMSException {
start();
}
}
消费者代码
package com.itmayiedu.producer;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class JmsReceiver {
private static String BROKERURL = "tcp://127.0.0.1:61616";
private static String QUEUE = "my-queue";
public static void main(String[] args) throws JMSException {
start();
}
static public void start() throws JMSException {
System.out.println("消费点启动...");
// 创建ActiveMQConnectionFactory 会话工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKERURL);
Connection connection = activeMQConnectionFactory.createConnection();
// 启动JMS 连接
connection.start();
// 开启消息事务,设置手动签收,保证数据幂等性
Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
// 指定消费队列
Queue queue = session.createQueue(QUEUE);
MessageConsumer consumer = session.createConsumer(queue);
//消费消息
while (true) {
TextMessage textMessage = (TextMessage) consumer.receive();
if (textMessage != null) {
System.out.println("接受到消息:" + textMessage.getText());
textMessage.acknowledge();//手动签收
session.commit();
} else {
break;
}
}
connection.close();
}
}
运行结果
发布订阅
生产者代码
package com.itmayiedu.producer;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TOPSend {
private static String BROKERURL = "tcp://127.0.0.1:61616";
private static String TOPIC = "my-topic";
public static void main(String[] args) throws JMSException {
start();
}
static public void start() throws JMSException {
System.out.println("生产者已经启动....");
// 创建ActiveMQConnectionFactory 会话工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKERURL);
Connection connection = activeMQConnectionFactory.createConnection();
// 启动JMS 连接
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(null);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
send(producer, session);
System.out.println("发送成功!");
connection.close();
}
static public void send(MessageProducer producer, Session session) throws JMSException {
for (int i = 1; i <= 5; i++) {
System.out.println("我是消息" + i);
TextMessage textMessage = session.createTextMessage("我是消息" + i);
Destination destination = session.createTopic(TOPIC);
producer.send(destination, textMessage);
}
}
}
消费者代码
package com.itmayiedu.producer;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TopReceiver {
private static String BROKERURL = "tcp://127.0.0.1:61616";
private static String TOPIC = "my-topic";
public static void main(String[] args) throws JMSException {
start();
}
static public void start() throws JMSException {
System.out.println("消费点启动...");
// 创建ActiveMQConnectionFactory 会话工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKERURL);
Connection connection = activeMQConnectionFactory.createConnection();
// 启动JMS 连接
connection.start();
// 不开消息启事物,消息主要发送消费者,则表示消息已经签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建一个队列
Topic topic = session.createTopic(TOPIC);
MessageConsumer consumer = session.createConsumer(topic);
//消费消息
while (true) {
TextMessage textMessage = (TextMessage) consumer.receive();
if (textMessage != null) {
System.out.println("接受到消息:" + textMessage.getText());
} else {
break;
}
}
connection.close();
}
}
运营结果
控制台启动两个消费者,这两个消费者同时消费消息
ActiveMQ web 控制台