RabbitMQ 基础

目录

一.核心概念

1.Producer和Consumer

2.Connection和Channel

[3.Virtual host](#3.Virtual host)

4.Queue

5.Exchange

二.工作模式

1.Simple(简单模式)

[2.Work Queue(工作队列)](#2.Work Queue(工作队列))

3.Publish/Subscribe(发布/订阅模式)

4.Routing(路由模式)

5.Topics(通配符模式)

6.RPC(RPC通信)

[7.Publisher Confirms(发布确认)](#7.Publisher Confirms(发布确认))

一.核心概念

1.Producer和Consumer

Producer:生产者,是RabbitMQ Server的客户端,向RabbitMQ发送消息;

Consumer:消费者,是RabbitMQ Server的客户端,从RabbitMQ接收消息;

Broker:是RabbitMQ Server,主要是接收和收发消息;

2.Connection和Channel

Connection:连接,是客户端和RabbitMQ服务器之间的⼀个TCP连接。这个连接是建立消息传递的基础, 它负责传输客户端和服务器之间的所有数据和控制信息;

Channel:信道, Channel是在Connection之上的⼀个抽象层。在 RabbitMQ 中,⼀个TCP连接可以有多个Channel,每个Channel 都是独立的虚拟连接。消息的发送和接收都是基于 Channel的。通道的主要作用是将消息的读写操作复用到同⼀个TCP连接上,这样可以减少建立和关闭连接的开销,提高性能。

3.Virtual host

虚拟主机。这是⼀个虚拟概念。它为消息队列提供了⼀种逻辑上的隔离机制。对于RabbitMQ而言,⼀个 BrokerServer 上可以存在多个 Virtual Host。当多个不同的用户使用同⼀个RabbitMQ Server 提供的服务时,可以虚拟划分出多个 vhost,每个用户在自己的 vhost 创建exchange/queue 等

4.Queue

队列,是RabbitMQ的内部对象,用于存储消息

5.Exchange

交换机。生产者将消息发送到Exchange,由交换机将消息按⼀定规则路由到⼀个或多个队列中。交换机只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息就会丢失。

RabbitMQ交换机有四种类型:Fanout、Direct、topic、Headers,不同类型有着不同的路由策略。

1)Fanout:广播,将消息交给所有绑定到交换机的队列;

2)Direct:定向,把消息交给符合指定routing key的队列;

3)Topic:通配符,把消息交给符合routing pattern(路由模式)的队列;

4)Headers:交换器不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。Headers类型的交换器性能会很差,而且也不使用,基本上不会看到它的存在。

RoutingKey:路由键。生产者将消息发给交换器时,指定的⼀个字符串,用来告诉交换机应该如何处理这个消息;

Binding Key:绑定。RabbitMQ中通过Binding(绑定)将交换器与队列关联起来,在绑定的时候⼀般会指定⼀个Binding Key,这样RabbitMQ就知道如何正确地将消息路由到队列了。

二.工作模式

一共有7中工作模式,想了解更多请看官网:RabbitMQ Tutorials | RabbitMQ

1.Simple(简单模式)

P:生产者,发送消息的程序

C:消费者,消费的接收者

Queue:消息队列,生产者可以向其发送信息,消费者可以从中取出消息

Producer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机
//4.声明队列
channel.queueDeclare("hello",true,false,false,null);
//5.发送消息
String msg="hello rabbitmq";
channel.basicPublish("","hello",null,msg.getBytes());
//6.释放连接
channel.close();
connection.close();

Consumer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机
//4.声明队列
channel.queueDeclare("hello",true,false,false,null);
//5.消费消息
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("接收到消息:"+new String(body));
    }
};
channel.basicConsume("hello",true,consumer);
//6.释放连接
channel.close();
connection.close();

2.Work Queue(工作队列)

一个生产者P,多个消费者C1、C2,Queue将信息分给不同消费者,消息不会重复,分配给不同的消费者。适用于集群环境中做异步处理。

Producer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机,声明队列
channel.queueDeclare(Constants.WORK_QUEUE,true,false,false,null);
//4.发送消息
String msg="hello work queue";
channel.basicPublish("",Constants.WORK_QUEUE,null,msg.getBytes());
//5.释放连接
channel.close();
connection.close();

Consumer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机,声明队列
channel.queueDeclare(Constants.WORK_QUEUE,true,false,false,null);
//4.消费消息
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("接收到消息:"+new String(body));
    }
};
channel.basicConsume(Constants.WORK_QUEUE,true,consumer);
//5.释放连接
channel.close();
connection.close();

3.Publish/Subscribe(发布/订阅模式)

X:交换机,是Fanout类型的

交换机将消息复制多份,每个消费者C都接收相同的消息。适用于消息需要被多个消费者同时接收的场景。

