RabbitMQ学习笔记

RabbitMQ学习笔记

一、安装部署

​ 建议使用docker ,安装docker后,下载mq镜像即可,这里不进行具体操作,

docker pull rabbitmq:management
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672  rabbitmq:management

二、java编程学习

官网java-api:https://rabbitmq.github.io/rabbitmq-java-client/api/current/com/rabbitmq/client/package-summary.html

官网文档:https://www.rabbitmq.com/getstarted.html

    RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting in a post box, you can be sure that Mr. or Ms. Mailperson will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.
The major difference between RabbitMQ and the post office is that it doesn't deal with paper, instead it accepts, stores and forwards binary blobs of data ‒ *messages*
    RabbitMQ是一个消息代理:它接受和转发消息。你可以把它想象成一个邮局:当你把你想要寄的邮件放到一个邮箱里,你可以确定邮递员先生或女士最终会把邮件送到收件人那里。在这个类比中,RabbitMQ是一个邮箱、一个邮局和一个邮递员。
RabbitMQ和邮局之间的主要区别是它不处理纸张,而是接受、存储和转发二进制blob数据- *消息*
	There aren't any message timeouts; RabbitMQ will redeliver the message when the consumer dies. It's fine even if processing a message takes a very, very long time.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MENDLjfL-1595819081883)(D:\markdown\picture\4237997-edeb65e914ef98ee.png)]

1.简单模式(Simple)

1.1 模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMlGTCiW-1595819081886)(D:\markdown\picture\python-one.png)]

​ 这是最简单的模型,一个生产者(Producer),只有一个消费者(Consumer)

1.2 生产者

代码逻辑:获取connection-》创建channel-》申明队列(非必要)-》发送消息-》关闭channel-》关闭connection

    /**
     * 简单模式,不指定交换机(exchage)直接发送到 队列中
     *
     * @param args
     * @throws IOException
     * @throws TimeoutException
     */
    public static void main(String[] args) throws IOException, TimeoutException {
        //获取连接
        Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
        //获取通道
        Channel channel = connection.createChannel();
        //创建队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        // 发送消息
        String msg = "hello simple";
        channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
        System.out.println("seng message");
        channel.close();
        connection.close();
    }
1.3 消费者

代码逻辑:获取connection-》创建channel-》申明队列(非必要)-》消费消息-》关闭channel-》关闭connection

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
        Channel channel = connection.createChannel();
//        channel.queueDeclare(SimpleProducer.QUEUE_NAME,false,false,false,null);
        // autoAck 是否自动应答
        // false : 默认,不自动应答,在没有进行人工应答的前提下,该消息可以重复消费,消息队列不会进行删除
        boolean autoAck =true;
        channel.basicConsume(SimpleProducer.QUEUE_NAME,autoAck, new DefaultConsumer(channel) {

            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(new String(body, "utf-8"));
            }

        });

    }
1.4 结果分析
  1. 消费者 需要更新合理设置 autoAck(自动应答)

​ false: 默认,不自动应答。在没有进行人工应答的前提下,消息队列不会将该消息进行删除,消息会标记成unack。

​ unack的消息在特定的情况可以进行重新消费(产生unack的消费者和rabbitmq断开连接后,该消息的状态变成ready状态,可以有其他消费者继续消费)

​ 说明: 手工应答方式 com.rabbitmq.client.Channel#basicAck

​ true: 自动应答,客户端接收到消息后,就会给rabbitmq发送确认信息,表示客户端已经接收,但是不关心客户端是否处理正常

2.正常情况下一个消息只能被一个消费者消费

2.工作模式(Work queues)

​ 工作模式 就是消费者会有多个,一个消息只能被一个消费者消费,消息默认采用轮训的方式进行消费,即每个消费者轮着 消费一个消息。

另外:消费者在不自动应答,或者手工忘记应答的情况下,rabbitmq中消息的状态会变成unack状态,该消费者断开后,这些unack的消息状态会变成

​ ready状态

2.1模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHoSxOWN-1595819081888)(D:\markdown\picture\python-two.png)]

2.2 生产者和消费者

​ 代码参简单模式,多个消费者就好

2.3轮循分发(Round-robin dispatching)

​ By default, RabbitMQ will send each message to the next consumer, in sequence. On average every consumer will get the same number of messages. This way of distributing messages is called round-robin. Try this out with three or more workers

默认情况下,RabbitMQ将按顺序将每条消息发送给下一个使用者。平均而言,每个消费者将获得相同数量的消息。这种分发消息的方式称为循环

2.4公平分发(Fair dispatch)

