RabbitMQ是一個由erlang開發的AMQP(Advanced Message Queue )的開源實現。java
AMQP,即Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標準高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件同產品、不一樣的開發語言等條件的限制。node
AMQP的實現有:RabbitMQ、OpenAMQ、Apache Qpid、Redhat Enterprise MRG、AMQP Infrastructure、ØMQ、Zyre等。 web
一、跨系統的異步通訊 ,異步,解耦,削峯都有體現。正則表達式
二、應用內的同步變成異步 秒殺:本身發送給本身數據庫
三、基於Pub/Sub模型實現的事件驅動 放款失敗通知、提貨通知、購買碎屏保 系統間同步數據 摒棄ELT(好比全量同步商戶數據); 摒棄API(好比定時增量獲取用戶、獲取產品,變成增量廣播)。vim
四、利用RabbitMQ實現事務的最終一致性centos
RabbitMQ使用Erlang語言編寫,使用Mnesia數據庫存儲消息。bash
當消息生產者/(消費者)要生產/(消費)消息的時候須要與服務器創建一個長鏈接,在RabbitMQ中叫作Connection,爲了解決客戶端與服務器所產生的頻繁的鏈接問題,因爲會大量的消耗服務器內存,這裏引入了消息通道的概念,在保持長鏈接的狀況下。能夠經過創建Channel的方式與服務器通信,當有請求的時候就會創建通道,結束則關閉通道。在RabbitMQ中,通常的作法不會讓消息直接發送到消息隊列中,這裏引入了Exchange(交換機)的概念,經過交換機來實現消息更加靈活的消息分發,交換機沒有實際的進程,而隊列是有的,它只是一個地址列表,在隊列建立的時候會與Exchange綁定一個專屬的 key ,在生產者生產消息的時候也會指定這個key,那麼 Exchange 就會經過這個key去匹配 Queue,從而實現靈活分發。而後消費者會經過訂閱指定的隊列去消費消息。在RabbitMQ中有Virtual Host 虛擬機的概念,他能夠當成是一個小型的MQ,一個RabbitMQ服務器上能夠有多個虛擬機,相互之間是隔離的,固然不一樣的虛擬機之間能夠有相同命名的交換機與隊列,能夠實現資源的隔離。服務器
最新版本的RabbitMQ有四種交換機類型,分別是Direct exchange、Fanout exchange、Topic exchange、Headers exchange。cookie
Direct Exchange 直連交換機:
定義:直連類型的交換機與一個隊列綁定時,須要指定一個明確的binding key。路由規則:發送消息到直連類型的交換機時,只有routing key跟binding key徹底匹配時,綁定的隊列才能收到消息。
示例:
// 只有隊列1能收到消息 channel.basicPublish("MY_DIRECT_EXCHANGE", "key1", null, msg.getBytes());
Topic Exchange 主題交換機:
定義:主題類型的交換機與一個隊列綁定時,能夠指定按模式匹配的routing key。通配符有兩個,*表明匹配一個單詞。#表明匹配零個或者多個單詞。單詞與單詞之間用 . 隔開。路由規則:發送消息到主題類型的交換機時,routing key符合binding key的模式時,綁定的隊列才能收到消息。
示例:
// 只有隊列1能收到消息 channel.basicPublish("MY_TOPIC_EXCHANGE", "sh.abc", null, msg.getBytes()); // 隊列2和隊列3能收到消息 channel.basicPublish("MY_TOPIC_EXCHANGE", "bj.book", null, msg.getBytes()); // 只有隊列4能收到消息 channel.basicPublish("MY_TOPIC_EXCHANGE", "abc.def.food", null, msg.getBytes());
Fanout Exchange 廣播交換機:
定義:廣播類型的交換機與一個隊列綁定時,不須要指定binding key。路由規則:當消息發送到廣播類型的交換機時,不須要指定routing key,全部與之綁定的隊列都能收到消息。
Headers Exchanges:
不處理路由鍵。而是根據發送的消息內容中的headers屬性進行匹配。在綁定Queue與Exchange時指定一組鍵值對;當消息發送到RabbitMQ時會取到該消息的headers與Exchange綁定時指定的鍵值對進行匹配;若是徹底匹配則消息會路由到該隊列,不然不會路由到該隊列。headers屬性是一個鍵值對,能夠是Hashtable,鍵值對的值能夠是任何類型。而fanout,direct,topic 的路由鍵都須要要字符串形式的。匹配規則x-match有下列兩種類型:
x-match = all :表示全部的鍵值對都匹配才能接受到消息。
x-match = any :表示只要有鍵值對匹配就能接受到消息。
系統版本:CentOS Linux release 7.5.1804 (Core)
RabbitMQ版本:3.6.12
Erlang版本:erlang-19.0.4-1.el7.centos.x86_64
JDK版本:1.8
Erlang安裝:
Erlang包安裝:https://www.erlang.org/downloads/19.0 下載對應安裝包 otp_src_19.0.tar.gz
添加依賴:yum install ncurses-devel
解壓:tar -xf otp_src_20.1.tar.gz ,重命名下 mv otp_src_19.0 otp
進入目錄安裝:./configure --prefix=/usr/local/erlang --without-javac & make(時間有點小長) & make install
cd /usr/local/erlang/bin 執行 ./erl 出現如下即安裝完成:
添加環境變量:export PATH=$PATH:/usr/local/erlang/bin
RabbitMQ安裝:
下載安裝包:http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.12/ 選擇 rabbitmq-server-generic-unix-3.6.12.tar.xz 下載
上傳至服務器,我這邊放在 /mysoft 下。Mq安裝包默認是xz結尾的,解壓xz文件後獲得tar文件
xz -d rabbitmq-server-generic-unix-3.6.12.tar.xz
執行解壓命令 tar -xvf rabbitmq-server-generic-unix-3.6.12.tar
添加環境變量:export PATH=$PATH:/mysoft/rabbitmq_server-3.6.12/sbin
環境變量生效:source /etc/profile
配置網頁插件:
首先建立目錄,不然可能報錯:mkdir /etc/rabbitmq
啓動mq:./rabbitmq-server -detached
進入 sbin 目錄,啓用插件:./rabbitmq-plugins enable rabbitmq_management
啓用rabbitmq_management插件去管理rabbitmq服務,可是在訪問管理界面使用guest用戶登陸時出現login failed錯誤。到服務器上查詢日誌顯示出現錯誤的緣由是:
HTTP access denied: user 'guest' - User can only log in via localhost。
rabbitmq從3.3.0開始禁止使用guest/guest權限經過除localhost外的訪問。若是想使用guest/guest經過遠程機器訪問,須要在rabbitmq配置文件中(/mysoft/rabbitmq_server-3.6.12/etc/rabbitmq/rabbitmq.config)中設置loopback_users爲[]。rabbitmq.config文件須要本身建立,完整內容以下(注意後面的半角句號):
[{rabbit, [{loopback_users, []}]}].
重啓,再經過訪問 http://192.168.254.137:15672 ,經過guest/guest 登錄:
查看服務狀態:rabbitmqctl status
關閉服務:rabbitmqctl stop
查看mq用戶:rabbitmqctl list_users
查看用戶權限:rabbitmqctl list_user_permissions guest
新增用戶: rabbitmqctl add_user admin 123456
設置角色:rabbitmqctl set_user_tags admin administrator
賦予管理員權限:rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
rabbitmqctl set_permissions -p [Vhost_Name][username][conf][write][read]
conf:一個正則表達式match哪些配置資源可以被該用戶訪問
write:一個正則表達式match哪些配置資源可以被該用戶讀。
read:一個正則表達式match哪些配置資源可以被該用戶訪問
根據我的需求更改rabbitmq的環境變量:
建立環境變量配置文件 vim
/mysoft/rabbitmq_server-3.6.12/etc/rabbitmq/rabbitmq-env.conf
RABBITMQ_MNESIA_BASE=/data/rabbitmq/mnesia //數據庫位置 RABBITMQ_LOG_BASE=/data/rabbitmq/log //日誌文件目錄
mkdir /data/rabbitmq/mnesia mkdir /data/rabbitmq/log chowm -R rabbitmq:rabbitmq /data/rabbitmq
默認狀態下 日誌存放位置 /mysoft/rabbitmq_server-3.6.12/var/log/rabbitmq 下面,經過查看日誌,在啓動的時候會輸出如下信息:
=INFO REPORT==== 24-Jan-2019::22:25:38 === Starting RabbitMQ 3.6.12 on Erlang 19.0.4 Copyright (C) 2007-2017 Pivotal Software, Inc. Licensed under the MPL. See http://www.rabbitmq.com/ =INFO REPORT==== 24-Jan-2019::22:25:38 === node : rabbit@localhost home dir : /root //配置文件位置 config file(s) : /mysoft/rabbitmq_server-3.6.12/etc/rabbitmq/rabbitmq.config cookie hash : aRQYNdsONCZK2FIkVnK0bA== //日誌文件 log : /mysoft/rabbitmq_server-3.6.12/var/log/rabbitmq/rabbit@localhost.log sasl log : /mysoft/rabbitmq_server-3.6.12/var/log/rabbitmq/rabbit@localhost-sasl.log //數據庫位置 database dir : /mysoft/rabbitmq_server-3.6.12/var/lib/rabbitmq/mnesia/rabbit@localhost //內存信息 =INFO REPORT==== 24-Jan-2019::22:25:40 === Memory high watermark set to 389 MiB (408762777 bytes) of 974 MiB (1021906944 bytes) total =INFO REPORT==== 24-Jan-2019::22:25:40 === Enabling free disk space monitoring =INFO REPORT==== 24-Jan-2019::22:25:40 === Disk free limit set to 50MB =INFO REPORT==== 24-Jan-2019::22:25:40 === Limiting to approx 924 file handles (829 sockets) =INFO REPORT==== 24-Jan-2019::22:25:40 === FHC read buffering: OFF FHC write buffering: ON =INFO REPORT==== 24-Jan-2019::22:25:40 === Waiting for Mnesia tables for 30000 ms, 9 retries left =INFO REPORT==== 24-Jan-2019::22:25:40 === Waiting for Mnesia tables for 30000 ms, 9 retries left =INFO REPORT==== 24-Jan-2019::22:25:40 === Priority queues enabled, real BQ is rabbit_variable_queue =INFO REPORT==== 24-Jan-2019::22:25:40 === Starting rabbit_node_monitor =INFO REPORT==== 24-Jan-2019::22:25:40 === Management plugin: using rates mode 'basic' =INFO REPORT==== 24-Jan-2019::22:25:40 === msg_store_transient: using rabbit_msg_store_ets_index to provide index =INFO REPORT==== 24-Jan-2019::22:25:40 === msg_store_persistent: using rabbit_msg_store_ets_index to provide index //AMQP端口 =INFO REPORT==== 24-Jan-2019::22:25:40 === started TCP Listener on 0.0.0.0:5672 //管理端口 =INFO REPORT==== 24-Jan-2019::22:25:40 === Management plugin started. Port: 15672 //數據庫加載完成 =INFO REPORT==== 24-Jan-2019::22:25:40 === Statistics database started. //插件加載 =INFO REPORT==== 24-Jan-2019::22:25:40 === Server startup complete; 6 plugins started. * rabbitmq_management * rabbitmq_management_agent * rabbitmq_web_dispatch * amqp_client * cowboy * cowlib
這段日誌包含了RabbitMQ的版本號、Erlang的版本號、RabbitMQ服務節點名稱、cookie的hash值、RabbitMQ配置文件地址、內存限制、磁盤限制、默認帳戶guest的建立以及權限配置等等。