RabbitMQ提高消息可靠性的方法

mandatory参数

当mandatory参数设置为true的时候,交换器没法根据自身的类型和路由键找到一个符合条件的队列,那么RabbitMQ会调用Basic.Return命令将消息返回给生产者。当mandatory参数设置为false时,出现上述情形,则消息直接被丢弃。ide

生产者是如何获取到没有被正确路由到合适的队列的消息呢?能够经过调用channel.addReturnListener来添加ReturnListener监听器实现。示例部分代码以下:spa

//建立信道
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME,"direct",true,false,null);
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,ROUTING_KEY);
        String message = "Hello Rabbitmq";
        channel.basicPublish(EXCHANGE_NAME,ROUTING_KEY,true, MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());
        channel.addReturnListener(new ReturnListener() {
            @Override
            public void handleReturn(int i, String s, String s1, String s2, AMQP.BasicProperties basicProperties, byte[] bytes) throws IOException {
                String message = new String(bytes);
                System.out.println("Basic Return 返回的结果是:" + message);
            }
        });

上述代码中生产者若是没有成功的将消息路由到队列,此时RabbitMQ会经过Basic.Return来返回“Hello Rabbitmq”这条消息,以后生产者客户端经过ReturnListener监听到了这个事件,上述代码运行的结果是:Basic Return 返回的结果是:Hello Rabbitmq。code

备份交换器

备份交换器,英文名称为Alternate Exchange,简称AE,或者更直白的称之为“备胎交换器”。能够经过在声明交换器(调用channel.exchangeDeclare方法)的时候添加alternate-exchange参数来实现,也能够经过策略的方式实现,若是同时使用则前者的优先级更高,会覆盖掉Policy的设置。orm

      //建立信道
        Channel channel = connection.createChannel();
        //设置备份交换器的参数
        Map<String,Object> arg = new HashMap<String, Object>();
        arg.put("alternate","myAe");
        channel.exchangeDeclare("normalExchange","direct",true,false,arg);
        channel.exchangeDeclare("myAe","fanout",true,false,null);
        channel.queueDeclare("normalQueue",true,false,false,null);
        channel.queueBind("normalQueue","normalExchange","normalKey");
        channel.queueDeclare("unroutrdQueue",true,false,false,null);
        channel.queueBind("unroutrdQueue","myAe","");

上述代码中声明了两个交换器的normalExchange和myAe,分别绑定了noemalQueue和unroutrdQueue这两个队列,同时将myAe设置为normalExchange的备份交换器,注意myAe的交换器类型为fanout。以下图:blog

一样,能够采用Policy的方式设置备份交换器,能够参考以下:rabbitmq

rabbitmqctl set_policy AE "^normalExchange$" `{"alternate-exchange": "myAe"}`队列

备份交换器其实和普通的交换器没有太大的区别,为了方便使用,建议设置为fanout类型,如若想设置为direct或者topic的类型的也没有什么不能够的。须要注意的是,消息被重发到备份交换器时路由键和从生产者发出的路由键是同样的事件

对于备份交换器,存在如下几种特殊的状况:路由

  ❤ 若是设置的备份交换器不存在,客户端和RabbitMQ服务端都不会有异常出现,此时消息会丢失。get

  ❤ 若是备份交换器没有绑定任何队列,客户端和RabbitMQ服务端不会有异常出现,此时消息会丢失。

  ❤ 若是备份交换器没有任何匹配的队列,客户端和RabbitMQ都不会有异常出现,此时消息会丢失。

  ❤ 若是备份交换器和mandatory参数一块儿使用,那么mandatory参数无效。

参考:《RabbitMQ实战指南》 朱忠华  著;

相关文章
相关标签/搜索