1.整合RabbitMQ
<!--rabbitmq消息队列-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置文件
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
listener:
simple:
acknowledge-mode: manual #手动应答
concurrency: 5 #消费端最小并发数
max-concurrency: 10 #消费端最大并发数
prefetch: 5 #一次请求中预处理的消息数量
cache:
channel:
size: 50 #缓存的channel数量
3.设置配置类
@Configuration
public class MQConfig {
public static final String DELAY_EXCHANGE = "Ex.DelayExchange";
public static final String DELAY_QUEUE = "MQ.DelayQueue";
public static final String DELAY_KEY = "delay.#";
@Bean
public TopicExchange delayExchange(){
Map<String, Object> pros = new HashMap<>();
// 设置交换机支持延迟消息推送
pros.put("x-delayed-message", "topic");
TopicExchange exchange = new TopicExchange(DELAY_EXCHANGE, true, false, pros);
exchange.setDelayed(true);
return exchange;
}
@Bean
public Queue delayQueue(){
return new Queue(DELAY_QUEUE, true);
}
@Bean
public Binding delayBinding(){
return BindingBuilder.bind(delayQueue()).to(delayExchange()).with(DELAY_KEY);
}
}
4.消息生产端
@Component
public class MQSender {
@Autowired
private RabbitTemplate rabbitTemplate;
final RabbitTemplate.ConfirmCallback confirmCallback= new RabbitTemplate.ConfirmCallback() {
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("correlationData: " + correlationData);
System.out.println("ack: " + ack);
if(!ack){
System.out.println("异常处理....");
}
}
};
final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("return exchange: " + exchange + ", routingKey: "
+ routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText);
}
};
// 发送延时消息
public void sendDelayMessage(Object message) {
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(confirmCallback);
rabbitTemplate.setReturnCallback(returnCallback);
// UUID 全局唯一
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString().replaceAll("-",""));
// 发送消息时指定 header 延迟时间
rabbitTemplate.convertAndSend(MQConfig.DELAY_EXCHANGE, "delay.boot", message,
new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
// 设置消息持久化
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
// message.getMessageProperties().setHeader("x-delay", "6000");
message.getMessageProperties().setDelay(6000);
System.err.println("发送消息的时间:" + System.currentTimeMillis());
return message;
}
}, correlationData);
}
}
5.消息消费端
@Component
public class MQReceiver {
@RabbitListener(queues = "MQ.DelayQueue")
@RabbitHandler
public void onDelayMessage(Message msg, Channel channel) throws IOException {
System.err.println("接收到消息的时间:" + System.currentTimeMillis());
long deliveryTag = msg.getMessageProperties().getDeliveryTag();
channel.basicAck(deliveryTag, true);
System.err.println("接收到的消息:" + new String(msg.getBody()));
}
}
6.测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class MQSenderTest {
@Autowired
private MQSender mqSender;
@Test
public void sendDelayMsg() throws Exception {
String msg = "发送延时消息";
mqSender.sendDelayMessage(msg);
}
}