RabbitMQ几种典型模式

本文详细介绍简单模式Simple、工作模式Work、发布订阅模式Publish/Subscribe、路由模式Routing、通配符模式Topics、远程调用模式RPC(暂不对该队列模式进行详解)

模式1:简单模式(Simple / HelloWorld 单生产单消费)
简单的发送与接收,没有特别的处理。

å¨è¿éæå¥å¾çæè¿°

RabbitMQ连接(公共的连接方法,其他模式共用此方法)

package com.sc.queuemode.connection; 
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {
    public static Connection getConnection() throws IOException, TimeoutException {
        //定义连接池
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //连接地址
        connectionFactory.setHost("localhost");
        //连接端口
        connectionFactory.setPort(5672);
        //用户名
        connectionFactory.setUsername("guest");
        //密码
        connectionFactory.setPassword("guest");
        //通过连接工厂获取连接
        Connection connection = connectionFactory.newConnection();
        //返回连接
        return connection;
    }
}

Producer:

package com.sc.queuemode.simple;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {
    private final static String QUEUE_NAME = "hello";
    public static void main(String[] args) throws IOException, TimeoutException {
        //获取连接
        Connection connection = ConnectionUtil.getConnection();
        //从连接中声明通道
        Channel channel = connection.createChannel();
        //队列申明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //消息内容
        String message = "simple queue hello world !";
        //推送发布消息
        //basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        //信道关闭
        channel.close();
        //连接关闭
        connection.close();
    }
}

Consumer:

package com.sc.queuemode.simple;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Consumer1 {
    
    private final static String QUEUE_NAME = "hello_queue";
    
    public static void main(String[] args) throws IOException, TimeoutException{
        //获取连接
        Connection connection = ConnectionUtil.getConnection();
        //声明信道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //声明消费者
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body) 
                    throws IOException {
                String message = new String(body,"UTF-8");
                System.out.println("customer 消费消息:"+message);
            }
        };
        channel.basicConsume(QUEUE_NAME, true,consumer);
    }
}

模式2:工作模式(Work单发送多接收)
一个生产者端,多个消费者端。示例中为了保证消息发送的可靠性,使队列持久化了。同时为了防止接收端在处理消息时down掉,只有在消息处理完成后才发送消息确认。

å¨è¿éæå¥å¾çæè¿°

Producer:

package com.sc.queuemode.work;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {
    
    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws IOException, TimeoutException {
        //获取连接
        Connection connection = ConnectionUtil.getConnection();
        //声明信道
        Channel channel = connection.createChannel();
        //队列申明,durable:true消息持久化
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        //消息内容
        String message ="hello work queue";
        for(int i = 0; i < 20; i++) {
            //发布消息
            //basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
            channel.basicPublish("", QUEUE_NAME, null, (i + " " +message).getBytes());
        }
        //关闭通道
        channel.close();
        //连接关闭
        connection.close();
    }
    


Consumer:
消费者1

package com.sc.queuemode.work;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;
/*
* 消费者1
*/
public class Consumer1 {
    
    private final static String QUEUE_NAME = "work_queue";
    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        
        //声明队列的消费者O
        Consumer consumer1 = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                //channel.basicConsume(QUEUE_NAME, false, consumer1);
                String message = new String(body, "UTF-8");
                System.out.println("customer1 消费消息:"+message);
                //手动返回结果
                channel.basicAck(envelope.getDeliveryTag(), false);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //定义的消费者监听队列 autoAck:true自动返回结果,false手动返回
        channel.basicConsume(QUEUE_NAME, false,consumer1);
    }
}

消费者2

