消息(Message)是指在應用間傳送的數據。消息能夠很是簡單,好比只包含文本字符串,也能夠更復雜,可能包含嵌入對象。消息隊列(Message Queue)是一種應用間的通訊方式,消息發送後能夠當即返回,由消息系統來確保消息的可靠傳遞。消息發佈者只管把消息發佈到 MQ 中而不用管誰來取,消息使用者只管從 MQ 中取消息而不論是誰發佈的。這樣發佈者和使用者都不用知道對方的存在。html
消息隊列是一種應用間的異步協做機制
,那何時須要使用消息隊列呢?像用戶下單以後、生成訂單、結算,定時給系統註冊用戶推送活動消息,一些常見的流程類的業務都會用到消息隊列服務。node
RabbitMQ是一個消息的代理器,用於接收和發送消息,你能夠這樣想,他就是一個郵局,當您把須要寄送的郵件投遞到郵筒之時,你能夠肯定的是郵遞員先生確定會把郵件發送到須要接收郵件的人的手裏,不會送錯的。在這個比喻中,RabbitMQ就是一個郵箱,也能夠理解爲郵局和郵遞員,他們負責把消息發送出去和用於接收信息。
RabbitMQ和郵局這二者之間的主要區別是它不會處理紙質郵件,取而代之的是接收、存儲和發送二進制數據塊,也就是咱們一般所說的消息。linux
下圖是RabbitMQ服務的內部結構git
RabbitMQ 是一個由 Erlang 語言開發的 AMQP 的開源實現。AMQP :Advanced Message Queue,高級消息隊列協議。它是應用層協議的一個開放標準,爲面向消息的中間件設計,基於此協議的客戶端與消息中間件可傳遞消息,並不受產品、開發語言等條件的限制。
RabbitMQ 最初起源於金融系統,用於在分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。github
1)可靠性(Reliability
RabbitMQ 使用一些機制來保證可靠性,如持久化、傳輸確認、發佈確認。
2)靈活的路由(Flexible Routing)
在消息進入隊列以前,經過Exchange 來路由消息的。對於典型的路由功能,RabbitMQ 已經提供了一些內置的Exchange 來實現。針對更復雜的路由功能,能夠將多個Exchange綁定在一塊兒,也經過插件機制實現本身的 Exchange 。
3)消息集羣(Clustering)
多個 RabbitMQ 服務器能夠組成一個集羣,造成一個邏輯 Broker 。
4)高可用(Highly Available Queues)
隊列能夠在集羣中的機器上進行鏡像,使得在部分節點出問題的狀況下隊列仍然可用。
5)多種協議(Multi-protocol)
RabbitMQ 支持多種消息隊列協議,好比 STOMP、MQTT 等等。
6)多語言客戶端(Many Clients)
RabbitMQ 幾乎支持全部經常使用語言,好比 Java、.NET、Ruby 等等。
7)管理界面(Management UI)
RabbitMQ 提供了一個易用的用戶界面,使得用戶能夠監控和管理消息 Broker 的許多方面。
8)跟蹤機制(Tracing)
若是消息異常,RabbitMQ 提供了消息跟蹤機制,使用者能夠找出發生了什麼。
9)插件機制(Plugin System)
RabbitMQ 提供了許多插件,來從多方面進行擴展,也能夠編寫本身的插件。
1)首先須要安裝Erlang環境shell
https://bintray.com/rabbitmq/rpm/erlang [root@master ~]# rpm -ivh erlang-20.3.8-1.el7.centos.x86_64.rpm 準備中... ################################# [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)下載安裝Rabbitmqjson
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)查看狀態信息segmentfault
[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}}]
1)rabbitmqctl #管理與操做命令centos
[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 / ... 更多操做內容請參考:http://www.rabbitmq.com/rabbitmqctl.8.html
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 hostnamed "server.example.com", the node name of the RabbitMQ Erlang node willusually be rabbit@server (unless RABBITMQ_NODENAME has been set to somenon-default value at broker startup time). The output of hostname -s is usuallythe correct suffix to use after the "@" sign. See rabbitmq-server(1) fordetails of configuring the RabbitMQ broker. Quiet output mode is selected with the "-q" flag. Informational messages aresuppressed 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 whichto 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客戶端。
[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/rabbitmqadmin
RabbitMQ 是用 erlang 開發的,集羣很是方便,由於 erlang 天生就是一門分佈式語言,但其自己並不支持負載均衡。
RabbitMQ 的集羣節點包括:
1)內存節點
內存節點就是將全部數據放在內存,只保存狀態到內存(例外的狀況:持久的queue內容將被保存到 disk)
2)磁盤節點。
磁盤節點將數據放在磁盤,保存狀態到內存和磁盤,內存節點雖然不寫入磁盤,可是它執行比磁盤節點要好,集羣中,只須要一個磁盤節點來保存狀態 就足夠了,若是集羣中只有內存節點,那麼不能中止它們,不然全部的狀態,消息等都會丟失。
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 取數據時臨時拉取。該模式帶來的反作用也很明顯,除了下降系統性能外,若是鏡像隊列數量過多,加之大量的消息進入,集羣內部的網絡帶寬將會被這種同步通信大大消耗掉,所,在對可靠性要求較高的場合中適用。
若有錯誤或其它問題,歡迎小夥伴留言評論、指正。若有幫助,歡迎點贊+轉發分享。
歡迎你們關注民工哥的公衆號:民工哥技術之路