RabbitMQ 搭建和工作模式

MQ基本概念

1. MQ概述

MQ全稱 Message Queue([kju?])(消息隊列),是在消息的傳輸過程中保存消息的容器。多用于分布式系統之間進行通信。

(隊列是一種容器,用于存放數據的都是容器,存放消息的就是消息隊列)

分布式系統的調用:

方式一:直接調用

order

product

account

方式二:間接調用

A將數據存放到中間一個系統,通過中間的系統發送到B

中間系統可以成為中間件MQ

生產者-》中間件《--消費者

MQ是用于存放消息的中間件

被調用者叫生產者 調用者是消費者(微服務中說過)

2. MQ的優勢和劣勢

1 優勢

應用解耦:提高系統容錯性和可維護性。

異步提速:提升用戶體驗和系統吞吐量。

削峰填谷:提高系統穩定性。

應用解耦

系統的耦合性越高,容錯性就越低,可維護性就越低。

例:訂單系統 的時候 依賴于庫存系統 支付系統 物流系統 當庫存系統發生異常,就有可能導致訂單系統發生異常 下單失敗

追加系統 x 就只能修改訂單系統更改代碼 導致維護性比較低

使用 MQ 使得應用間解耦,提升容錯性和可維護性

庫存系統宕機訂單系統影響不大,因為消息已經發送到mq了當庫存系統恢復的時候就可以正常使用了。

追加系統的時候跟訂單系統無關

已將數據發送到MQ了,直接從MQ中拿就行了,無需更改訂單中的代碼,可維護性提高

異步提速

一個下單操作耗時:20 + 300 + 300 + 300 = 920ms

用戶點擊完下單按鈕后,需要等待920ms才能得到下單響應,太慢!

用戶點擊完下單按鈕后,只需等待25ms就能得到下單響應 (20 + 5 = 25ms)。

提升用戶體驗和系統吞吐量(單位時間內處理請求的數目)。

以前920ms處理一個請求,現在25ms處理一個請求,系統的吞吐量(單位時間內訪問量)增加

削峰填谷(削峰)

使用了 MQ 之后,限制消費消息的速度為1000,這樣一來,高峰期產生的數據勢必會被積壓在 MQ 中,高峰就被“削”掉了,但是因為消息積壓,在高峰期過后的一段時間內,消費消息的速度還是會維持在1000,直到消費完積壓的消息,這就叫做“填谷”。

使用MQ后,可以提高系統穩定性。

2 劣勢

系統可用性降低

系統引入的外部依賴越多,系統穩定性越差。一旦 MQ 宕機,就會對業務造成影響。如何保證MQ的高可用?

系統復雜度提高

MQ 的加入大大增加了系統的復雜度,以前系統間是同步的遠程調用,現在是通過 MQ 進行異步調用。如何保證消息沒有被重復消費?怎么處理消息丟失情況?那么保證消息傳遞的順序性?

一致性問題

A 系統處理完業務,通過 MQ 給B、C、D三個系統發消息數據,如果 B 系統、C 系統處理成功,D 系統處理失敗。如何保證消息數據處理的一致性?

既然 MQ 有優勢也有劣勢,那么使用 MQ 需要滿足什么條件呢?

消費者--》生產者

  1. 生產者不需要從消費者處獲得反饋。引入消息隊列之前的直接調用,其接口的返回值應該為空,這才讓明明下層的動作還沒做,上層卻當成動作做完了繼續往后走,即所謂異步成為了可能。

訂單->庫存

  1. 容許短暫的不一致性。
  2. 確實是用了有效果。即解耦、提速、削峰這些方面的收益,超過加入MQ,管理MQ這些成本。

3. 常見的MQ產品

目前業界有很多的 MQ 產品,例如 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等,也有直接使用 Redis 充當消息隊列的案例,而這些消息隊列產品,各有側重,在實際選型時,需要結合自身需求及 MQ 產品特征,綜合考慮。

RabbitMQ基本介紹

