上一篇文章介绍了如何搭建 RabbitMQ 环境,我们构建 RabbitMQ 环境,就是为了使用他的消息队列机制,本文会介绍怎么使用最基本的消息队列模型
配置 RabbitMQ server
最开始,我们需要添加 RabbitMQ 的依赖
标记段内容如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
然后,需要在我们的 Springboot 的项目里,设置需要连接的 RabbitMQ Server 相关配置信息
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest #配置好的 RabbitMQ server 默认的账号
spring.rabbitmq.password=guest #配置好的 RabbitMQ server 默认的密码
绑定队列和交换器
以下是测试的队列路由常量和交换器名常量,根据实际情况调整
public class Constant {
public static final String HOSH_TOPIC = "hosh.customer";
public static final String HOSH_TOPIC_EXC = "exchange";
}
消息队列模型最重要的就是队列,生产者和消费者都会依赖对应的队列,生产者向队列写入数据,消费者从队列中获取数据,RabbitMQ 在队列前有一层交换器,生产者和消费者不能直接向队列中读、写数据,需要通过交换器实现,那么我们就需要将队列和交换器绑定起来,形成绑定关系
@Configuration
public class MQTopicConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.port}")
private int port;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost("/");
connectionFactory.setPublisherConfirms(true);
return connectionFactory;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
@Bean
public Queue coreQueue() {
// 构建队列
return new Queue(Constant.HOSH_TOPIC);
}
@Bean
public TopicExchange coreTopicExchange() {
// 构建交换器
return new TopicExchange(Constant.HOSH_TOPIC_EXC);
}
@Bean
public Binding bindingCoreExchange() {
// 队列绑定到交换机上,同时定义支持的路由
return BindingBuilder.bind(coreQueue()).to(coreTopicExchange()).with(Constant.HOSH_TOPIC);
}
}
生产者
我们需要一个向队列写入数据的生产者
@Component
public class HoshMQSender implements RabbitTemplate.ConfirmCallback{
private RabbitTemplate rabbitTemplate;
@Autowired
public HoshMQSender(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
this.rabbitTemplate.setConfirmCallback(this);
}
public void send(String str) {
// 标识该条消息内容的唯一 ID
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(Constant.HOSH_TOPIC_EXC, Constant.HOSH_TOPIC, str, correlationData);
System.out.println("HoshMQSender send id=" + correlationData.getId());
}
// 队列内容发送到 MQ 的确认
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
if (b) {
System.out.println("recv HoshMQSender confirm id=" + correlationData.getId());
} else {
System.out.println("not recv " + s);
}
}
}
消费者
需要一个消费者消费队列中的数据
@Component
public class HoshMqReceiver {
@RabbitHandler
@RabbitListener(queues = Constant.HOSH_TOPIC)
public void onReceiver(String msg) {
System.out.println("HoshMqReceiver msg " + msg);
}
}
测试队列消息的发送和接受
从代码可以看出,我们的程序既是生产者也是消费者,实际情况中,生产者和消费者可能不是同一个程序
先启动 RabbitMQ server,在 dos 终端输入 rabbitmq-server.bat
剩下的就是需要一段测试代码,测试我们的队列消息的收发了
for(int i = 0; i < 10; i++) {
hoshMQSender.send("不知道是什么鬼的测试内容" + i);
}
最后,来看看使用 RabbitMQ 的效果吧