消息(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 取数据时临时拉取。该模式带来的反作用也很明显,除了下降系统性能外,若是镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通信大大消耗掉,所,在对可靠性要求较高的场合中适用。
若有错误或其它问题,欢迎小伙伴留言评论、指正。若有帮助,欢迎点赞+转发分享。
欢迎你们关注民工哥的公众号:民工哥技术之路