RabbitMQ概念、以及第一個rabbit的demo

概念認識

Broker:簡單來說就是消息隊列服務器實體。

  •     Exchange:消息交換機,它指定消息按什麼規則,路由到哪個隊列。
  •     Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列。
  •     Binding:綁定,它的作用就是把exchange和queue按照路由規則綁定起來。
  •     Routing Key:路由關鍵字,exchange根據這個關鍵字進行消息投遞。
  •     vhost:虛擬主機,一個broker裏可以開設多個vhost,用作不同用戶的權限分離。
  •     producer:消息生產者,就是投遞消息的程序。
  •     consumer:消息消費者,就是接受消息的程序。
  •     channel:消息通道,在客戶端的每個連接裏,可建立多個channel,每個channel代表一個會話任務。

消息隊列的使用過程大概如下:

  1.     客戶端連接到消息隊列服務器,打開一個channel。
  2.     客戶端聲明一個exchange,並設置相關屬性。
  3.     客戶端聲明一個queue,並設置相關屬性。
  4.     客戶端使用routing key,在exchange和queue之間建立好綁定關係。
  5.     客戶端投遞消息到exchange。

      exchange接收到消息後,就根據消息的key和已經設置的binding,進行消息路由,將消息投遞到一個或多個隊列裏。

      exchange也有幾個類型,完全根據key進行投遞的叫做Direct交換機,例如,綁定時設置了routing key爲”abc”,那麼客戶端提交的消息,只有設置了key爲”abc”的纔會投遞到隊列。對key進行模式匹配後進行投遞的叫做Topic交換機,符號”#”匹配一個或多個詞,符號”*”匹配正好一個詞。例如”abc.#”匹配”abc.def.ghi”,”abc.*”只匹配”abc.def”。還有一種不需要key的,叫做Fanout交換機,它採取廣播模式,一個消息進來時,投遞到與該交換機綁定的所有隊列。

       RabbitMQ支持消息的持久化,也就是數據寫在磁盤上,爲了數據安全考慮,我想大多數用戶都會選擇持久化。消息隊列持久化包括3個部分:

    exchange持久化,在聲明時指定durable => 1
    queue持久化,在聲明時指定durable => 1
    消息持久化,在投遞時指定delivery_mode => 2(1是非持久化)

        如果exchange和queue都是持久化的,那麼它們之間的binding也是持久化的。如果exchange和queue兩者之間有一個持久化,一個非持久化,就不允許建立綁定。
 

 

rabbitmq官方說明文檔地址:

https://www.rabbitmq.com/getstarted.html

 

通信方式主要可以分爲兩種:

其一:點對點(即沒有交換機)

其二:發佈訂閱(有交換機exchange)

常用的兩種:

其一:Routing路由方式

其二:Topics比較靈活,路徑匹配

 

服務啓動及配置

首先啓動rabbitmq-server

service rabbitmq-server start

本地端口訪問:  http://192.168.239.129:15672

訪問成功,則證明安裝成功。才能進入後續操作

 

創建一個新的用戶:

創建一個虛擬主機

 

設置虛擬主機的權限permissions,和用戶綁定

點擊虛擬主機的名字

選擇剛剛創建的用戶

 

退出登錄,用剛剛的用戶登錄成功即可

可參考:

https://blog.51cto.com/13877966/2297056

https://blog.csdn.net/qq_38455201/article/details/80308771

 

demo

導入依賴:

<dependencies>
        <!--rabbitmq-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

 

創建Send 生產者

package com.ldgroup.rabbitmqdemo.service;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * @Description
 * @Author by mocar小師兄
 * @Date 2020/4/25 0:58
 **/
public class Send {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    public static final String QUEUE_A = "QUEUE_A";


    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.239.129");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("mocar");
        connectionFactory.setPassword("mocar");
        connectionFactory.setVirtualHost("/mocar");
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();
        //隊列聲明,隊列不存在則創建,否則不做處理
        //exclusive:獨有的,是否只允許當前連接使用此隊列
        channel.queueDeclare(QUEUE_A,true,false,false,null);
        String msg="第一次發送消息rabbitmq";
        channel.basicPublish("",QUEUE_A,null,msg.getBytes());
        System.out.println("發送完成");

    }
}

 

發送成功,產生一條帶消費的消息 

 

 

 

創建Receiving消費者

package com.ldgroup.rabbitmqdemo.service;

import com.rabbitmq.client.*;

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

/**
 * @Description
 * @Author by mocar小師兄
 * @Date 2020/4/25 1:56
 **/
public class Receiving {
    public static final String QUEUE_A = "QUEUE_A";

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.239.129");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("mocar");
        connectionFactory.setPassword("mocar");
        connectionFactory.setVirtualHost("/mocar");
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();
       //創建消費者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            //等待隊列有消息之後,自動回調
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //super.handleDelivery(consumerTag, envelope, properties, body);
                //消費消息
                String msg = new String(body,"utf-8");
                System.out.println("消費消息:\t" + msg);
            }
        };
        //讓消費者監聽隊列
        //消費後ACK確認消息成功消費
        channel.basicConsume(QUEUE_A,true,defaultConsumer);
        System.out.println("成功消費");
    }
}

 

消息成功被消費

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章