最近有个Java项目要引入RabbitMQ,监听另一个非Java项目的消息。
我是Java项目,引入Spring AMQP依赖,利用注解轻松搞定Exchanges、Queues、Routing key的注册绑定,实现消息的监听和发送。
另一个非Java项目因为时间比较赶只实现了消息的监听和发送,Exchanges、Queues、Routing key的注册绑定需要手动进行。
本文介绍下怎么利用Spring AMQP的注解实现RabbitMQ消息发送和监听,以及怎么登录控台手动创建User,Virtual host,绑定Exchanges、Queues、Routing key。
第一部分:利用Spring AMQP的注解实现rabbit消息发送和监听
1.引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置类
@Configuration
@Slf4j
public class RabbitMqConfig {
@Value("${availableProcessors:4}")
private Integer availableProcessors;
@Bean
public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory, MetricsManager metricsManager){
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
//设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
log.info("ConfirmCallback: 相关数据:{}", correlationData);
log.info("ConfirmCallback: 确认情况:{}", ack);
log.info("ConfirmCallback: 原因:{}", cause);
}
});
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback(){
@Override
public void returnedMessage(ReturnedMessage returned) {
log.info("ReturnsCallback: 消息:{}", returned);
}
});
return rabbitTemplate;
}
/**
* rabbitListenerContainerFactory是beanName的默认名称,如果不叫这个名称会多出一个默认的bean,@RabbitListener containerFactory
* @param connectionFactory
* @return
*/
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//代码手动ack
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//开启消费者数量
factory.setConcurrentConsumers(availableProcessors);
// PrefetchCount 每次接受数据量,默认250
return factory;
}
3.发送消息
@Component
@Slf4j
public class GenerateImagesSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void convertAndSend(String messageData, String exchange, String routingKey) {
try {
rabbitTemplate.convertAndSend(exchange, routingKey, messageData, (Message message) -> {
message.getMessageProperties().setHeader("x-delay", TimeUnit.SECONDS.toMillis(1));
return message;
});
log.info("发送消息成功 routingKey:{}", routingKey);
} catch (Exception e) {
log.error("发送消息失败", e);
}
}
}
4.监听消息
@Component
@Slf4j
public class TestReceiver {
/**
* 监听xxxx
*
* @param tag
* @param channel
* @param message
*/
@RabbitListener(bindings = {@QueueBinding(value = @Queue("Qqueue"),
exchange = @Exchange(value = "Exchange", type = "x-delayed-message",
arguments = @Argument(name = "x-delayed-type", value = "direct")),
key = "Routing key")})
public void generateTextSuccessEvent(@Header(AmqpHeaders.DELIVERY_TAG) long tag, Channel channel, Message message) {
MDC.put(TRACE_ID_NAME, "MQ" + UuidUtil.nextAsTextWithoutHyphen16());
String msg = null;
try {
msg = new String(message.getBody(), "UTF-8");
log.info("xxxx完成事件监听......msg:{}", msg);
} catch (Exception e) {
log.error("xxxx完成事件监听", e);
} finally {
ack(tag, channel, msg);
}
}
private void ack(long tag, Channel channel, String msg) {
try {
channel.basicAck(tag, false);
} catch (Exception e) {
log.error("【报警】basicAck失败:msg={}", msg, e);
}
}
}
第二部分:登录控台手动创建User、Virtual host,绑定Exchanges、Queues、Routing key
1.创建user
2.创建Virtual host
3.user绑定Virtual host
4.创建Exchanges
5.创建Queues
6.Exchanges绑定Queues