Producer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机
channel.exchangeDeclare(Constants.FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT,true);
//4.声明队列
channel.queueDeclare(Constants.FANOUT_QUEUE1,true,false,false,null);
channel.queueDeclare(Constants.FANOUT_QUEUE2,true,false,false,null);
//5.绑定交换机和队列
channel.queueBind(Constants.FANOUT_QUEUE1,Constants.FANOUT_EXCHANGE,"");
channel.queueBind(Constants.FANOUT_QUEUE2,Constants.FANOUT_EXCHANGE,"");
//6.发布消息
String msg="hello fanout";
channel.basicPublish(Constants.FANOUT_EXCHANGE,"",null,msg.getBytes());
//7.释放连接
channel.close();
connection.close();

Consumer:

java 复制代码
// 有两个消费者,这里只给出一个
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明队列
channel.queueDeclare(Constants.FANOUT_QUEUE1,true,false,false,null);
//5.消费消息
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("接收到消息:"+new String(body));
    }
};
channel.basicConsume(Constants.FANOUT_QUEUE1,true,consumer);
//6.释放连接
channel.close();
connection.close();

4.Routing(路由模式)

X:交换机,是Direct类型的

交换机根据RoutingKey分发给对应的消费者队列,就如上图的abc。适用于需要特定规则分发消息的场景。

Producer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机
channel.exchangeDeclare(Constants.DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT,true);
//4.声明队列
channel.queueDeclare(Constants.DIRECT_QUEUE1,true,false,false,null);
channel.queueDeclare(Constants.DIRECT_QUEUE2,true,false,false,null);
//5.绑定交换机和队列
channel.queueBind(Constants.DIRECT_QUEUE1,Constants.DIRECT_EXCHANGE,"a");
channel.queueBind(Constants.DIRECT_QUEUE2,Constants.DIRECT_EXCHANGE,"a");
channel.queueBind(Constants.DIRECT_QUEUE2,Constants.DIRECT_EXCHANGE,"b");
channel.queueBind(Constants.DIRECT_QUEUE2,Constants.DIRECT_EXCHANGE,"c");
//6.发布消息
String msg_a="hello routingKey is a";
channel.basicPublish(Constants.DIRECT_EXCHANGE,"a",null,msg_a.getBytes());
String msg_b="hello routingKey is b";
channel.basicPublish(Constants.DIRECT_EXCHANGE,"b",null,msg_b.getBytes());
String msg_c="hello routingKey is c";
channel.basicPublish(Constants.DIRECT_EXCHANGE,"c",null,msg_c.getBytes());
//7.释放连接
channel.close();
connection.close();

Consumer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明队列
channel.queueDeclare(Constants.DIRECT_QUEUE1,true,false,false,null);
//5.消费消息
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("接收到消息:"+new String(body));
    }
};
channel.basicConsume(Constants.DIRECT_QUEUE1,true,consumer);
//6.释放连接
channel.close();
connection.close();

5.Topics(通配符模式)

路由模式的升级版,路由的RoutingKey可以通过正则表达式的方式来定义,匹配更加灵活。

Producer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明交换机
channel.exchangeDeclare(Constants.TOPIC_EXCHANGE, BuiltinExchangeType.TOPIC,true);
//4.声明队列
channel.queueDeclare(Constants.TOPIC_QUEUE1,true,false,false,null);
channel.queueDeclare(Constants.TOPIC_QUEUE2,true,false,false,null);
//5.绑定交换机和队列
channel.queueBind(Constants.TOPIC_QUEUE1,Constants.TOPIC_EXCHANGE,"*.a.*");
channel.queueBind(Constants.TOPIC_QUEUE2,Constants.TOPIC_EXCHANGE,"*.*.b");
channel.queueBind(Constants.TOPIC_QUEUE2,Constants.TOPIC_EXCHANGE,"c.#");
//6.发布消息
String msg_a="hello topic,routingKey is r.a.few";
channel.basicPublish(Constants.TOPIC_EXCHANGE,"er.a.few",null,msg_a.getBytes());
String msg_b="hello topic,routingKey is erg.a.b";
channel.basicPublish(Constants.TOPIC_EXCHANGE,"erg.a.b",null,msg_b.getBytes());
String msg_c="hello topic,routingKey is c";
channel.basicPublish(Constants.TOPIC_EXCHANGE,"c.wfew",null,msg_c.getBytes());
//7.释放连接
channel.close();
connection.close();

​​​​​​​Consumer:

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明队列
channel.queueDeclare(Constants.TOPIC_QUEUE1,true,false,false,null);
//5.消费消息
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("接收到消息:"+new String(body));
    }
};
channel.basicConsume(Constants.TOPIC_QUEUE1,true,consumer);
//6.释放连接
channel.close();
connection.close();