img

In order to defeat that we can use the basicQos method with the prefetchCount = 1 setting. This tells RabbitMQ not to give more than one message to a worker at a time. Or, in other words, don’t dispatch a new message to a worker until it has processed and acknowledged the previous one. Instead, it will dispatch it to the next worker that is not still busy

​ 从上上面的描述中,我们知道了 多消费者的情况下,采用的是轮循的方式,但是实际过程中,有的消费者处理比较快,有的消费者处理慢,这个时候我们希望处理快的消费者能尽可能多的消费消息。

​ 基于上述实际需求,rabbitMQ提供了 一个com.rabbitmq.client.Channel#basicQos(int)

prefetchCount maximum number of messages that the server will deliver, 0 if unlimited

 /**
     * Request a specific prefetchCount "quality of service" settings
     * for this channel.
     * <p>
     * Note the prefetch count must be between 0 and 65535 (unsigned short in AMQP 0-9-1).
     *
     * @param prefetchCount maximum number of messages that the server
     *                      will deliver, 0 if unlimited
     * @throws java.io.IOException if an error is encountered
     * @see #basicQos(int, int, boolean)
     */
    void basicQos(int prefetchCount) throws IOException;

​ 在消费者中的channel进行设置

 Channel channel = connection.createChannel();
 channel.basicQos(1);
2.5结果分析

1.多个消费者均分消息进行消费,默认采用轮训的方式进行消费,即每个消费者轮着 消费一个消息。

2.正常情况下一个消息只能被一个消费者消费

3.在公平分发中,如果所有消费者channel.basicQos(prefetchCount);,prefetchCount不一定,从先现象上看还是轮询方式

​ 当rabbitmq要将队列中的一条消息投递给消费者时,会遍历该队列上的消费者列表,选一个合适的消费者,然后将消息投递出去。其中挑选消费者的一个依据就是看消费者对应的channel上未ack的消息数是否达到设置的prefetch_count个数,如果未ack的消息数达到了prefetch_count的个数,则不符合要求。当挑选到合适的消费者后,中断后续的遍历。

消费者A(处理快1s)消费者B(处理慢5s)分发方式
不设置prefetchCount不设置prefetchCount轮询方式
不设置prefetchCountprefetchCount=1公平方式
prefetchCount=1prefetchCount=1公平方式
prefetchCount=mprefetchCount=n公平方式

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

​ 简单模式、工作模式 都是生产者直接将消息发送到QUEQE中,然后RabbitMQ将消息分发给对应消费者。正常情况下,一个消息只能被一个消费者消费。但是实际业务需求中,常常会需要一个消息需要被多个消费者消费,比如

​ 公众号关注:作者发表了一遍文章(类似消息),然后每个关注公众号的人就能收到通知,可以去查看新的文章。

​ 账号注册:账号注册成功后,需要发邮件,发短信

上述的场景其实 就是典型的发布、订阅模式,RabbitMQ当然也是支持的。

3.1模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-auIbU35q-1595819081893)(D:\markdown\picture\exchanges.png)]

​ 这是RabbitMQ 完整的消息模式 生产者(Producer),交换机(exchange),队列(QUEQE),消费者(Consumer)

The core idea in the messaging model in RabbitMQ is that the producer never sends any messages directly to a queue. Actually, quite often the producer doesn’t even know if a message will be delivered to any queue at all.

Instead, the producer can only send messages to an exchange. An exchange is a very simple thing. On one side it receives messages from producers and the other side it pushes them to queues. The exchange must know exactly what to do with a message it receives. Should it be appended to a particular queue? Should it be appended to many queues? Or should it get discarded. The rules for that are defined by the exchange type.

There are a few exchange types available: direct, topic, headers and fanout. We’ll focus on the last one – the fanout. Let’s create an exchange of that type, and call it logs:

3.2 exchange(交换机)

​ 消息的一个中间传递者,生产者只需要关注交换机,无需关注消息的消费情况,只需要将消息投递给交换机就好。

​ 交换机不会存储消息,如果没有队列绑定交换机,消息将会丢失

​ 下面摘取官网对4中交换机的类型的描述

