代码
1.pom
java
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
2.yml
java
spring:
# autoconfigure:
# exclude:
# - org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration
# - org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration
activemq:
# 本地 ActiveMQ 默认端口
broker-url: tcp://localhost:61616
# 根据你本地实际情况配置,如果没有认证可以不配置
# user: admin
# password: admin
jms:
listener:
auto-startup: true
3.XxxApplication
java
@EnableScheduling
@ComponentScan(basePackages = "com.xxx")
@EnableDiscoveryClient
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@MapperScan("com.xxx.*.mapper")
@ConfigurationPropertiesScan("com.xxxx.api.properties")
@EnableJms
public class XxxApplication {
4.JmsConfig
java
@Configuration
public class JmsConfig {
/**
* Topic 监听容器:开启发布订阅模式
*/
@Bean
public DefaultJmsListenerContainerFactory topicJmsListenerContainerFactory(
ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPubSubDomain(true);
return factory;
}
}
5.MessageConsumer
java
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class MessageConsumer {
/**
* 监听 Queue,默认就是 Queue 模式
*/
@JmsListener(destination = "demo.queue")
public void onQueueMessage(String message) {
System.out.println("[Queue 收到消息] " + message);
}
/**
* 监听 Topic,需要指定 topic 容器工厂
*/
@JmsListener(destination = "demo.topic", containerFactory = "topicJmsListenerContainerFactory")
public void onTopicMessage(String message) {
System.out.println("[Topic 收到消息] " + message);
}
}
6.MessageProducer
java
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
@Service
public class MessageProducer {
// private final JmsTemplate jmsTemplate;
//
// public MessageProducer(JmsTemplate jmsTemplate) {
// this.jmsTemplate = jmsTemplate;
// }
@Autowired(required = false)
private JmsTemplate jmsTemplate;
/**
* 发送 Queue 消息:点对点
*/
public void sendQueue(String queueName, String message) {
jmsTemplate.convertAndSend(queueName, message);
}
/**
* 发送 Topic 消息:发布订阅
*/
public void sendTopic(String topicName, String message) {
// 直接指定为 Topic,不会影响其他 Queue 发送
jmsTemplate.convertAndSend(new ActiveMQTopic(topicName), message);
}
}
测试controller
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/msg")
public class MessageController {
// private final MessageProducer producer;
//
// public MessageController(MessageProducer producer) {
// this.producer = producer;
// }
@Autowired(required = false)
private MessageProducer producer;
@PostMapping("/queue")
public String sendQueue(@RequestParam String msg) {
producer.sendQueue("demo.queue", msg);
return "Queue 消息已发送: " + msg;
}
@PostMapping("/topic")
public String sendTopic(@RequestParam String msg) {
producer.sendTopic("demo.topic", msg);
return "Topic 消息已发送: " + msg;
}
}
MQ区别
ActiveMQ和RabbitMQ是两款经典的消息队列中间件,它们在多个方面存在显著差异:
开发语言不同
ActiveMQ使用Java开发,RabbitMQ使用Erlang开发。
支持的协议不同
ActiveMQ主要遵循JMS规范,同时支持OpenWire、STOMP、REST、XMPP、AMQP等多种协议。RabbitMQ主要走AMQP协议,同时也支持MQTT、STOMP等协议。
性能表现不同
RabbitMQ的延迟更低,可以达到微秒级,而ActiveMQ一般在毫秒级。吞吐量方面,两者单机都在万级左右,都远低于Kafka和RocketMQ的十万级水平。
可靠性方面
RabbitMQ的消息确认机制更完善,理论上更不容易丢失消息。
路由灵活性
RabbitMQ通过交换机(Exchange)和绑定键(Binding Key)的机制,支持更灵活复杂的消息路由。ActiveMQ的路由能力相对简单。
社区活跃度
RabbitMQ社区更活跃,文档更齐全,多语言支持更好。ActiveMQ近年使用减少,维护重心已转向其他产品。
适用场景
如果项目已有JMS规范依赖,或者需要与Java生态深度集成,ActiveMQ仍是合适的选择。但对于新项目,RabbitMQ通常是更优先的选项,尤其是在需要灵活路由、多语言支持和活跃社区支持的场景下。