小鸡炸

导航

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);
	}
}

posted on 2022-01-19 10:44  小鸡炸  阅读(62)  评论(0编辑  收藏  举报