package com.sc.queuemode.work;
    import java.io.IOException;
    import java.util.concurrent.TimeoutException;    
    import com.rabbitmq.client.AMQP.BasicProperties;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.Consumer;
    import com.rabbitmq.client.DefaultConsumer;
    import com.rabbitmq.client.Envelope;
    import com.sc.queuemode.connection.ConnectionUtil;
    /*
    * 消费者2
    */
    public class Consumer2 {
        private final static String QUEUE_NAME = "work_queue";
    
       public static void main(String[] args) throws IOException, TimeoutException{
           Connection connection = ConnectionUtil.getConnection();
           Channel channel = connection.createChannel();
           channel.queueDeclare(QUEUE_NAME, true, false, false, null);
           
           //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
           channel.basicQos(1);
           
           //声明队列的消费者
           Consumer consumer2 = new DefaultConsumer(channel){
               @Override
               public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                       throws IOException {
                   //channel.basicConsume(QUEUE_NAME, false, consumer1);
                   String message = new String(body, "UTF-8");
                   System.out.println("customer2 消费消息:"+message);
                   channel.basicAck(envelope.getDeliveryTag(), false);
                   try {
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
           };
           //定义的消费者监听队列(第二个参数:true自动返回结果,false手动返回)
           channel.basicConsume(QUEUE_NAME, false,consumer2);
    }
}

模式3:发布、订阅模式(Publish/Subscribe)
使用场景:发布、订阅模式,生产者端发送消息,多个消费者同时接收所有的消息。

å¨è¿éæå¥å¾çæè¿°

Producer:

package com.sc.queuemode.publish_subscrible;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {

    private final static String EXCHANGE_NAME = "publishSubscrible_exchange";
    
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //声明交换机Exchange类型为fanout
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        
        String message = "publish/subscrible hello world";
        channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
        System.out.println("发布订阅 生产者 发布消息:"+message);
        channel.close();
        connection.close();
    }
}

生产者端发布消息到交换机,使用“fanout”方式发送,即广播消息,不需要使用queue,发送端不需要关心谁接收。
消费者1:

package com.sc.queuemode.publish_subscrible;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer1 {
    
    //队列1
    private final static String QUEUE_NAME = "publishSubscrible_queue";
    private final static String EXCHANGE_NAME = "publishSubscrible_exchange";

    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        //声明队列
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        //绑定队列到交换机
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
        
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        
        //申明消费者
        Consumer consumer1 = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发布订阅 消费者1 消费消息:"+message);
                //手动返回结果
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, consumer1);
    }
}

消费者2:

package com.sc.queuemode.publish_subscrible;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer2 {

    //队列2
    private final static String QUEUE_NAME = "publishSubscrible_queue2";
    private final static String EXCHANGE_NAME = "publishSubscrible_exchange";

    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        //声明队列
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        //绑定队列到交换机
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
        
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        
        //申明消费者
        Consumer consumer2 = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("发布订阅 消费者2 消费消息:"+message);
                //手动返回结果
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, consumer2);
    }

}

消费者端:
1、声明和生产者端一样的交换机。
2、注意binding queue的时候,channel.queueBind()的第三个参数Routing key为空,即所有的消息都接收。如果这个值不为空,在exchange type为“fanout”方式下该值被忽略!
 


模式4:路由模式(Routing)
生产者按routing key发送消息,不同的消费者端按不同的routing key接收消息。

å¨è¿éæå¥å¾çæè¿°

Producer:

package com.sc.queuemode.routing;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {
    
    private final static String EXCHANGE_NAME = "routing_exchange";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //声明交换机Exchange类型为direct
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        
        //发布消息3种routingKey的消息
        String message = "hello info";
        channel.basicPublish(EXCHANGE_NAME, "info", null, message.getBytes());
        System.out.println("路由模式发布info消息:"+message);
        
        message = "hello warning";
        channel.basicPublish(EXCHANGE_NAME, "warning", null, message.getBytes());
        System.out.println("路由模式发布warning消息:"+message);
        
        message = "hello error";
        channel.basicPublish(EXCHANGE_NAME, "error", null, message.getBytes());
        System.out.println("路由模式发布error消息:"+message);
    }
}

消费者端和模式3(发布订阅模式)的区别:
1、exchange的type为direct
2、发送消息的时候加入了routing key
Consumer:
消费者1

package com.sc.queuemode.routing;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer1 {

    private final static String QUEUE_NAME = "routing_queue1";
    private final static String EXCHANGE_NAME = "routing_exchange";
    
    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        //申明队列
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        
        //队列绑定交换机,指定路由routingKey
        //结束路由routingKey为info和warning的消息
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "info");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "warning");
        
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        
        //声明消费者
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("路由模式 消费者1 消费消息:"+message);
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, consumer);
    }
}

