RabbitMQ 是目前非常热门的一款消息中间件,不管是互联网行业还是传统行业都在大量的使用 。 RabbitMQ 凭借其高可靠、易扩展、高可用及丰富的功能特性受到越来越多企业的青睐。作为一个合格的开发者,有必要深入地了解 RabbitMQ 的相关知识,为自己的职业生涯添砖加瓦 。
RabbitMQ 是一个实现了 AMQP 的开源消息中间件,使用高性能的 Erlang 编写。 RabbitMQ 具有可靠性、支持多种协议、高可用、支持消息集群以及多语言客户端等特点,在分布式系统中存储转发消息,具有不错的性能表现。
AMQP (Advanced Message Queuing Protocol,高级消息队列协议)是一个线路层的协议规范, 而不是 API 规范(例如 JMS)。由于 AMQP 是一个线路层协议规范,因此它天然就是跨平台的, 就像 SMTP、 HTTP 等协议一样,只要开发者按照规范的格式发送数据,任何平台都可以通过 AMQP 进行消息交互。像目前流行的 StormMQ、 RabbitMQ 等都实现了 AMQP。
在Docker Hub官网查询rabbitmq版本信息,安装一个带有web管理界面的rabbitmq:Docker Hub官网Rabbit MQ版本页面
docker pull rabbitmq:3.8.0-management
首先在宿主机创建好映射目录rabbitmq,然后创建好data目录,并且要赋予足够的权限
chown -R 1000 [rabbitmq|目录]
执行如下命令时,当前所在目录一定要在rabbitmq,因为下面代码有用到pwd命令。
docker run -d --name rabbitmq \
-p 5672:5672 -p 15672:15672 \
-v $PWD/data:/var/lib/rabbitmq \
--hostname chenfu-admin \
-e RABBITMQ_DEFAULT_VHOST=my_vhost \
-e RABBITMQ_DEFAULT_USER=chenfu \
-e RABBITMQ_DEFAULT_PASS=chenfu \
rabbitmq:3.8.0-management
参数解析
docker ps
参考博客:centos7安装Rabbit MQ
主要参考博客:RabbitMQ安装参考博客
系统环境Cent OS 7.5 Mini
预装环境
yum install gcc glibc-devel make ncurses-devel openssl-devel autoconf
yum install unixODBC unixODBC-devel
wget http://erlang.org/download/otp_src_19.3.tar.gz
tar -zxvf otp_src_19.3.tar.gz
cd otp_src_19.3
./configure --prefix=/usr/local/erlang --enable-smp-support
make && make install
ln -s /usr/local/erlang/bin/erl /usr/local/bin/
输入如下命令,会显示出erlang的安装目录
whereis erlang
安装过程出现问题,可以参考这篇文章:erlang安装教程及常见问题
安装Rabbit MQ
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.1/rabbitmq-server-generic-unix-3.6.1.tar.xz
解压缩xz文件
tar -xvf rabbitmq-server-generic-unix-3.6.1.tar.xz
./rabbitmq-server stop
./rabbitmq-server start
或者
./rabbitmq-server -detached
./rabbitmq-server status
首先创建目录,否则可能报错:
mkdir /etc/rabbitmq
启用插件
./rabbitmq-plugins enable rabbitmq_management
配置linux 端口 15672 网页管理 5672 AMQP端口
firewall-cmd --permanent --add-port=15672/tcp
firewall-cmd --permanent --add-port=5672/tcp
systemctl restart firewalld.service
./rabbitmqctl add_user chenfu chenfu
./rabbitmqctl set_permissions -p / chenfu ".*" ".*" ".*"
./rabbitmqctl set_user_tags chenfu administrator
RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上, RabbitMQ 就好比由邮局、邮箱和邮递员组成的一个系统。从计算机术语层面来说,RabbitMQ 模型更像是一种交换机模型。
生产者创建消息,然后发布到 RabbitMQ 中。消息一般可以包含 2 个部分:消息体和标签(Label)。消息体也可以称之为 payload,在实际应用中,消息体一般是一个带有业务逻辑结构的数据,比如一个 JSON 字符串。当然可以进一步对这个消息体进行序列化操作。消息的标签用来表述这条消息 , 比如一个交换器的名称和一个路由键。 生产者把消息交由 RabbitMQ, RabbitMQ 之后会根据标签把消息发送给感兴趣的消费者(Consumer)。
消费者连接到 RabbitMQ 服务器,并订阅到队列上。当消费者消费一条消息时,只是消费消息的消息体(payload)。在消息路由的过程中,消息的标签会丢弃,存入到队列中的消息只有消息体,消费者也只会消费到消息体,也就不知道消息的生产者是谁,当然消费者也不需要知道。
对于 RabbitMQ 来说,一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点,或者 RabbitMQ 服务实例。大多数情况下也可以将一个 RabbitMQ Broker 看作一台 RabbitMQ 服务器。
RabbitMQ 中消息都只能存储在队列中,RabbitMQ 的生产者生产消息并最终投递到队列中,消费者可以从队列中获取消息并消费。多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息井处理。
RabbitMQ 不支持队列层面的广播消费,如果需要广播消费,需要在其上进行二次开发,处理逻辑会变得异常复杂,同时也不建议这么做。
生产者将消息发送到 Exchange (交换器,通常也可以用大写的 “X” 来表示),由交换器将消息路由到一个或者多个队列中。如果路由不到,或许会返回给生产者,或许直接丢弃。这里可以将 RabbitMQ 中的交换器看作一个简单的实体。
RabbitMQ 中的交换器有四种类型,不同的类型有着不同的路由策略
交换器类型
RabbitMQ 常用的交换器类型有 fanout、 direct、 topic、 headers 这四种。 AMQP 协议里还提到另外两种类型: System 和自定义。
它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。
direct 类型的交换器路由规则也很简单,它会把消息路由到那些 BindingKey 和 RoutingKey全匹配的队列中。
前面讲到 direct 类型的交换器路由规则是完全匹配 BindingKey 和 RoutingKey,但是这种严格的匹配方式在很多情况下不能满足实际业务的需求。 topic 类型的交换器在匹配规则上进行了扩展,它与 direct 类型的交换器相似,也是将消息路由到 BindingKey 和 RoutingKey 相匹配的队列中,但这里的匹配规则有些不同,它约定:
*:匹配单个字母或数字
#:匹配0~多个字母或数字
生产者将消息发给交换器的时候, 一般会指定一个 RoutingKey,用 来指定这个消息的路由规则,而这个 RoutingKey 需要与交换器类型和绑定键 (BindingKey) 联合使用才能最终生效。
在交换器类型和绑定键 (BindingKey) 固定的情况下,生产者可以在发送消息给交换器时,通过指定 RoutingKey 来决定消息流向哪里。
RabbitMQ 中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一个绑定键 (BindingKey),这样 RabbitMQ 就知道如何正确地将消息路由到队列了。
生产者将消息发送给交换器时, 需要一个 RoutingKey,当 BindingKey 和 RoutingKey 相匹配时,消息会被路由到对应的队列中。在绑定多个队列到同一个交换器的时候,这些绑定允许使用相同的 BindingKey。而且BindingKey 并不是在所有的情况下都生效,它依赖于交换器类型,比如 fanout 类型的交换器就会无视 BindingKey,而是将消息路由到所有绑定到该交换器的队列中 。