Introduction and Application of RabbitMQ

Introduction

The full name of MQ is Message Queue, which is message queue. RabbitMQ (default port: 15672, user name: guest password: guest) is a
message queue developed by erlang language and based on AMQP (Advanced Message Queue Advanced Message Queue Protocol) protocol.

Features

1、使得简单,功能强大。
2、基于AMQP协议。
3、社区活跃,文档完善。
4、高并发性能好,这主要得益于Erlang语言。
5、Spring Boot默认已集成RabbitMQ    

Application scenarios

1、任务异步处理。
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理,提高了应用程序的响应时间。

2、应用程序解耦合
MQ 相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。

Noun analysis

Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。
Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。

working principle

-----发送消息-----
1、生产者和Broker建立TCP连接。
2、生产者和Broker建立通道。
3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)

----接收消息-----
1、消费者和Broker建立TCP连接
2、消费者和Broker建立通道
3、消费者监听指定的Queue(队列)
4、当有消息到达Queue时Broker默认将消息推送给消费者。
5、消费者接收到消息。

Operating mode

1. Work queues work queue mode

  • A message can only be received by one consumer;
  • Rabbit uses polling to send messages to consumers evenly;
  • Consumers will receive the next message after processing a certain message.

2. Publish/Subscribe publish subscription model

  • Each consumer monitors its own queue.
  • The producer sends the message to the broker, and the exchange forwards the message to each queue bound to this exchange, and each queue bound to the exchange will receive the message

3. Routing routing mode

  • Each consumer monitors its own queue and sets the routingkey.
  • The producer sends the message to the switch, and the switch forwards the message to the specified queue according to the routingkey

4. Topics routing mode

  • Each consumer monitors its own queue and sets a routingkey with a wildcard.
  • The producer sends the message to the broker, and the switch forwards the message to the specified queue according to the routingkey
  • The symbol # can match multiple words, and the symbol * can match one word. Separated by "."

5. Header

  • The difference between the header mode and routing is that the header mode cancels the routing key and uses the key/value (key-value pair) matching queue in the header.

6. RPC

  • RPC is the method for the client to remotely call the server. MQ can be used to implement asynchronous RPC calls. It is implemented based on Direct switches. The process is as follows:

    1. The client is the producer and the consumer. It sends RPC call messages to the RPC request queue and monitors the RPC response queue.

    2. The server monitors the messages in the RPC request queue, and executes the server method after receiving the message, and obtains the result returned by the method

    3. The server sends the result of the RPC method to the RPC response queue

    4. The client (RPC caller) monitors the RPC response queue and receives the RPC call result.

application

Add coordinates

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
    </dependency>
<dependencies>

Producer

public class Producer01 {

//队列
private static final String QUEUE = "myQueue";

public static void main(String[] args) {
    //通过连接工厂创建新的连接和mq建立连接
    ConnectionFactory connectionFactory = new ConnectionFactory();
    connectionFactory.setHost("127.0.0.1");
    connectionFactory.setPort(5672);//端口
    connectionFactory.setUsername("guest");
    connectionFactory.setPassword("guest");
    //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个独立的mq
    connectionFactory.setVirtualHost("/");

    Connection connection = null;
    Channel channel = null;
    try {
        //建立新连接
        connection = connectionFactory.newConnection();
        //创建会话通道,生产者和mq服务所有通信都在channel通道中完成
        channel = connection.createChannel();
        //声明队列,如果队列在mq 中没有则要创建
        //参数:String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
        /**
         * 参数明细
         * 1、queue 队列名称
         * 2、durable 是否持久化,如果持久化,mq重启后队列还在
         * 3、exclusive 是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列则自动删除,如果将此参数设置true可用于临时队列的创建
         * 4、autoDelete 自动删除,队列不再使用时是否自动删除此队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除)
         * 5、arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间
         */
        channel.queueDeclare(QUEUE,true,false,false,null);
        //发送消息
        //参数:String exchange, String routingKey, BasicProperties props, byte[] body
        /**
         * 参数明细:
         * 1、exchange,交换机,如果不指定将使用mq的默认交换机(设置为"")
         * 2、routingKey,路由key,交换机根据路由key来将消息转发到指定的队列,如果使用默认交换机,routingKey设置为队列的名称
         * 3、props,消息的属性
         * 4、body,消息内容
         */
        //消息内容
        String message = "hello world 程序员";
        channel.basicPublish("",QUEUE,null,message.getBytes());
        System.out.println("send to mq "+message);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //关闭连接
        //先关闭通道
        try {
            channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}

consumer

public class Consumer01 {

//队列
private static final String QUEUE = "myQueue";

public static void main(String[] args) throws IOException, TimeoutException {
    //通过连接工厂创建新的连接和mq建立连接
    ConnectionFactory connectionFactory = new ConnectionFactory();
    connectionFactory.setHost("127.0.0.1");
    connectionFactory.setPort(5672);//端口
    connectionFactory.setUsername("guest");
    connectionFactory.setPassword("guest");
    //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个独立的mq
    connectionFactory.setVirtualHost("/");

    //建立新连接
    Connection connection = connectionFactory.newConnection();
    //创建会话通道,生产者和mq服务所有通信都在channel通道中完成
    Channel channel = connection.createChannel();

    //监听队列
    //声明队列,如果队列在mq 中没有则要创建
    //参数:String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
    /**
     * 参数明细
     * 1、queue 队列名称
     * 2、durable 是否持久化,如果持久化,mq重启后队列还在
     * 3、exclusive 是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列则自动删除,如果将此参数设置true可用于临时队列的创建
     * 4、autoDelete 自动删除,队列不再使用时是否自动删除此队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除)
     * 5、arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间
     */
    channel.queueDeclare(QUEUE,true,false,false,null);

    //实现消费方法
    DefaultConsumer defaultConsumer = new DefaultConsumer(channel){

        /**
         * 当接收到消息后此方法将被调用
         * @param consumerTag  消费者标签,用来标识消费者的,在监听队列时设置channel.basicConsume
         * @param envelope 信封,通过envelope
         * @param properties 消息属性
         * @param body 消息内容
         * @throws IOException
         */
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
            //交换机
            String exchange = envelope.getExchange();
            //消息id,mq在channel中用来标识消息的id,可用于确认消息已接收
            long deliveryTag = envelope.getDeliveryTag();
            //消息内容
            String message= new String(body,"utf-8");
            System.out.println("receive message:"+message);
        }
    };

    //监听队列
    //参数:String queue, boolean autoAck, Consumer callback
    /**
     * 参数明细:
     * 1、queue 队列名称
     * 2、autoAck 自动回复,当消费者接收到消息后要告诉mq消息已接收,如果将此参数设置为tru表示会自动回复mq,如果设置为false要通过编程实现回复
     * 3、callback,消费方法,当消费者接收到消息要执行的方法
     */
    channel.basicConsume(QUEUE,true,defaultConsumer);
    }
}

Guess you like

Origin blog.csdn.net/mrhs_dhls/article/details/107773287