6.RPC(RPC通信)

在RPC通信中,没有消费者和生产者,通过两个队列来实现一个可回调的过程。

1)客户端发送消息到⼀个指定的队列,并在消息属性中设置replyTo字段,这个字段指定了⼀个回调队列, 用于接收服务端的响应;

2)服务端接收到请求后,处理请求并发送响应消息到replyTo指定的回调队列;

3)客户端在回调队列上等待响应消息。⼀旦收到响应,客户端会检查消息的correlationId属性,以确保它是所期望的响应。

Client(客户端):

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.声明队列
channel.queueDeclare(Constants.RPC_REQUEST_QUEUE,true,false,false,null);
channel.queueDeclare(Constants.RPC_RESPONSE_QUEUE,true,false,false,null);
//4.发送请求
//消息内容
String msg="hello rpc";
//设置请求的唯一标识
String correlationId= UUID.randomUUID().toString();
//设置相关属性
AMQP.BasicProperties pros=new AMQP.BasicProperties().builder()
        .correlationId(correlationId)
        .replyTo(Constants.RPC_RESPONSE_QUEUE)
        .build();
channel.basicPublish("",Constants.RPC_REQUEST_QUEUE,pros,msg.getBytes());
//5.接收响应
final BlockingQueue<String> response=new ArrayBlockingQueue<>(1);
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        String respMsg=new String(body);
        System.out.println("接收到消息");
        if(correlationId.equals(properties.getCorrelationId())){
            response.offer(respMsg);
        }
    }
};
channel.basicConsume(Constants.RPC_RESPONSE_QUEUE,true,consumer);
String result=response.take();
System.out.println("rpc接收到的信息是:"+result);

​​​​​​​Server(服务端):

java 复制代码
//1.创建连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost(Constants.HOST);
connectionFactory.setPort(Constants.PORT);
connectionFactory.setUsername(Constants.USER_NAME);
connectionFactory.setPassword(Constants.PASSWORD);
connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST);
Connection connection=connectionFactory.newConnection();
//2.开启信道
Channel channel=connection.createChannel();
//3.接收请求
channel.basicQos(1);    //设置每次只能有一个请求
DefaultConsumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        String request=new String(body,"UTF-8");
        System.out.println("接收到请求消息");
        String response="针对请求:"+request+",请求成功";
        AMQP.BasicProperties pros=new AMQP.BasicProperties().builder()
                .correlationId(properties.getCorrelationId())
                .build();
        channel.basicPublish("",Constants.RPC_RESPONSE_QUEUE,pros,response.getBytes());
        channel.basicAck(envelope.getDeliveryTag(),false);
    }
};
channel.basicConsume(Constants.RPC_REQUEST_QUEUE,false,consumer);

7.Publisher Confirms(发布确认)

Publisher Confirms模式是RabbitMQ提供的⼀种确保消息可靠发送到RabbitMQ服务器的机制。在这种模式下,生产者可以等待RabbitMQ服务器的确认,以确保消息已经被服务器接收并处理。通过Publisher Confirms模式,生产者可以确保消息被RabbitMQ服务器成功接收, 从而避免消息丢失

的问题。

具体过程:

1)生产者将Channel设置为confirm模式(通过调用channel.confirmSelect()完成)后, 发布的每一条消息都会获得⼀个唯⼀的ID,生产者可以将这些序列号与消息关联起来,以便跟踪消息的状态;

2)当消息被RabbitMQ服务器接收并处理后,服务器会异步地向生产者发送⼀个确认(ACK)给生产者(包含消息的唯⼀ID),表明消息已经送达。

