RabbitMQConfig:
@Configuration
public class RabbitConfigBack {
public static final String TEST_QUEUE1 = "TEST_MSG1.MSG";
public static final String DEAD_LETTER_QUEUE_ROUTING_KEY1 = "DEAD_ROUTE_KEY1";
public static final String DEAD_QUEUE1 = "DEAD_MSG1.MSG";
public static final String TEST_EXCHANGE = "TEST_EXCHANGE.EXCHANGE";
public static final String DEAD_FANOUT_EXCHANGE = "DEAD_FANOUT_EXCHANGE.EXCHANGE";
@Value("${spring.rabbitmq.listener.simple.retry.max-interval}")
private int maxInterval;
@Bean
public Queue test1Queue() {
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", DEAD_FANOUT_EXCHANGE);
args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_ROUTING_KEY1);
args.put("x-message-ttl", maxInterval);
return QueueBuilder.durable(TEST_QUEUE1).withArguments(args).build();
}
@Bean
public Queue deadQueue1() {
Queue queue = new Queue(DEAD_QUEUE1, true, false, false);
return queue;
}
@Bean
public FanoutExchange testExchange() {
FanoutExchange fanoutExchange = new FanoutExchange(TEST_EXCHANGE, true, false);
return fanoutExchange;
}
@Bean
public FanoutExchange deadFanoutExchange() {
FanoutExchange fanoutExchange = new FanoutExchange(DEAD_FANOUT_EXCHANGE, true, false);
return fanoutExchange;
}
@Bean
Binding bindingExchangeTest1Msg(Queue test1Queue, FanoutExchange testExchange) {
return BindingBuilder.bind(test1Queue).to(testExchange);
}
@Bean
Binding bindingExchangeDead1Msg(Queue deadQueue1, FanoutExchange deadFanoutExchange) {
return BindingBuilder.bind(deadQueue1).to(deadFanoutExchange);
}
/**
* 获取rabbitmq的登录信息
*/
//ip地址
@Value("${spring.rabbitmq.host}")
private String host;
//端口号
@Value("${spring.rabbitmq.port}")
private int port;
//账号
@Value("${spring.rabbitmq.username}")
private String username;
//密码
@Value("${spring.rabbitmq.password}")
private String password;
/**
* 设置连接工厂
*/
@Bean
public ConnectionFactory connectionFactory() {
//实例缓存连接工厂,参数是 rabbitmq的ip和端口
CachingConnectionFactory factory = new CachingConnectionFactory(host, port);
//登录用户名
factory.setUsername(username);
//登录密码
factory.setPassword(password);
//设置主机的虚拟路径
factory.setVirtualHost("/");
//确认是否发布
factory.setPublisherConfirms(true);
return factory;
}
/**
* 设置rabbitmq模板
*/
@Bean
public RabbitTemplate rabbitTemplate() {
//将连接工程工厂对象注入模板里,然后返回一个模板对象
return new RabbitTemplate(this.connectionFactory());
}
}
Sender
@Component
public class MQSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void testDeadQueue(String msg) {
this.amqpTemplate.convertAndSend(RabbitConfigBack.TEST_QUEUE1, msg);
}
}
Consumer
@Component
public class Test1MQ {
@RabbitHandler
@RabbitListener(queues = RabbitConfigBack.TEST_QUEUE1)
public void process(String msg, Message message, Channel channel) throws IOException, InterruptedException {
try {
System.out.println(LocalDateTime.now() + ":Subscriber:" + new String(message.getBody(), "UTF-8"));
//当程序处理出现问题时,消息使用basicReject上报
int a = 0;
int b = 1 / a;
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
} catch (Exception ex) {
//出现异常手动放回队列
Thread.sleep(2000);
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
}
}
}
DEAD LETTER CONSUMER
@Component
public class DeadConsumerMQ {
@RabbitListener(queues = RabbitConfigBack.DEAD_QUEUE1)
public void process1(Message message, Channel channel) throws Exception {
System.out.println("Dead Subscriber:" + new String(message.getBody(), "UTF-8"));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
}
}
Yml
rabbitmq:
host: localhost
port: 5672
username: root
password: 123
listener:
simple:
acknowledge-mode: manual #手动ack
default-requeue-rejected: true
prefetch: 1
retry:
enabled: true
max-attempts: 3
max-interval: 6000 #重试最大间隔时间 10秒
initial-interval: 2000 #重试初始时间 2秒
multiplier: 2 #间隔时间乘子,间隔时间*乘子=下一次的间隔时间,最大不能超过设置的最大间隔时间
publisher-confirms: true
publisher-returns: true