AMQP,即 Advanced Message Queuing Protocol(英[?pr??t?k?l])(高級消息隊列協議),是一個網絡協議,是應用層協議的一個開放標準,為面向消息的中間件設計。基于此協議的客戶端與消息中間件可傳遞消息,并不受客戶端/中間件不同產品,不同的開發語言等條件的限制。2006年,AMQP 規范發布。類比HTTP。

消息隊列中間件

exchange 交換機 分發消息 分發到不同的容器 queue 通過路由來處理

queue 容器

routes 路由

生產者 發布消息到exchange exchange 通過不同的路由規則發布/路由 給不同的queue 進行存儲 cunsumer通過隊列去監聽拿到消息進行消費

2007年,Rabbit 技術公司基于 AMQP 標準開發的 RabbitMQ 1.0 發布。RabbitMQ 采用 Erlang 語言開發。Erlang 語言由 Ericson 設計,專門為開發高并發和分布式系統的一種語言,在電信領域使用廣泛。

1. RabbitMQ 基礎架構

Broker 中間者 服務

procedure 和consumer都是客戶端

客戶端通過鏈接和服務端進行通信 所以需要建立起來連接 然后進行通信a

使用channel(管道)節省資源

一個rabbitmq里面有很多的虛擬機 相當于mysql里面有很多數據庫,數據庫里面有很多表,都是獨立的。

每個虛擬機里面有很多的exchange和queue 獨立分區的作用

2. RabbitMQ 中的相關概念

Broker:接收和分發消息的應用,RabbitMQ Server就是 Message Broker。

Virtual host:出于多租戶和安全因素設計的,把 AMQP 的基本組件劃分到一個虛擬的分組中,類似于網絡中的 namespace 概念。當多個不同的用戶使用同一個 RabbitMQ server 提供的服務時,可以劃分出多個vhost,每個用戶在自己的 vhost 創建 exchange/queue 等。

Connection:publisher/consumer 和 broker 之間的 TCP 連接。

Channel:如果每一次訪問 RabbitMQ 都建立一個 Connection,在消息量大的時候建立 TCP Connection的開銷將是巨大的,效率也較低。Channel 是在 connection 內部建立的邏輯連接,如果應用程序支持多線程,通常每個thread創建單獨的 channel 進行通訊,AMQP method 包含了channel id 幫助客戶端和message broker 識別 channel,所以 channel 之間是完全隔離的。Channel 作為輕量級的 Connection 極大減少了操作系統建立 TCP connection 的開銷。

Exchange:message 到達 broker 的第一站,根據分發規則,匹配查詢表中的 routing key,分發消息到queue 中去。常用的類型有:

direct (point-to-point)

topic (publish-subscribe)

fanout (multicast)

Queue:消息最終被送到這里等待 consumer 取走

Binding:exchange 和 queue 之間的虛擬連接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查詢表中,用于 message 的分發依據

3. RabbitMQ的6 種工作模式

RabbitMQ 提供了 6 種工作模式:

簡單模式、work queues、Publish/Subscribe 發布與訂閱模式、Routing 路由模式、Topics 主題模式、RPC 遠程調用模式(遠程調用,不太算 MQ;暫不作介紹)。==

官網對應模式介紹:RabbitMQ Tutorials — RabbitMQ

4. AMQP 和 JMS

MQ是消息通信的模型;實現MQ的大致有兩種主流方式:AMQP、JMS。

AMQP

AMQP是一種協議,更準確的說是一種binary wire-level protocol(鏈接協議)。這是其和JMS的本質差別,AMQP不從API層進行限定,而是直接定義網絡交換的數據格式。

JMS

JMS即Java消息服務(Java Message Service)應用程序接口,是一個Java平臺中關于面向消息中間件(MOM)的API,用于在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。

(規定了消息客戶端的一套api的東西,rabbitmq沒有遵循規則)

JMS 是 JavaEE 規范中的一種,類比JDBC。

AMQP與 JMS 區別

