生产者发布消息至交换器,未被正确路由时,未设置mandatory参数及ReturnListener监听处理,消息会被broker丢弃,如果不想消息丢失,可以使用备份交换器,这样可以将未被正确路由的消息存储到备份交换机指定的队列。

public static void main(String[] argv) throws Exception {
   ConnectionFactory factory = new ConnectionFactory();
   factory.setHost("localhost");
   try (Connection connection = factory.newConnection();
        Channel channel = connection.createChannel()) {
       /** 定义一个备份交换机 和普通交换机无区别 */
       channel.exchangeDeclare("alternate_exchange", "fanout", true, false, null);
       channel.queueDeclare("alternate_queue", true, false, false, null);
       channel.queueBind("alternate_queue", "alternate_exchange", "");

       Map<String, Object> args = new HashMap<>(1);
       args.put("alternate-exchange", "alternate_exchange");
       /** 定义业务交换机 通过参数设置备份交换机 */
       channel.exchangeDeclare("biz_exchange", "direct", true, false, args);
       channel.queueDeclare("biz_queue", true, false, false, null);
       channel.queueBind("biz_queue", "biz_exchange", "biz_route");

       channel.basicPublish("biz_exchange", "biz_route_nil", MessageProperties.PERSISTENT_TEXT_PLAIN, "hello star".getBytes());
   }
   Scanner scanner = new Scanner(System.in);
   while (scanner.hasNext()) {
       System.out.println(scanner.next());
   }
}

定义一个本分交换机,与普通交换机无区别,然后在普通业务交换机中使用参数 alternate-exchange 关联备份交换机,此时如果消息未被正常路由,消息将会路由到备份交换机的队列上。
备份交换机建议设置为 fanout ,这样可以避免出现业务消息未被正确路由时,又未能正确匹配备份交换机的绑定队列(如 direct 时),导致消息丢失。