訊息中介軟體rabbitMQ

zc發表於2021-08-15

簡介

RabbitMQ是一個訊息代理 - 一個訊息系統的媒介。它可以為你的應用提供一個通用的訊息傳送和接收平臺,並且保證訊息在傳輸過程中的安全。RabbitMQ實現了高階訊息佇列協議(AMQP)的開源訊息代理軟體(亦稱面向訊息的中介軟體)。其採用Erlang語言編寫的,群集和故障轉移是構建在開放電信平臺框架上的。

特點

  1. RabbitMQ是部署最廣泛的開源訊息代理。

  2. RabbitMQ有成千上萬的使用者,是最受歡迎的開源訊息代理之一。從T-Mobile 到Runtastic,RabbitMQ在全球範圍內的小型初創企業和大型企業中都得到使用。

  3. RabbitMQ輕巧,易於在內部和雲中部署。它支援多種訊息傳遞協議。RabbitMQ可以部署在分散式和聯合配置中,以滿足大規模,高可用性的要求。

  4. RabbitMQ可在許多作業系統和雲環境上執行,併為大多數流行語言提供了廣泛的開發人員工具。

技術亮點

可靠性
RabbitMQ提供了多種技術可以讓你在效能和可靠性之間進行權衡。這些技術包括永續性機制、投遞確認、釋出者證實和高可用性機制。

路由靈活
訊息在到達佇列前是通過交換機進行路由的。RabbitMQ為典型的路由邏輯提供了多種內建交換機型別。如果你有更復雜的路由需求,可以將這些交換機組合起來使用,你甚至可以實現自己的交換機型別,並且當做RabbitMQ的外掛來使用。

叢集
在相同區域網中的多個RabbitMQ伺服器可以聚合在一起,作為一個獨立的邏輯代理來使用。

聯合
對於伺服器來說,它比叢集需要更多的鬆散和非可靠連結。為此RabbitMQ提供了聯合模型。

高可用的佇列
在同一個叢集裡,佇列可以被映象到多個機器中,以確保當其中某些硬體出現故障後,你的訊息仍然安全。

多協議
RabbitMQ 支援多種訊息協議的訊息傳遞。

廣泛的客戶端
只要是你能想到的程式語言幾乎都有與其相適配的RabbitMQ客戶端。

視覺化管理工具
RabbitMQ附帶了一個易於使用的視覺化管理工具,它可以幫助你監控訊息代理的每一個環節。

追蹤
如果你的訊息系統有異常行為,RabbitMQ還提供了追蹤的支援,讓你能夠發現問題所在。

外掛系統
RabbitMQ附帶了各種各樣的外掛來對自己進行擴充套件。你甚至也可以寫自己的外掛來使用。

商業支援
可以提供商業支援,包括培訓和諮詢。

大型社群
圍繞著RabbitMQ有一個大型的社群,那兒有著各種各樣的客戶端、外掛、指南等等。

安裝rabbitMQ

若提示許可權不足請加上sudo
此安裝教程基於centos7
http://www.rabbitmq.com/which-erlang.html檢視安裝rabbitmq需要安裝erlang對應的版本。

https://github.com/rabbitmq/erlang-rpm/releases 頁面找到需要下載的erlang版本。
使用wget進行安裝

wget -P /home/download https://github.com/rabbitmq/erlang-rpm/releases/download/v21.2.3/erlang-21.2.3-1.el7.centos.x86_64.rpm

安裝erlang

rpm -Uvh /home/download/erlang-21.2.3-1.el7.centos.x86_64.rpm

安裝 socat

yum install -y socat

安裝RabbitMQ

wget -P /home/download https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.9/rabbitmq-server-3.7.9-1.el7.noarch.rpm
rpm -Uvh /home/download/rabbitmq-server-3.7.9-1.el7.noarch.rpm

安裝完成 ,關閉防火牆

systemctl stop firewalld.service

啟動和關閉

啟動服務

systemctl start rabbitmq-server

檢視狀態

systemctl status rabbitmq-server

關閉服務

systemctl stop rabbitmq-server

設定開機自啟

systemctl enable rabbitmq-server

開啟Web管理外掛

rabbitmq-plugins enable rabbitmq_management

rabbitmq有一個預設的guest使用者,但只能通過localhost訪問,所以需要新增一個能夠遠端訪問的使用者。
新增使用者

rabbitmqctl add_user admin admin

為使用者分配操作許可權

rabbitmqctl set_user_tags admin administrator

為使用者分配資源許可權

rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"

本地訪問服務ip地址加上埠號15672即可訪問Web管理頁面
在這裡插入圖片描述

rabbitMQ幾種工作模式

匯入依賴

<dependency>
	   <groupId>com.rabbitmq</groupId>
	   <artifactId>amqp-client</artifactId>
	   <version>5.5.1</version>