java 复制代码
public class PublisherConfirms {
    private static final Integer MESSAGE_COUNT = 10000;
    static Connection createConnection() throws Exception {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(Constants.HOST);
        connectionFactory.setPort(Constants.PORT); //需要提前开放端口号
        connectionFactory.setUsername(Constants.USER_NAME);//账号
        connectionFactory.setPassword(Constants.PASSWORD);  //密码
        connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST); //虚拟主机
        return connectionFactory.newConnection();
    }


    public static void main(String[] args) throws Exception {
        //单独确认
        publishingMessagesIndividually();
        //批量确认
        publishingMessagesInBatches();
        //异步确认
        //handlingPublisherConfirmsAsynchronously();
    }

    /**
     * 异步确认
     */
    private static void handlingPublisherConfirmsAsynchronously() throws Exception{
        try (Connection connection = createConnection()){
            //1. 开启信道
            Channel channel = connection.createChannel();
            //2. 设置信道为confirm模式
            channel.confirmSelect();
            //3. 声明队列
            channel.queueDeclare(Constants.PUBLISHER_CONFIRMS_QUEUE3, true, false, false, null);
            //4. 监听confirm
            //集合中存储的是未确认的消息ID
            long start = System.currentTimeMillis();
            SortedSet<Long> confirmSeqNo = Collections.synchronizedSortedSet(new TreeSet<>());

            channel.addConfirmListener(new ConfirmListener() {
                @Override
                public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                    if (multiple){
                        confirmSeqNo.headSet(deliveryTag+1).clear();
                    }else {
                        confirmSeqNo.remove(deliveryTag);
                    }
                }

                @Override
                public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                    if (multiple){
                        confirmSeqNo.headSet(deliveryTag+1).clear();
                    }else {
                        confirmSeqNo.remove(deliveryTag);
                    }
                    //业务需要根据实际场景进行处理, 比如重发, 此处代码省略
                }
            });
            //5. 发送消息
            for (int i = 0; i < MESSAGE_COUNT; i++) {
                String msg = "hello publisher confirms"+i;
                long seqNo = channel.getNextPublishSeqNo();
                channel.basicPublish("",Constants.PUBLISHER_CONFIRMS_QUEUE3, null, msg.getBytes());
                confirmSeqNo.add(seqNo);
            }
            while (!confirmSeqNo.isEmpty()){
                Thread.sleep(10);
            }
            long end = System.currentTimeMillis();
            System.out.printf("异步确认策略, 消息条数: %d, 耗时: %d ms \n",MESSAGE_COUNT, end-start);
        }
    }

    /**
     * 批量确认
     */
    private static void publishingMessagesInBatches() throws Exception{
        try(Connection connection = createConnection()) {
            //1. 开启信道
            Channel channel = connection.createChannel();
            //2. 设置信道为confirm模式
            channel.confirmSelect();
            //3. 声明队列
            channel.queueDeclare(Constants.PUBLISHER_CONFIRMS_QUEUE2, true, false, false, null);
            //4. 发送消息, 并进行确认
            long start = System.currentTimeMillis();
            int batchSize = 100;
            int outstandingMessageCount = 0;
            for (int i = 0; i < MESSAGE_COUNT; i++) {
                String msg = "hello publisher confirms"+i;
                channel.basicPublish("",Constants.PUBLISHER_CONFIRMS_QUEUE2, null, msg.getBytes());
                outstandingMessageCount++;
                if (outstandingMessageCount==batchSize){
                    channel.waitForConfirmsOrDie(5000);
                    outstandingMessageCount = 0;
                }
            }
            if (outstandingMessageCount>0){
                channel.waitForConfirmsOrDie(5000);
            }
            long end = System.currentTimeMillis();
            System.out.printf("批量确认策略, 消息条数: %d, 耗时: %d ms \n",MESSAGE_COUNT, end-start);

        }
    }

    /**
     * 单独确认
     */
    private static void publishingMessagesIndividually() throws Exception{
        try(Connection connection = createConnection()) {
            //1. 开启信道
            Channel channel = connection.createChannel();
            //2. 设置信道为confirm模式
            channel.confirmSelect();
            //3. 声明队列
            channel.queueDeclare(Constants.PUBLISHER_CONFIRMS_QUEUE1, true, false, false, null);
            //4. 发送消息, 并等待确认
            long start = System.currentTimeMillis();
            for (int i = 0; i < MESSAGE_COUNT; i++) {
                String msg = "hello publisher confirms"+i;
                channel.basicPublish("",Constants.PUBLISHER_CONFIRMS_QUEUE1, null, msg.getBytes());
                //等待确认
                channel.waitForConfirmsOrDie(5000);
            }
            long end = System.currentTimeMillis();
            System.out.printf("单独确认策略, 消息条数: %d, 耗时: %d ms \n",MESSAGE_COUNT, end-start);
        }
    }
}
相关推荐
齐木卡卡西在敲代码2 小时前
kafka的pull的依据
分布式·kafka
W|J3 小时前
Rabbit 实战指南-学习笔记
rabbitmq
DN金猿6 小时前
rabbitmq发送的延迟消息时间过长就立即消费了
分布式·rabbitmq
Monly216 小时前
RabbitMQ:SpringAMQP Topic Exchange(主题交换机)
spring boot·rabbitmq·java-rabbitmq
程序员不迷路9 小时前
Kafka学习
分布式·kafka
北i9 小时前
ZooKeeper 一致性模型解析:线性一致性与顺序一致性的平衡
分布式·zookeeper·云原生
IT技术小密圈9 小时前
图解分布式锁: 5分钟搞懂分布式锁
分布式·后端·面试
bing_15810 小时前
kafka 生产者是如何发送消息的?
分布式·kafka
Monly2116 小时前
RabbitMQ:数据隔离
分布式·rabbitmq