type用途简单解释
BuiltinExchangeType.FANOUTThe fanout exchange is very simple. As you can probably guess from the name, it just broadcasts all the messages it receives to all the queues it knows订阅模式,消息会全部无差异的分发到与交换机绑定的队列中
BuiltinExchangeType.DIRECTThe routing algorithm behind a direct exchange is simple - a message goes to the queues whose binding key exactly matches the routing key of the message路由模式,消息会根据routekey发到不同的队列中
BuiltinExchangeType.TOPICMessages sent to a topic exchange can’t have an arbitrary routing_key - it must be a list of words, delimited by dots. The words can be anything, but usually they specify some features connected to the message. A few valid routing key examples: “stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”. There can be as many words in the routing key as you like, up to the limit of 255 bytes.
The binding key must also be in the same form. The logic behind the topic exchange is similar to a direct one - a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key. However there are two important special cases for binding keys:
主题模式,采用模糊匹配的方式,将消息发到不通的队列中
BuiltinExchangeType.HEADERS
3.3生产者

​ 代码逻辑:获取connection-》创建channel-》声明交换机(非必要)-》发送消息(明确知道是哪个交换机)-》关闭channel-》关闭connection

   public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
        final Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
        String msgTemplate = "producer[pubSub] send message {%s}";
        String msg = "";
        int messageNum = 100;
        for(int i=0;i<messageNum;i++){
            msg =  String.format(msgTemplate,i);
            channel.basicPublish(EXCHANGE_NAME,"",false,false,null,msg.getBytes("UTF-8"));
            System.out.println(msg);
        }

        channel.close();
        connection.close();
    }

The most important change is that we now want to publish messages to our defined exchange instead of the nameless one. We need to supply a routingKey when sending, but its value is ignored for fanout exchanges

3.4消费者

​ 代码逻辑:获取connection-》创建channel-》声明交换机(非必要)-》消息队列绑定交换机(非必要)-》消费消息(需要知道消费那个队列QUEUE)-》关闭channel-》关闭connection

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
        final Channel channel = connection.createChannel();
        //随机创建队列,并将队列和交换机进行绑定,这个动作可以在rabbitMQ控制台
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, ProducerPubSub.EXCHANGE_NAME, "");
        //队列和交换机绑定结束
        channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(consumerTag + "----" + new String(body, "UTF-8"));
            }
        });

//        channel.close();
//        connection.close();

    }
3.5结果分析

1.交换机、队列可以在RabbitMQ控制台创建,也可以通过采用声明的方式进行创建

2.生产者 需要关注 将消息发送到 哪个交换机;消息者需要关注 从哪个队列中获取消息

3.交换机和队列需要进行绑定,可以通过程序的方式绑定也可以通过RabbitMQ控制台进行绑定

4.发布订阅模式中exchange的type需要设置成 BuiltinExchangeType.FANOUT,basicPublish中的routeKey不能为null,但是这个值在 BuiltinExchangeType.FANOUT情况下忽略。

4.路由模式(routing)

3.1模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O32SN4I7-1595819081894)(D:\markdown\picture\direct-exchange.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-11kDSXsu-1595819081896)(D:\markdown\picture\direct-exchange-multiple.png)]

3.2生产者

代码逻辑:获取connection-》创建channel-》声明交换机(非必要)-》发送消息(明确知道是哪个交换机,哪些key)-》关闭channel-》关闭connection

    public final static  String  EXCHANGE_NAME ="routing-exchange";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
        final Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        String msgTemplate = "producer[routing] send message {%s}";
        String msg = "";
        int messageNum = 100;
        for(int i=0;i<messageNum;i++){
            msg =  String.format(msgTemplate,i);
            channel.basicPublish(EXCHANGE_NAME,"route1",false,false,null,msg.getBytes("UTF-8"));
            System.out.println(msg);
        }

        channel.close();
        connection.close();
    }
3.3消费者

代码逻辑:获取connection-》创建channel-》声明交换机(非必要)-》消息队列绑定交换机和routekey(非必要)-》消费消息(需要知道消费那个队列QUEUE)-》关闭channel-》关闭connection

public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
        final Channel channel = connection.createChannel();
        //随机创建队列,并将队列和交换机进行绑定,这个动作可以在rabbitMQ控制台
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, ProducerRouting.EXCHANGE_NAME, "route1");
        //队列和交换机
        channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(consumerTag + "----" + new String(body, "UTF-8"));
            }
        });

//        channel.close();
//        connection.close();

    }
3.4结果分析

1.路由模式比订阅模式灵活,只将消费者感兴趣的消息放到消费者绑定的队列中

2.一个消息只能绑定一个routekey

5.topic模式

5.1模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NQc61v9B-1595819081897)(D:\markdown\picture\python-five.png)]

5.2生产者和消费者

​ 代码和路由模式一样,有2点差别

交换机类型:topic模式 交换机类型 设置成 topic

routekey:routekey采用 XXX.XXX.XXX 这样以.分割的方式,支持*,#模糊匹配