</dependency>

simple簡單模式
在這裡插入圖片描述
訊息生產者將訊息放入佇列
訊息的消費者監聽訊息佇列,如果佇列中有訊息,就消費掉,訊息被拿走後,自動從佇列中刪除

生產者

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
 * 簡單佇列生產者
 * 使用RabbitMQ的預設交換器傳送訊息
 */
public class Producer {

    public static void main(String[] args) {
        // 建立連線工廠
        ConnectionFactory factory = new ConnectionFactory();
        // 設定連線屬性
        // 此處填寫你的服務IP
        factory.setHost("192.168.3.36");
        factory.setPort(5672);
        // 填寫使用者名稱和密碼
        factory.setUsername("admin");
        factory.setPassword("admin");
        Connection connection = null;
        Channel channel = null;

        try {
            // 從連線工廠獲取連線
            connection = factory.newConnection("生產者");

            // 從連結中建立通道
            channel = connection.createChannel();

            /**
             * 宣告(建立)佇列
             * 如果佇列不存在,才會建立
             * RabbitMQ 不允許宣告兩個佇列名相同,屬性不同的佇列,否則會報錯
             *
             * queueDeclare引數說明:
             * @param queue 佇列名稱
             * @param durable 佇列是否持久化
             * @param exclusive 是否排他,即是否為私有的,如果為true,會對當前佇列加鎖,其它通道不能訪問,並且在連線關閉時會自動刪除,不受持久化和自動刪除的屬性控制
             * @param autoDelete 是否自動刪除,當最後一個消費者斷開連線之後是否自動刪除
             * @param arguments 佇列引數,設定佇列的有效期、訊息最大長度、佇列中所有訊息的生命週期等等
             */
            channel.queueDeclare("queue1", false, false, false, null);

            // 訊息內容
            String message = "Hello World!";
            // 傳送訊息
            channel.basicPublish("", "queue1", null, message.getBytes());
            System.out.println("訊息已傳送!");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {
            // 關閉通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }
            // 關閉連線
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在這裡插入圖片描述

消費者

package com.study.rabbitmq.a132.simple;

import com.rabbitmq.client.*;

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

/**
 * 簡單佇列消費者
 */
public class Consumer {

    public static void main(String[] args) {
        // 建立連線工廠
        ConnectionFactory factory = new ConnectionFactory();
        // 設定連線屬性
        factory.setHost("192.168.3.36");
        factory.setUsername("admin");
        factory.setPassword("admin");

        Connection connection = null;
        Channel channel = null;

        try {
            // 從連線工廠獲取連線
            connection = factory.newConnection("消費者");
            // 從連結中建立通道
            channel = connection.createChannel();

            channel.queueDeclare("queue1", false, false, false, null);
            // 定義收到訊息後的回撥
            DeliverCallback callback = new DeliverCallback() {
                public void handle(String consumerTag, Delivery message) throws IOException {
                    System.out.println("收到訊息:" + new String(message.getBody(), "UTF-8"));
                }
            };
            //監聽佇列
            channel.basicConsume("queue1", true, callback, new CancelCallback() {
                public void handle(String consumerTag) throws IOException {
                }
            });

            System.out.println("開始接收訊息");
            System.in.read();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {
            // 關閉通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }

            // 關閉連線
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在這裡插入圖片描述
work工作模式(資源的競爭)
在這裡插入圖片描述
訊息產生者將訊息放入佇列。
消費者可以有多個,同時監聽同一個佇列。C1 C2共同爭搶當前的訊息佇列內容,誰先拿到誰負責消費訊息。

publish/subscribe釋出訂閱(共享資源)
在這裡插入圖片描述

X代表交換機(rabbitMQ內部元件),訊息產生者將訊息放入交換機,交換機發布訂閱把訊息傳送到所有訊息佇列中,對應訊息佇列的消費者拿到訊息進行消費(廣播)

routing路由模式
在這裡插入圖片描述

訊息生產者將訊息傳送給交換機按照路由判斷,交換機根據路由的key,只能匹配上路由key對應的訊息佇列,對應的消費者才能消費訊息。
訊息生產者

channel.basicPublish("routing-exchange", "black", null, message.getBytes());

將訊息傳送到routing-exchange交換機上,路由key為black
topic 主題模式(路由模式的一種)
在這裡插入圖片描述

  • #代表萬用字元
    *代表多個單詞,#代表一個單詞
    路由功能新增模糊匹配
    訊息產生者產生訊息,把訊息交給交換機
    交換機根據key的規則模糊匹配到對應的佇列,由佇列的監聽消費者接收訊息消費

RPC模式
在這裡插入圖片描述

遠端過程呼叫,訊息生產者傳送一個訊息,等待一個返回結果。

相關文章