生产者发布消息至交换器,未被正确路由时,未设置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 时),导致消息丢失。