​ *: 匹配一个word,例如 route.msg. * 匹配 route.msg.hello,route.msg.world,不匹配 route.msg.hello.word

​ #:匹配多个word 例如 route.msg. # 匹配 route.msg.hello,route.msg.world,也匹配 route.msg.hello.word

5.3结果分析

1.topic模式相比路由模式更加另外,消费者关注的routekey在不调整的情况下,可以获取新的生产者产生的消息

2.topic模式在不使用*,# 通配符的时候,和路由模式一样,只有routekey完全一致,才能进行消费

3.topic 模式生产者产生消息的topic 是明确的

4.交换机类下 direct 和topic 的差异 就在routekey的解析匹配上

6.RPC模式

6.1模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YamcvK5X-1595819081898)(D:\markdown\picture\python-six.png)]

  • For an RPC request, the Client sends a message with two properties: replyTo, which is set to a anonymous exclusive queue created just for the request, and correlationId, which is set to a unique value for every request.

  • The request is sent to an rpc_queue queue.

  • The RPC worker (aka: server) is waiting for requests on that queue. When a request appears, it does the job and sends a message with the result back to the Client, using the queue from the replyTo field.

  • The client waits for data on the reply queue. When a message appears, it checks the correlationId property. If it matches the value from the request it returns the response to the application.

    6.2服务端
    public class RpcServer {
    
        public static void main(String[] args) throws IOException, TimeoutException {
            Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
            final Channel channel = connection.createChannel();
            channel.queueDeclare(RpcClient.RPC_QUEUE_NAME, false, false, false, null);
    
            channel.basicConsume(RpcClient.RPC_QUEUE_NAME, false, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    System.out.println(consumerTag + "--rpc-server--" + new String(body, "UTF-8"));
                    AMQP.BasicProperties replyProps = new AMQP.BasicProperties
                            .Builder()
                            .correlationId(properties.getCorrelationId())
                            .build();
                    channel.basicPublish("", properties.getReplyTo(), replyProps, "response".getBytes("UTF-8"));
                    channel.basicAck(envelope.getDeliveryTag(), false);
    
    
                }
            });
    
    //        channel.close();
    //        connection.close();
    
        }
    }
    
    6.3客户端
    public class RpcClient {
    
        public final static String RPC_QUEUE_NAME = "RPC-QUEUE";
        public  final static String CALL_BACK_QUEUE = "CALLBACK-RPC-QUEUE";
    
        public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
            Connection connection = ConnectionFactory.createConnection(RabbitMQconfigBuilder.initRabbitMQconfig());
            final Channel channel = connection.createChannel();
            final String corrId = UUID.randomUUID().toString();
    
            String replyQueueName = channel.queueDeclare().getQueue();
            AMQP.BasicProperties props = new AMQP.BasicProperties
                    .Builder()
                    .correlationId(corrId)
                    .replyTo(replyQueueName)
                    .build();
            String message = "rpc-client call (hello)";
            channel.basicPublish("", RPC_QUEUE_NAME, props, message.getBytes("UTF-8"));
    
            final BlockingQueue<String> response = new ArrayBlockingQueue<>(1);
    
            String ctag = channel.basicConsume(replyQueueName, true, (consumerTag, delivery) -> {
                if (delivery.getProperties().getCorrelationId().equals(corrId)) {
                    response.offer(new String(delivery.getBody(), "UTF-8"));
                }
            }, consumerTag -> {
            });
    
            String result = response.take();
            System.out.println(result);
            channel.basicCancel(ctag);
            channel.close();
            connection.close();
        }
    }
    
    6.4分析结果

    1.服务端和客户端都是同时是生产者和消费者

    2.客户端通过在产生消息的时候,通过AMQP.BasicProperties 进行参数扩展,增加消息之外的额外信息,用户服务端进行处理

7.消费者应答(ack)

消费者应答,就上rabbitmq将消费分发给消费者后,消费者给rabbitmq的一个响应。有自动和手动两种,默认是手动。

​ 消费者代码 中设置 autoAck 即可 进行自动和手动的切换

String basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, CancelCallback cancelCallback)

​ 这个消息者应答 就消息在rabbitmq中queue中的的状态变化,如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-woAyFci8-1595819081899)(D:\markdown\picture\image-20200727103701879.png)]

8.生产者确认(Publisher Confirms)

​ 生产者确认:生产者将消息发送给rabbitmq后,rabbitmq对生产者的应答,告诉生产者消息是否传达到

