本文使用的是linux版本的RabbitMQ,版本是:
rabbitmq-server-3.6.15-1.el6.noarch.rpm
rabbitmq_delayed_message_exchange插件
插件下载地址:
http://www.rabbitmq.com/community-plugins.html
由于我安装的是3.6.*系列的版本号,因此对应的rabbitmq_delayed_message_exchange
插件也选择3.6.x的,怕版本不对应不兼容踩坑就麻烦了。下载后将解压后的rabbitmq_delayed_message_exchange-20171215-3.6.x.ez 放在RabbitMQ安装目录下的plugins
目录下,并使用如下命令启动这个插件:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
最后在RabbitMQ安装根目录使用这个命令:sbin/rabbitmq-plugins list ,查看是否已经安装rabbitmq_delayed_message_exchange
插件
由于我是用的gradle 所以直接为了方便快捷直接引入了,cloud版本可以自己搞成F或者G的都没问题
compile "org.springframework.cloud:spring-cloud-dependencies:Edgware.SR6"
Spring Boot的版本我使用的是1.5.7.RELEASE
接下来在application.yml
文件中加入mq配置:
也很简单,代码如下:
@Bean public CustomExchange getSingleToDelayExchange() { Mapargs = new HashMap<>(); args.put("x-delayed-type", "direct"); return new CustomExchange(rabbitMqProperty.getSingleToDelayExchange(),"x-delayed-message",true, false,args); } @Bean public Queue getSingleToDelayQueue() { return new Queue(rabbitMqProperty.getSingleToDelayQueue()); } @Bean public Binding getSingleToDelayRoutingkey() { return BindingBuilder.bind(getSingleToDelayQueue()).to(getSingleToDelayExchange()).with(rabbitMqProperty.getSingleToDelayRoutingkey()).noargs(); } /** * 因为要设置回调类,所以应是prototype类型,如果是singleton类型,则回调类为最后一次设置 */ @Bean // @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) { RabbitTemplate template = new RabbitTemplate(connectionFactory); template.setMessageConverter(messageConverter); return template; } @Bean(name = "simpleRabbitListenerContainerFactory") public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, MessageConverter messageConverter) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMaxConcurrentConsumers(20); factory.setConcurrentConsumers(5); factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); factory.setMessageConverter(messageConverter); return factory; } @Bean public MessageConverter messageConverter() { return new Jackson2JsonMessageConverter(); } @Bean(name = "rabbitAdmin") public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { return new RabbitAdmin(connectionFactory); }
public class DelayQueueProducer { @Resource RabbitMqSendUtil rabbitMqSendUtil; @Resource RabbitMqProperty rabbitMqProperty; public void sendMsg(String msg,int expires) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("消息发送时间:"+sdf.format(new Date())); MessagePostProcessor messagePostProcessor = new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setHeader("x-delay",expires); return message; } }; rabbitMqSendUtil.send(rabbitMqProperty.getSingleToDelayExchange(), rabbitMqProperty.getSingleToDelayRoutingkey(), msg,messagePostProcessor); } }
@Component public class DelayQuerueConsumer { @RabbitListener(queues = "${spring.rabbitmq.SingleToDelayQueue}") @RabbitHandler public void receive(String msg, Channel channel, Message message) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("消息接收时间:"+sdf.format(new Date())); System.out.println("接收到的消息:"+msg); try { channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); } catch (IOException e) { e.printStackTrace(); } } }
分别调用模拟测试先发送一个10秒、一个2秒的延迟消息。都可以完美消费