JMS是定義了統一的接口,來對消息操作進行統一;AMQP是通過規定協議來統一數據交互的格式。

JMS限定了必須使用Java語言;AMQP只是協議,不規定實現方式,因此是跨語言的。

JMS規定了兩種消息模式;而AMQP的消息模式更加豐富

再談市場上常見的消息隊列

ActiveMQ:基于JMS

ZeroMQ:基于C語言開發

RabbitMQ:基于AMQP協議,erlang語言開發,穩定性好

RocketMQ:基于JMS,阿里巴巴產品

Kafka:類似MQ的產品;分布式消息系統,高吞吐量。

RabbitMQ的安裝和配置

安裝依賴環境

在線安裝依賴環境:

yum -y install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz

安裝Erlang

rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm

安裝RabbitMQ

rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm

安裝rabbitmq

rpm -ivh rabbitmq-server-3.7.18-1.el7.noarch.rpm

啟動RabbitMQ

systemctl start rabbitmq-server # 啟動服務

systemctl stop rabbitmq-server # 停止服務

systemctl restart rabbitmq-server # 重啟服務

systemctl status rabbitmq-server #查看狀態

配置RabbitMQ

開啟管理界面

rabbitmq-plugins enable rabbitmq_management

修改默認配置信息

vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.18/ebin/rabbit.app?

修改后重啟

打開客戶端

192.168.221.37:15672

使用guest/guest登錄之后出現如下即為安裝成功

操作RabbitMQ

1)添加虛擬主機

2)添加用戶

3)給用戶分配虛擬主機

先清除

再分配

查看結果

分配成功

重新使用新用戶登錄

4)在MQ中添加發布消息

發送成功后

消費信息

搭建工程

添加jar包

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

添加消費者