Publisher confirms are a RabbitMQ extension to implement reliable publishing. When publisher confirms are enabled on a channel, messages the client publishes are confirmed asynchronously by the broker, meaning they have been taken care of on the server side.

1.Publisher confirms are enabled at the channel level with the Channel#confirmSelect method:

this method must be called on every channel that you expect to use publisher confirms. Confirms should be enabled just once, not for every message published.

​ 每一个channel都要进行设置,不是发送每个消息的时候都要设置

2.Channel#waitForConfirmsOrDie(long) method. The method returns as soon as the message has been confirmed. If the message is not confirmed within the timeout or if it is nack-ed (meaning the broker could not take care of it for some reason), the method will throw an exception. The handling of the exception will usually consists in logging an error message and/or retrying to send the message.

3.channel.addConfirmListener((sequenceNumber, multiple) ,rabbitmq异步回掉处理

sequence number: a number that identifies the confirmed or nack-ed message. We will see shortly how to correlate it with the published message.
multiple: this is a boolean value. If false, only one message is confirmed/nack-ed, if true, all messages with a lower or equal sequence number are confirmed/nack-ed.

9.持久化

​ 消息的持久化,是为了防止因为rabbitmq故障,导致消息丢失的设计的。但是持久化不是针对整个rabbitmq的,是针对队列和消息的

When RabbitMQ quits or crashes it will forget the queues and messages unless you tell it not to. Two things are required to make sure that messages aren’t lost: we need to mark both the queue and messages as durable.

First, we need to make sure that the queue will survive a RabbitMQ node restart. In order to do so, we need to declare it as durable:

声明队列持久化,rabbitmq重启后,队列还存在

boolean durable = true;
channel.queueDeclare("hello", durable, false, false, null);

Second, we need to mark our messages as persistent - by setting MessageProperties (which implements BasicProperties) to the value PERSISTENT_TEXT_PLAIN

消息持久化,设置持久化的格式

channel.basicPublish("", "task_queue",
            MessageProperties.PERSISTENT_TEXT_PLAIN,
            message.getBytes());

三、常用java-API讲解

1.1 获取connection

 com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
 connectionFactory.setHost(rabbitMQConfig.getHost());
 connectionFactory.setPort(rabbitMQConfig.getPort());
 connectionFactory.setVirtualHost(rabbitMQConfig.getVirtualHost());
 connectionFactory.setUsername(rabbitMQConfig.getUserName());
 connectionFactory.setPassword(rabbitMQConfig.getPassword());
 return connectionFactory.newConnection();

1.2 创建channel 通道

connection.createChannel()

1.3 声明队列queue

/**
     * Actively declare a server-named exclusive, autodelete, non-durable queue.
     * The name of the new queue is held in the "queue" field of the {@link com.rabbitmq.client.AMQP.Queue.DeclareOk} result.
     * @see com.rabbitmq.client.AMQP.Queue.Declare
     * @see com.rabbitmq.client.AMQP.Queue.DeclareOk
     * @return a declaration-confirm method to indicate the queue was successfully declared
     * @throws java.io.IOException if an error is encountered
     */
    Queue.DeclareOk queueDeclare() throws IOException;

    /**
     * Declare a queue
     * @see com.rabbitmq.client.AMQP.Queue.Declare
     * @see com.rabbitmq.client.AMQP.Queue.DeclareOk
     * @param queue the name of the queue
     * @param durable true if we are declaring a durable queue (the queue will survive a server restart)
     * @param exclusive true if we are declaring an exclusive queue (restricted to this connection)
     * @param autoDelete true if we are declaring an autodelete queue (server will delete it when no longer in use)
     * @param arguments other properties (construction arguments) for the queue
     * @return a declaration-confirm method to indicate the queue was successfully declared
     * @throws java.io.IOException if an error is encountered
     */
    Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
                                 Map<String, Object> arguments) throws IOException;

如果rabbitmq中没有该队列 ,则按照申明参数进行创建。如果rabbitmq中存在该队列(名称匹配),则比较申明的队列和已经存在的队列属性是否一致,如果不一致,该申明处代码异常报错。如果一致,则申明队列成功,保证了RabbitMQ存在该队列

1.4 申明交换机exchange

如果rabbitmq中没有exchange ,则按照申明参数进行创建。如果rabbitmq中存在该exchange(名称匹配),则比较申明的exchange和已经存在的exchange属性是否一致,如果不一致,该申明处代码异常报错。如果一致,则申明exchange成功,保证了RabbitMQ存在该exchange

1.5 发送消息

1.6 接收消息

采用响应编程的方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值