消息(Message)是指在應用間傳送的數據。消息能夠很是簡單,好比只包含文本字符串,也能夠更復雜,可能包含嵌入對象。
消息隊列(Message Queue)是一種應用間的通訊方式,消息發送後能夠當即返回,由消息系統來確保消息的可靠傳遞。消息發佈者只管把消息發佈到 MQ 中而不用管誰來取,消息使用者只管從 MQ 中取消息而不論是誰發佈的。這樣發佈者和使用者都不用知道對方的存在。html
消息隊列是一種應用間的異步協做機制,那何時須要使用 MQ 呢?
像用戶下單以後、生成訂單、結算,定時給系統註冊用戶推送活動消息,一些常見的流程類的業務都會用到消息隊列服務。
node
RabbitMQ是一個消息的代理器,用於接收和發送消息,你能夠這樣想,他就是一個郵局,當您把須要寄送的郵件投遞到郵筒之時,你能夠肯定的是郵遞員先生確定會把郵件發送到須要接收郵件的人的手裏,不會送錯的。在這個比喻中,RabbitMQ就是一個郵箱,也能夠理解爲郵局和郵遞員,他們負責把消息發送出去和用於接收信息。
RabbitMQ和郵局這二者之間的主要區別是它不會處理紙質郵件,取而代之的是接收、存儲和發送二進制數據塊,也就是咱們一般所說的消息。linux
下圖是RabbitMQ服務的內部結構
git
RabbitMQ 是一個由 Erlang 語言開發的 AMQP 的開源實現。AMQP :Advanced Message Queue,高級消息隊列協議。它是應用層協議的一個開放標準,爲面向消息的中間件設計,基於此協議的客戶端與消息中間件可傳遞消息,並不受產品、開發語言等條件的限制。github
RabbitMQ 最初起源於金融系統,用於在分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。具體特色包括:shell
1)可靠性(Reliability)
RabbitMQ 使用一些機制來保證可靠性,如持久化、傳輸確認、發佈確認。json
2)靈活的路由(Flexible Routing)
在消息進入隊列以前,經過 Exchange 來路由消息的。對於典型的路由功能,RabbitMQ 已經提供了一些內置的 Exchange 來實現。針對更復雜的路由功能,能夠將多個 Exchange 綁定在一塊兒,也經過插件機制實現本身的 Exchange 。centos
3)消息集羣(Clustering)
多個 RabbitMQ 服務器能夠組成一個集羣,造成一個邏輯 Broker 。安全
4)高可用(Highly Available Queues)
隊列能夠在集羣中的機器上進行鏡像,使得在部分節點出問題的狀況下隊列仍然可用。ruby
5)多種協議(Multi-protocol)
RabbitMQ 支持多種消息隊列協議,好比 STOMP、MQTT 等等。
6)多語言客戶端(Many Clients)
RabbitMQ 幾乎支持全部經常使用語言,好比 Java、.NET、Ruby 等等。
7)管理界面(Management UI)
RabbitMQ 提供了一個易用的用戶界面,使得用戶能夠監控和管理消息 Broker 的許多方面。
8)跟蹤機制(Tracing)
若是消息異常,RabbitMQ 提供了消息跟蹤機制,使用者能夠找出發生了什麼。
1)首先須要安裝Erlang環境
https://bintray.com/rabbitmq/rpm/erlang [root@master ~]# rpm -ivh erlang-20.3.8-1.el7.centos.x86_64.rpm 警告:erlang-20.3.8-1.el7.centos.x86_64.rpm: 頭V4 RSA/SHA1 Signature, 密鑰 ID 6026dfca: NOKEY 準備中... ################################# [100%] 正在升級/安裝... 1:erlang-20.3.8-1.el7.centos ################################# [100%] [root@master ~]# erl Erlang/OTP 20 [erts-9.3.3] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:10] [hipe] [kernel-poll:false] Eshell V9.3.3 (abort with ^G) 1>
2)下載安裝Rabbitmq
https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.6/rabbitmq-server-3.7.6-1.el7.noarch.rpm [root@master ~]# ll rabbitmq-server-3.7.6-1.el7.noarch.rpm -rw-r--r-- 1 root root 9511623 6月 27 14:00 rabbitmq-server-3.7.6-1.el7.noarch.rpm [root@master ~]# rpm --import https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc [root@master ~]# yum install rabbitmq-server-3.7.6-1.el7.noarch.rpm [root@master ~]# chkconfig rabbitmq-server on 注意:正在將請求轉發到「systemctl enable rabbitmq-server.service」。 Created symlink from /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service to /usr/lib/systemd/system/rabbitmq-server.service. [root@master ~]# /sbin/service rabbitmq-server start Redirecting to /bin/systemctl start rabbitmq-server.service [root@master ~]# ps -ef|grep rabbitmq rabbitmq 5609 1 23 14:22 ? 00:00:02 /usr/lib64/erlang/erts-9.3.3/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db -zdbbl 1280000 -K true -- -root /usr/lib64/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.6/ebin -noshell -noinput -s rabbit boot -sname rabbit@master -boot start_sasl -kernel inet_default_connect_options [{nodelay,true}] -sasl errlog_type error -sasl sasl_error_logger false -rabbit lager_log_root "/var/log/rabbitmq" -rabbit lager_default_file "/var/log/rabbitmq/rabbit@master.log" -rabbit lager_upgrade_file "/var/log/rabbitmq/rabbit@master_upgrade.log" -rabbit enabled_plugins_file "/etc/rabbitmq/enabled_plugins" -rabbit plugins_dir "/usr/lib/rabbitmq/plugins:/usr/lib/rabbitmq/lib/rabbitmq_server-3.7.6/plugins" -rabbit plugins_expand_dir "/var/lib/rabbitmq/mnesia/rabbit@master-plugins-expand" -os_mon start_cpu_sup false -os_mon start_disksup false -os_mon start_memsup false -mnesia dir "/var/lib/rabbitmq/mnesia/rabbit@master" -kernel inet_dist_listen_min 25672 -kernel inet_dist_listen_max 25672 rabbitmq 5752 1 0 14:22 ? 00:00:00 /usr/lib64/erlang/erts-9.3.3/bin/epmd -daemon rabbitmq 5921 5609 0 14:22 ? 00:00:00 erl_child_setup 1024 rabbitmq 5937 5921 0 14:22 ? 00:00:00 inet_gethost 4 rabbitmq 5938 5937 0 14:22 ? 00:00:00 inet_gethost 4 root 5951 5300 0 14:23 pts/0 00:00:00 grep --color=auto rabbitmq [root@master ~]# netstat -lntup |grep 5672 -bash: netstat: 未找到命令 [root@master ~]# netstat -lntup |grep 5672 tcp 0 0 0.0.0.0:25672 0.0.0.0:* LISTEN 5609/beam.smp tcp6 0 0 :::5672 :::* LISTEN 5609/beam.smp
3)查看狀態信息
[root@master ~]# rabbitmqctl status Status of node rabbit@master ... [{pid,5609}, {running_applications, [{rabbit,"RabbitMQ","3.7.6"}, {mnesia,"MNESIA CXC 138 12","4.15.3"}, {rabbit_common, "Modules shared by rabbitmq-server and rabbitmq-erlang-client", "3.7.6"}, {ranch_proxy_protocol,"Ranch Proxy Protocol Transport","1.5.0"}, {ranch,"Socket acceptor pool for TCP protocols.","1.5.0"}, {ssl,"Erlang/OTP SSL application","8.2.6"}, {public_key,"Public key infrastructure","1.5.2"}, {asn1,"The Erlang ASN1 compiler version 5.0.5","5.0.5"}, {inets,"INETS CXC 138 49","6.5.2"}, {jsx,"a streaming, evented json parsing toolkit","2.8.2"}, {os_mon,"CPO CXC 138 46","2.4.4"}, {xmerl,"XML parser","1.3.16"}, {crypto,"CRYPTO","4.2.2"}, {recon,"Diagnostic tools for production use","2.3.2"}, {lager,"Erlang logging framework","3.5.1"}, {goldrush,"Erlang event stream processor","0.1.9"}, {compiler,"ERTS CXC 138 10","7.1.5"}, {syntax_tools,"Syntax tools","2.1.4"}, {syslog,"An RFC 3164 and RFC 5424 compliant logging framework.","3.4.2"}, {sasl,"SASL CXC 138 11","3.1.2"}, {stdlib,"ERTS CXC 138 10","3.4.5"}, {kernel,"ERTS CXC 138 10","5.4.3"}]}, {os,{unix,linux}}, {erlang_version, "Erlang/OTP 20 [erts-9.3.3] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:64] [hipe] [kernel-poll:true]\n"}, {memory, [{connection_readers,0}, {connection_writers,0}, {connection_channels,0}, {connection_other,0}, {queue_procs,0}, {queue_slave_procs,0}, {plugins,5936}, {other_proc,20754544}, {metrics,184432}, {mgmt_db,0}, {mnesia,72912}, {other_ets,1873688}, {binary,55376}, {msg_index,28720}, {code,25082003}, {atom,1041593}, {other_system,9173572}, {allocated_unused,8315896}, {reserved_unallocated,3670016}, {strategy,rss}, {total,[{erlang,58272776},{rss,70258688},{allocated,66588672}]}]}, {alarms,[]}, {listeners,[{clustering,25672,"::"},{amqp,5672,"::"}]}, {vm_memory_calculation_strategy,rss}, {vm_memory_high_watermark,0.4}, {vm_memory_limit,3281294131}, {disk_free_limit,50000000}, {disk_free,122394349568}, {file_descriptors, [{total_limit,924},{total_used,2},{sockets_limit,829},{sockets_used,0}]}, {processes,[{limit,1048576},{used,204}]}, {run_queue,0}, {uptime,111}, {kernel,{net_ticktime,60}}]6、Rabbitmq CLI介紹
自帶多個命令行工具
1)rabbitmqctl
管理與操做命令
* 中止節點
* 訪問節點狀態,有效配置,運行情況檢查
* 虛擬主機管理
* 用戶和權限管理
* 政策管理
* 列出隊列,鏈接,渠道,交流,消費者
* 集羣成員管理
更多操做內容請參考:http://www.rabbitmq.com/rabbitmqctl.8.html
[root@master ~]# rabbitmqctl list_bindings #查看綁定信息 Listing bindings for vhost /... [root@master ~]# rabbitmqctl list_exchanges #查看交換器 Listing exchanges for vhost / ... amq.rabbitmq.trace topic amq.match headers direct amq.headers headers amq.direct direct amq.rabbitmq.event topic amq.topic topic amq.fanout fanout [root@master ~]# rabbitmqctl list_queues #查看隊列 Timeout: 60.0 seconds ... Listing queues for vhost / ...
2)rabbitmq-plugins
是一個管理插件的工具:列表,啓用和禁用它們
[root@master ~]# rabbitmq-plugins --help Usage: rabbitmq-plugins [-n <node>] [-l] [-q] <command> [<command options>] General options: -n node -q quiet -l longnames Default node is "rabbit@server", where `server` is the local hostname. On a host named "server.example.com", the node name of the RabbitMQ Erlang node will usually be rabbit@server (unless RABBITMQ_NODENAME has been set to some non-default value at broker startup time). The output of hostname -s is usually the correct suffix to use after the "@" sign. See rabbitmq-server(1) for details of configuring the RabbitMQ broker. Quiet output mode is selected with the "-q" flag. Informational messages are suppressed when quiet mode is in effect. If RabbitMQ broker uses long node names for erlang distribution, "longnames" option should be specified. Some commands accept an optional virtual host parameter for which to display results. The default value is "/". Commands: disable <plugin>|--all [--offline] [--online] enable <plugin>|--all [--offline] [--online] help <command> list [pattern] [--verbose] [--minimal] [--enabled] [--implicitly-enabled] set [<plugin>] [--offline] [--online] <timeout> - operation timeout in seconds. Default is "infinity". 參考文章:http://www.rabbitmq.com/rabbitmq-plugins.8.html
3)rabbitmqadmin
它能夠執行一些與WEB界面相同的操做,rabbitmqadmin只是一個專門的HTTP客戶端。
安裝管理插件後,http://{主機名}:15672 /cli/rabbitmqadmin 進行下載
[root@master ~]# wget https://raw.githubusercontent.com/rabbitmq/rabbitmq-management/v3.7.6/bin/rabbitmqadmin [root@master ~]# cp rabbitmqadmin /usr/local/bin/ [root@master ~]# chmod +x /usr/local/bin/rabbitmqadmin7、RabbitMQ集羣
RabbitMQ 是用 erlang 開發的,集羣很是方便,由於 erlang 天生就是一門分佈式語言,但其自己並不支持負載均衡。
RabbitMQ 的集羣節點包括:
* 1)內存節點
內存節點就是將全部數據放在內存,只保存狀態到內存(例外的狀況:持久的queue內容將被保存到 disk)
* 2)磁盤節點。
磁盤節點將數據放在磁盤,保存狀態到內存和磁盤,內存節點雖然不寫入磁盤,可是它執行比磁盤節點要好,集羣中,只須要一個磁盤節點來保存狀態 就足夠了,若是集羣中只有內存節點,那麼不能中止它們,不然全部的狀態,消息等都會丟失。
不過,如前文所述,若是在投遞消息時,打開了消息的持久化,那即便是內存節點,數據仍是安全的放在磁盤。一個 RabbitMQ 集羣中能夠共享 user、vhost、queue、exchange 等,全部的數據和狀態都是必須在全部節點上覆制的,一個例外是那些當前只屬於建立它的節點的消息隊列,儘管它們可見且可被全部節點讀取。 RabbitMQ 節點能夠動態地加入到集羣中,一個節點它能夠加入到集羣中,也能夠從集羣環集羣進行一個基本的負載均衡。
Rabbit 模式大概分爲如下三種:
* 1)單一模式
* 2)普通模式
* 3)鏡像模式
單一模式:最簡單的狀況,非集羣模式。
普通模式:默認的集羣模式。
對於 Queue 來講,消息實體只存在於其中一個節點,A、B 兩個節點僅有相同的元數據,即隊列結構。當消息進入 A 節點的 Queue 中後,consumer 從 B 節點拉取時,RabbitMQ 會臨時在 A、B 間進行消息傳輸,把 A 中的消息實體取出並通過 B 發送給 consumer. 因此 consumer 應儘可能鏈接每個節點,從中取消息。即對於同一個邏輯隊列,要在多個節點創建物理 Queue。不然不管 consumer 連 A 或 B,出口總在 A,會產生瓶頸。該模式存在一個問題就是當 A 節點故障後,B 節點沒法取到 A 節點中還未消費的消息實體。若是作了消息持久化,那麼得等 A 節點恢復,而後纔可被消費。
鏡像模式:
把須要的隊列作成鏡像隊列,存在於多個節點,屬於 RabbitMQ 的 HA 方案。
該模式解決了上述問題,其實質和普通模式不一樣之處在於,消息實體會主動在鏡像節點間同步,而不是在 consumer 取數據時臨時拉取。該模式帶來的反作用也很明顯,除了下降系統性能外,若是鏡像隊列數量過多,加之大量的消息進入,集羣內部的網絡帶寬將會被這種同步通信大大消耗掉,所,在對可靠性要求較高的場合中適用。