public class MyTest {@Testpublic void aaa() throws IOException, TimeoutException {ConnectionFactory connectionFactory = new ConnectionFactory();//連接mqconnectionFactory.setUsername("賬號");connectionFactory.setPassword("密碼");connectionFactory.setHost("IP地址");connectionFactory.setPort(端口號);connectionFactory.setVirtualHost("/***");//建立連接Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String s = new String(body);System.out.println("mq:"+s);}};channel.basicConsume("test",true,consumer);}
}

結果

添加生產者

public class MyTest {@Testpublic void bbb() throws IOException, TimeoutException {ConnectionFactory connectionFactory = new ConnectionFactory();//連接mqconnectionFactory.setUsername("賬號"); connectionFactory.setPassword("密碼");connectionFactory.setHost("IP地址");connectionFactory.setPort(端口號); connectionFactory.setVirtualHost("/***");//建立連接Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();/*** String queue, 隊列的名稱* boolean durable, 持久化* boolean exclusive, 是否獨占* boolean autoDelete,  受否自動刪除* Map<String, Object> arguments  參數*/channel.queueDeclare("test",false,false,false,null);// 創建隊列channel.basicPublish("","test",null,"hello mq1".getBytes());}}

發消息

RabbitMQ工作模式

官網對應模式介紹:RabbitMQ Tutorials — RabbitMQ

Work queues工作隊列模式

?模式說明

Work Queues與入門程序的簡單模式相比,多了一個或一些消費端,多個消費端共同消費同一個隊列中的消息。

應用場景:對于 任務過重或任務較多情況使用工作隊列可以提高任務處理的速度。

創建兩個消費者

使用生產者發布消息

結果

訂閱模式

添加交換機

創建隊列

交換機綁定隊列

在交換機中發布消息

關聯隊列都會發布

修改消費者監聽不同隊列 測試

創建兩個消費者

創建交換機生產者
public class MyTestEx {@Testpublic void bbb() throws IOException, TimeoutException {ConnectionFactory connectionFactory = new ConnectionFactory();//連接mqconnectionFactory.setUsername("賬號");connectionFactory.setPassword("密碼");connectionFactory.setHost("IP地址");connectionFactory.setPort(端口號);connectionFactory.setVirtualHost("/***");//建立連接Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();//創建交換機channel.exchangeDeclare("myex1", BuiltinExchangeType.FANOUT,false);//創建隊列/*** String queue, 隊列的名稱* boolean durable, 持久化* boolean exclusive, 是否獨占* boolean autoDelete,  受否自動刪除* Map<String, Object> arguments  參數*/channel.queueBind("testmyex1",false,false,false,null);channel.queueBind("testmyex2",false,false,false,null);//綁定交換機channel.exchangeBind("testmyex1","myex1","");channel.exchangeBind("testmyex2","myex1","");channel.basicPublish("myex1","",null,"testex".getBytes());}
}

測試

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164260.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164260.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164260.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker部署微服務

目錄 docker操作命令 鏡像操作命令 拉取鏡像 導出鏡像 刪除鏡像 加載鏡像 推送鏡像 部署 pom文件加上 在每個模塊根目錄加上DockerFile文件 項目根目錄加上docker-compose.yml文件 打包&#xff0c;clean&#xff0c;package 服務器上新建文件夾 測試docker-compo…

基于springboot和微信小程序的流浪動物管理系統

基于springboot和微信小程序的流浪動物管理系統 內容簡介 基于微信小程序實現的流浪動物管理系統&#xff0c;該系統針對用戶與管理員兩種角色進行開發。 1、提供流浪動物的信息查詢功能&#xff0c;包括品種、年齡、性別、健康狀況等&#xff0c;提供救助活動報名功能。 2…

5.1 PBR基礎 BRDF介紹

基于物理的渲染&#xff08;Physically Based Rendering&#xff0c;PBR&#xff09;是指使用基于物理原理和微平面理論建模的著色/光照模型&#xff0c;以及使用從現實中測量的表面參數來準確表示真實世界材質的渲染理念。 一、反射率方程 理論基礎放在參考鏈接里。 直接開始…

【uniapp】uniapp開發小程序定制uni-collapse(折疊面板)

需求 最近在做小程序&#xff0c;有一個類似折疊面板的ui控件&#xff0c;效果大概是這樣 代碼 因為項目使用的是uniapp&#xff0c;所以打算去找uniapp的擴展組件&#xff0c;果然給我找到了這個叫uni-collapse的組件&#xff08;鏈接&#xff1a;uni-collapse&#xff09…

超詳細的接口測試

本文主要分為兩個部分&#xff1a; 第一部分&#xff1a;主要從問題出發&#xff0c;引入接口測試的相關內容并與前端測試進行簡單對比&#xff0c;總結兩者之前的區別與聯系。但該部分只交代了怎么做和如何做&#xff1f;并沒有解釋為什么要做&#xff1f; 第二部分&#xf…

ShellCode漏洞

ShellCode漏洞 可以查看如下網址&#xff1a; https://www.cnblogs.com/kakadewo/p/12996878.html 定義&#xff1a; shellcode是一段用于利用軟件漏洞而執行的代碼&#xff0c;shellcode為16進制之機械碼&#xff0c;以其經常讓攻擊者獲得shell而得名。shellcode常常使用機…

老鳥總結,軟件測試工程師職業發展規劃路線,入門到沖擊大廠...

目錄&#xff1a;導讀 前言一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 1、測試工程師發展…

YOCTO 下載repo工具失敗解決辦法

curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repocp repo ~/binchmod ax ~/bin/repo如果使用時報錯&#xff0c; 切換ubuntu 到 python3 版本。gedit repo 修改repo默認鏈接地址&#xff1a;REPO_URL "https://gerrit.googlesource.com/git-repo"…

Spring AOP-面向切面編程概念

Spring AOP-面向切面編程概念 AOP&#xff08;面向切面編程&#xff09;是編程范式的一種&#xff0c;它允許程序員將橫切關注點&#xff08;cross-cutting concerns&#xff09;模塊化。在面向切面編程中&#xff0c;這些橫切關注點通常體現為在多個點重復出現的代碼&#xf…

Android設計模式--適配器模式

至誠之道&#xff0c;可以前知 一&#xff0c;定義 適配器模式把一個類的接口變換成客戶端所期待的另一種接口&#xff0c;從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。 適配器模式在我們的開發中使用率極高&#xff0c;ListView&#xff0c;GridView&am…

面試cast:reinterpret_cast/const_cast/static_cast/dynamic_cast

目錄 1. cast 2. reinterpret_cast 3. const_cast 3.1 加上const的情況 3.2 去掉const的情況 4. static_cast 4.1 基本類型之間的轉換 4.2 void指針轉換為任意基本類型的指針 4.3 子類和父類之間的轉換 5. dynamic_cast 5.1 RTTI(Run-time Type Identification) 1.…

Selenium實現多頁面切換

當使用 Selenium 進行自動化測試或爬取數據時&#xff0c;有時需要處理多個頁面之間的切換。以下是一些可能需要多頁面切換的情況&#xff1a; 1、打開新窗口/頁面&#xff1a; 在當前頁面上點擊鏈接、按鈕或執行某些操作時&#xff0c;可能會打開一個新的窗口或頁面。此時&a…

【element優化經驗】怎么讓element-ui中表單多語言切換排版不亂

目錄 前言&#xff1a; 痛點&#xff1a; 1.左對齊&#xff0c;右對齊在中文和外語情況下字數不同&#xff0c;固定寬度會使名稱換行&#xff0c;不在整行對齊&#xff0c;影響美觀。 2.如果名稱和輸入框不在一行&#xff0c;會使頁面越來越長 3.label-width值給變量&#…

隨筆記錄-springmvc_ResourceHandlerRegistry+ResourceHttpRequestHandler

環境&#xff1a;springboot-2.7.5 配置文件配置靜態資源映射 springboot配置靜態資源映射方式是通過 WebMvcAutoConfiguration 實現的 spring: # resources: # # 自springboot 2.5.5之后&#xff0c;該屬性已經被廢棄&#xff0c;使用spring.web.resources.static-locat…

爬蟲逆向你應該懂得Javascript知識

背景 大家在學習爬蟲逆向的時候&#xff0c;一般都會涉及到對js源文件進行代碼扣去&#xff0c;但是有的時候&#xff0c;你最好有js基礎&#xff0c;能發現加密或者解密在那個位置&#xff0c;或者是能用python改寫js代碼&#xff0c;這就對個人的Javascript的能力有一定要求…

Switch的使用及其注意事項

注意第五點要看清&#xff0c;case執行完后匹配沒有成功&#xff0c;如過有Default&#xff0c;將會執行Default&#xff0c;如果有case在Default之后&#xff0c;而且Default沒有break語句&#xff0c;那么將會繼續執行case的語句&#xff0c;此時case中的常量表達式只起語句標…

【Skynet 入門實戰練習】游戲模塊劃分 | 基礎功能模塊 | timer 定時器模塊 | logger 日志服務模塊

文章目錄 游戲模塊基礎功能模塊定時器模塊日志模塊通用模塊 游戲模塊 游戲從邏輯方面可以分為下面幾個模塊&#xff1a; 注冊和登錄網絡協議數據庫玩法邏輯其他通用模塊 除了邏輯劃分&#xff0c;還有幾個重要的工具類模塊&#xff1a; Excel 配置導表工具GM 指令測試機器人…

系列一、Spring整合MyBatis不忽略mapper接口同目錄的xxxMapper.xml

一、概述 默認情況下maven要求我們將xml配置、properties配置等都放在resources目錄下&#xff0c;如果我們強行將其放在java目錄&#xff0c;即將xxxMapper.xml和xxxMapper接口放在同一個目錄下&#xff0c;那么默認情況下maven打包時會將這個xxxMapper.xml文件忽略掉&#xf…

【辦公常識_1】寫好的代碼如何上傳?使用svn commit

首先找到對應的目錄 找到文件之后點擊SVN Commit