最近没事干,在本地搭建了一个消息服务器,然后用SpringBoot整合ActiveMQ,测试了一下消息发送
消息服务器搭建参考我的下一篇博文,简单易上手
链接:https://blog.csdn.net/qq_43173523/article/details/103876218
消息发送分点对点和发布/订阅两种模式,本文将两种模式写在一个类中,单独测试
1、pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>lq-activemq</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lq-activemq</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、配置文件
spring:
activemq:
broker-url: tcp://localhost:61616
user: admin
password: admin
pool:
enabled: false
3、配置类
@Configuration
public class JMSConfig {
public final static String TOPIC = "springboot.topic.test";
public final static String QUEUE = "springboot.queue.test";
@Bean
public Queue queue() {
return new ActiveMQQueue(QUEUE);
}
@Bean
public Topic topic() {
return new ActiveMQTopic(TOPIC);
}
// topic模式的ListenerContainer
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(true);
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
// queue模式的ListenerContainer
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerQueue(ConnectionFactory activeMQConnectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
}
4、生产者
@RestController
public class JMSProducer {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private Queue queue;
@Autowired
private Topic topic;
// 发送消息,destination是发送到的队列,message是待发送的消息
public void sendMessage(Destination destination, final String message){
jmsTemplate.convertAndSend(destination, message);
}
}
5、消费者
queue两个,这种模式两个消费者共同消费,比如一个生产者发送了10条消息,两个消费者一共消费10条
topic两个,这种模式两个消费者单独消费,比如一个生产者发送了10条消息,两个消费者每个都消费10条,一共消费20条
测试类中可以查看两种消息模式的特点
@Component
public class JMSConsumer3 {
@Autowired
private Queue queue;
@Autowired
private Topic topic;
private final static Logger logger = LoggerFactory.getLogger(JMSConsumer3.class);
//topic模式
@JmsListener(destination = JMSConfig.TOPIC,containerFactory = "jmsListenerContainerTopic")
public void onTopicMessage(String msg) {
logger.info(topic+"1111111111111接收到topic消息:{}",msg);
}
//topic模式
@JmsListener(destination = JMSConfig.TOPIC,containerFactory = "jmsListenerContainerTopic")
public void onTopicMessage2(String msg) {
logger.info(topic+"222222222222222接收到topic消息:{}",msg);
}
//queue模式
@JmsListener(destination = JMSConfig.QUEUE,containerFactory = "jmsListenerContainerQueue")
public void onQueueMessage(String msg) {
logger.info(queue+"3333333333333333接收到queue消息:{}",msg);
}
@JmsListener(destination = JMSConfig.QUEUE,containerFactory = "jmsListenerContainerQueue")
public void onQueueMessage2(String msg) {
logger.info(queue+"444444444444444接收到queue消息:{}",msg);
}
}
6、测试类,两种消息模式的测试方法写在一个类中了
测试点对点:
@SpringBootTest
class LqActivemqApplicationTests {
@Autowired
private JMSProducer jmsProducer;
@Autowired
private Topic topic;
@Autowired
private Queue queue;
@Test
public void testJms2() {
for (int i=0;i<100;i++) {
jmsProducer.sendMessage(queue,"queue,world!" + i+"主题为"+queue);
//jmsProducer.sendMessage(topic, "topic,world!" + i+"主题为"+topic);
}
}
}
目前,一共发了十条消息,两个消费者一共只收到4条消息,部分消息被离奇消费,等待后续解决(正常是两个消费者一共消费10条消息)
测试发布/订阅模式,两个消费者
@SpringBootTest
class LqActivemqApplicationTests {
@Autowired
private JMSProducer jmsProducer;
@Autowired
private Topic topic;
@Autowired
private Queue queue;
@Test
public void testJms2() {
for (int i=0;i<100;i++) {
//jmsProducer.sendMessage(queue,"queue,world!" + i+"主题为"+queue);
jmsProducer.sendMessage(topic, "topic,world!" + i+"主题为"+topic);
}
}
}
一个生产者发送了了10条消息,两个消费者,每个消费者都消费10条消息,这是跟queue模式所不一样的
点对点和发布/订阅模式混合发送
@SpringBootTest
class LqActivemqApplicationTests {
@Autowired
private JMSProducer jmsProducer;
@Autowired
private Topic topic;
@Autowired
private Queue queue;
@Test
public void testJms2() {
for (int i=0;i<100;i++) {
jmsProducer.sendMessage(queue,"queue,world!" + i+"主题为"+queue);
jmsProducer.sendMessage(topic, "topic,world!" + i+"主题为"+topic);
}
}
}
两种模式互不影响