springboot+rabbit 2
继上一篇的延伸
利用rabbitmq的两种特性: Time To Live(TTL)、Dead Letter Exchanges(DLX)实现延时队列
rabbitmq 配置
import com.demo.common.constant.Constants;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* RabbitMq配置
*
* @Author:xuanyan
* @Date 2020/1/3
**/
@Configuration
public class RabbitMqConfig {
/**
* 延时使用开始
* 利用两种特性实现延时,初始化queue及exchange之间的binding关系
*/
/**
* 创建一个立即消费队列
* @return
*/
@Bean
public Queue immediateQueue() {
// 第一个参数是创建的queue的名字,第二个参数是是否支持持久化
return new Queue(Constants.IMMEDIATE_QUEUE, true);
}
/**
* 创建一个延时队列
* @return
*/
@Bean
public Queue delayQueue() {
Map<String, Object> params = new HashMap<>();
// x-dead-letter-exchange 声明了队列里的死信转发到的DLX名称,
params.put("x-dead-letter-exchange", Constants.IMMEDIATE_EXCHANGE);
// x-dead-letter-routing-key 声明了这些死信在转发时携带的 routing-key 名称。
params.put("x-dead-letter-routing-key", Constants.IMMEDIATE_ROUTING_KEY);
return new Queue(Constants.DELAY_QUEUE, true, false, false, params);
}
@Bean
public DirectExchange immediateExchange() {
// 一共有三种构造方法:
// 第一种,可以只传exchange的名字,
// 第二种,可以传exchange名字,是否支持持久化,是否可以自动删除,
// 第三种,在第二种参数上可以增加Map,Map中可以存放自定义exchange中的参数
return new DirectExchange(Constants.IMMEDIATE_EXCHANGE, true, false);
}
@Bean
public DirectExchange deadLetterExchange() {
//一共有三种构造方法
//第一种,可以只传exchange的名字
//第二种,可以传exchange名字,是否支持持久化,是否可以自动删除,
//第三种在第二种参数上可以增加Map,Map中可以存放自定义exchange中的参数
return new DirectExchange(Constants.DEAD_LETTER_EXCHANGE, true, false);
}
/**
* 把立即消费的队列和立即消费的exchange绑定在一起
* @return
*/
@Bean
public Binding immediateBinding() {
return BindingBuilder.bind(immediateQueue()).to(immediateExchange()).with(Constants.IMMEDIATE_ROUTING_KEY);
}
/**
* 把立即消费的队列和立即消费的exchange绑定在一起
* @return
*/
@Bean
public Binding delayBinding() {
return BindingBuilder.bind(delayQueue()).to(deadLetterExchange()).with(Constants.DELAY_ROUTING_KEY);
}
/**
* 延时使用结束
*/
}
消费者 Receiver
import com.demo.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @Author:xuanyan
* @Date 2020/1/3
**/
@Slf4j
@Component
@EnableRabbit
@Configuration
public class Receiver {
/**
* 消费者开始
*/
@RabbitListener(queues = Constants.IMMEDIATE_QUEUE)
@RabbitHandler
public void get(String msg) {
System.out.println(new Date() + " 收到延时消息了: " + msg);
}
/**
* 消费者结束
*/
}
生产者 Sender
import com.demo.common.constant.Constants;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 生产者
* @Author:xuanyan
* @Date 2020/1/3
**/
@Component
public class Sender {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 发送延迟消息
* delayTime 毫秒
*/
public void send(String msg, int delayTime) {
System.out.println("delayTime:[ms]" + delayTime);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
this.rabbitTemplate.convertAndSend(
Constants.DEAD_LETTER_EXCHANGE,
Constants.DELAY_ROUTING_KEY,
msg,
message -> {
message.getMessageProperties().setExpiration(delayTime + "");
System.out.println(sdf.format(new Date()) + " 发送完成.");
return message;
});
}
}
import com.demo.common.annotation.OpenAPI;
import com.demo.utils.mq.Sender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author:xuanyan
* @Date 2020/1/3
**/
@Api(description = "测试")
@RestController
public class TestController {
@Autowired
private Sender sender;
@OpenAPI
@ApiOperation("测试rabbitmq")
@GetMapping("/get")
public void test(){
sender.send("msg--send", 50000);
}
}
调起请求会在发送成功的50秒后返回message的内容