消费者2

package com.sc.queuemode.routing;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer2 {
    
    private final static String QUEUE_NAME = "routing_queue2";
    private final static String EXCHANGE_NAME = "routing_exchange";
    
    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        //申明队列
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        
        //队列绑定交换机,指定路由routingKey
        //结束路由routingKey为error的消息
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error");
        
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        
        //声明消费者
        Consumer consumer2 = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("路由模式 消费者2 消费消息:"+message);
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, consumer2);
    }
}

消费者端和模式3(发布订阅模式)的区别:
在绑定queue和exchange的时候使用了路由routing key,即从该exchange上只接收routing key指定的消息。
 

模式5:通配符(或主题)模式(Topics ,按topic发送接收)
生产者端不只按固定的routing key发送消息,而是按字符串“匹配”发送,消费者端同样如此。
与之前的路由模式相比,它将信息的传输类型的key更加细化,以“key1.key2.keyN…”的模式来指定信息传输的key的大类型和大类型下面的小类型,让消费者端可以更加精细的确认自己想要获取的信息类型。而在消费者端,不用精确的指定具体到哪一个大类型下的小类型的key,而是可以使用类似正则表达式(但与正则表达式规则完全不同)的通配符在指定一定范围或符合某一个字符串匹配规则的key,来获取想要的信息。“通配符交换机”(Topic Exchange)将路由键和某模式进行匹配。此时队列需要绑定在一个模式上。符号“#”匹配一个或多个词,符号“*”仅匹配一个词。

å¨è¿éæå¥å¾çæè¿°

Producer:

package com.sc.queuemode.topics;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.sc.queuemode.connection.ConnectionUtil;

public class Producter {
    
    private static final String EXCHANGE_NAME = "topic_exchange";
    
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel =connection.createChannel();
        //声明交换机类型为topic
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        
        String message = "发布了一条中国新闻消息";
        channel.basicPublish(EXCHANGE_NAME, "china.news", null, message.getBytes());
        
        message = "发布了一条中国天气消息";
        channel.basicPublish(EXCHANGE_NAME, "china.weather", null, message.getBytes());
        
        message = "发布了一条美国新闻消息";
        channel.basicPublish(EXCHANGE_NAME, "usa.news", null, message.getBytes());
        
        message = "发布了一条美国天气消息";
        channel.basicPublish(EXCHANGE_NAME, "usa.weather", null, message.getBytes());
    }
}

生产者和模式4(路由模式)的区别:
1、交换机exchange的type为topic
2、发送消息的routing key不是固定的单词,而是匹配字符串,如"china.#",*匹配一个单词,#匹配0个或多个单词。因此如“china.#”能够匹配到“china.news.info”,但是“china.* ”只会匹配到“china.news”

Consumer:
消费者1

package com.sc.queuemode.topics;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer1 {

    private static final String QUEUE_NAME = "topics_queue1";
    private static final String EXCHANGE_NAME = "topic_exchange";
    
    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //交换机申明
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        //队列声明
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        //队列绑定交换机并制定路由routingKey
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "china.#");
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        //申明消费者
        Consumer consumer1 = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("通配符模式 消费者1消费:"+message);
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, consumer1);
    }
}

消费者2

package com.sc.queuemode.topics;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.sc.queuemode.connection.ConnectionUtil;

public class Customer2 {
    
    private static final String QUEUE_NAME = "topics_queue2";
    private static final String EXCHANGE_NAME = "topic_exchange";
    
    public static void main(String[] args) throws IOException, TimeoutException{
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //交换机申明
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        //队列声明
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        //队列绑定交换机并制定路由routingKey
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "usa.#");
        //同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
        //保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
        //在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
        channel.basicQos(1);
        //申明消费者
        Consumer consumer2 = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("通配符模式 消费者2消费:"+message);
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, consumer2);
    }
}

 

--------------------- 
作者:通往架构师的路上 
来源:CSDN 
原文:https://blog.csdn.net/caiqing116/article/details/84032099 
版权声明:本文为博主原创文章,转载请附上博文链接!

发布了75 篇原创文章 · 获赞 41 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/Erica_1230/article/details/89847221