SpringBoot_ActiveMQ
一、ActiveMQ介绍【消息队列中间件】
1、但凡耗时长的功能都可以通过消息队列异步交给其他服务完成
写入ActiveMQ或读取ActiveMQ
ActiveMQ就是一个容器
常用的RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等
2、安装ActiveMQ
下载
新版:http://activemq.apache.org/components/artemis/download/
老版:http://activemq.apache.org/components/classic/download/
运行:activemq.bat
运行后访问:http://localhost:8161/
用户名和密码都是:admin
3、queue与topic
a、点对点:Queue,不可重复消费
消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。
消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。
Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费、其它的则不能消费此消息了。
当消费者不存在时,消息会一直保存,直到有消费消费
b、发布/订阅:Topic,可以重复消费
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。
和点对点方式不同,发布到topic的消息会被所有订阅者消费。
当生产者发布消息,不管是否有消费者。都不会保存消息
4、引用依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!--消息队列连接池-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.0</version>
</dependency>
二、queue 两个微服务点对点通信
1、接收者和发送者双方微服务添加以下配置
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
#默认queue、true群发、false不群发、此配置只需要对接收者配置,发送者不需要下面的配置
#spring.jms.pub-sub-domain=true
2、接收者微服务、创建一个项目、编写一个GetMsg接收消息的类、然后启动、等待接受消息
@Component
public class GetMsg {
/**
* 监听和读取active.queue消息、destination和名必须和发送者名称一致
*/
@JmsListener(destination = "active.queue")
public void readActiveTopic2(String message) {
System.out.println("1接受到:" + message);
}
}
3、发送者微服务、创建一个项目、编写一个发送者的方法、测试发送消息
如果有多个接收者、只能被其中一个获取、如果没有接收者、会被存储起来、等待接收者
@RestController
public class SendMsgController {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@RequestMapping("/send")
public Object send(String msg) {
//把消息发送到点对点的active.queue中
jmsMessagingTemplate.convertAndSend(new ActiveMQQueue("active.queue"), msg);
return "ok";
}
}
三、topic 群发
1、接收者和发送者双方微服务都需要修改配置
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
#默认queue、true群发、false不群发、此配置只需要对接收者配置,发送者不需要下面的配置
spring.jms.pub-sub-domain=true
2、接收者微服务、创建一个项目、编写一个GetMsg接收消息的类、然后启动、等待接受消息【可以多个接受者微服务】
@Component
public class GetMsg {
/**
* 监听和读取topic消息、destination和名必须和发送者名称一致
*/
@JmsListener(destination = "active.topic")
public void readActiveTopic2(String message) {
System.out.println("1接受到:" + message);
}
}
3、发送者微服务、创建一个项目、编写一个发送者的方法、测试发送消息
如果当时有多个接收者、大家都可以接受到、如果没有接收者、不会存储起来、消息直接失效
@RestController
public class SendMsgController {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@RequestMapping("/send")
public Object send(String msg) {
//发送点对点消息消息
//jmsMessagingTemplate.convertAndSend(new ActiveMQQueue("active.queue"), msg);
//群发消息
jmsMessagingTemplate.convertAndSend(new ActiveMQTopic("active.topic"), msg);
return "ok";
}
}
四、让接收者能既能接受点对点,亦能接受群发
1、在接收者微服务添加以下配置
import javax.jms.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
@Configuration
@EnableJms
public class JmsConfig {
@Bean
public JmsListenerContainerFactory<?> topicListenerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setPubSubDomain(true);
factory.setConnectionFactory(connectionFactory);
return factory;
}
@Bean
public JmsListenerContainerFactory<?> queueListenerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setPubSubDomain(false);
factory.setConnectionFactory(connectionFactory);
return factory;
}
}
2、接受类的方法修改成以下方式
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class GetMsg {
/**
* 监听和读取active.queue消息
*/
@JmsListener(destination = "active.queue",containerFactory="queueListenerFactory")
public void readActiveTopic1(String message) {
System.out.println("点对点的----avtivemq001接受到:" + message);
}
/**
* 监听和读取active.queue消息
*/
@JmsListener(destination = "active.queue",containerFactory="topicListenerFactory")
public void readActiveTopic2(String message) {
System.out.println("群发的----avtivemq001接受到:" + message);
}
}