【准备】
准备一、RabbitMQ的安装
//安装erlang所需依赖包
yum install unixODBC unixODBC-devel wxBase wxGTK SDL wxGTK-gl
//下载erlang
wget https://packages.erlang-solutions.com/erlang/rpm/centos/7/x86_64/esl-erlang_19.3.6-1~centos~7_amd64.rpm
//安装erlang
rpm -ivh esl-erlang_19.3.6-1~centos~7_amd64.rpm
//安装RabbitMQ
rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.6/rabbitmq-server-3.6.6-1.el7.noarch.rpm
rpm -ivh rabbitmq-server-3.6.6-1.el7.noarch.rpm
配置省略。。。
注:
1.erlang与rabbitMQ的版本对应 (https://www.rabbitmq.com/which-erlang.html)
2.erlang下载(https://www.erlang-solutions.com/resources/download.html)
3.rabbitmq下载(https://www.rabbitmq.com/install-rpm.html#downloads)
准备二、下载插件-rabbitmq_delayed_message_exchange
1.下载(https://www.rabbitmq.com/community-plugins.html)
2.将下载的插件放入插件目录(cd /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.6/plugins/)
3.启用插件(cd /usr/sbin)
#启用插件
rabbitmq-plugins enable/disable rabbitmq_delayed_message_exchange
#查看插件列表
rabbitmq-plugins list
最前面会有 【E】 标志
4.重启RabbitMQ
service rabbitmq-server restart
再次查询插件列表时,可以看见 【E*】 标志,表示插件已经生效,接下来看代码
【RabbitMQ延时队列的创建、消息的生产者和消费者】
1. 声明交换机、延时队列、routingkey,并绑定
@Configuration
public class DelayedRabbitMQConfig {
public static final String DELAYED_QUEUE_NAME = "delayQueue.queue.demo";
public static final String DELAYED_EXCHANGE_NAME = "delayQueue.exchange.demo";
public static final String DELAYED_ROUTING_KEY = "delayQueue.routingkey.demo";
@Bean
public Queue immediateQueue() {
return new Queue(DELAYED_QUEUE_NAME);
}
@Bean
public CustomExchange customExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange(DELAYED_EXCHANGE_NAME, "x-delayed-message", true, false, args);
}
@Bean
public Binding bindingNotify(@Qualifier("immediateQueue") Queue queue,
@Qualifier("customExchange") CustomExchange customExchange) {
return BindingBuilder.bind(queue).to(customExchange).with(DELAYED_ROUTING_KEY).noargs();
}
}
2. 消息的生产者
@RestController
@RequestMapping("/demo")
@Slf4j
public class TestController {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostMapping("testRabbitMQ")
@ApiOperation(value = "testRabbitMQ", notes = "", response = String.class)
public Result testRabbitMQ(@ApiParam(value = "MSG", required = true) @RequestParam String msg,
@ApiParam(value = "延时时间(单位ms)", required = true) @RequestParam Integer delayTime) {
log.info("当前时间:{},收到请求,msg:{},delayTime:{}", new Date(), msg, delayTime);
rabbitTemplate.convertAndSend(DELAYED_EXCHANGE_NAME, DELAYED_ROUTING_KEY, msg, a -> {
a.getMessageProperties().setDelay(delayTime);
return a;
});
return Response.success();
}
}
3. 消息的消费者
@Slf4j
@Component
public class DeadLetterQueueConsumer {
// //死信队列名称(与普通队列的差别)
// @RabbitListener(queues = "delayQueue.deadLetter.demo")
//停止使用死信队列来完成延时队列功能,RabbitMQ安装【延时插件】后,使用【延时队列名称】
@RabbitListener(queues = "delayQueue.queue.demo")
public void testConsumer(Message message, Channel channel) throws IOException {
//获取消息
String msg = new String(message.getBody());
//手动确认已经接受到了消息,RabbitMQ不再Re_Queue(处理消费端报错后,Re_Queue造成的死循环)
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
log.info("当前时间:{},延时队列收到消息:{}", new Date().toString(), msg);
}
}