RabbitMQ实战指南-朱忠华-电子工业出版社

RabbitMQ简介

消息中间件的作用:

  • 解耦
  • 冗余(存储)
  • 拓展性
  • 削峰
  • 可恢复性:处理消息的机器宕机之后,消息中间件可以存储消息
  • 顺序保证
  • 缓冲
  • 异步通信:消息中间件可以延迟消费

RabbitMQ具体特点:

  • 可靠性:消息确认发布、传输确认,持久化
  • 灵活的路由
  • 拓展性:可以拓展为集群
  • 高可用:可以设置队列镜像,单一RabbitMQ挂机后,有镜像提供服务
  • 多种协议
  • 多语言客户端
  • 管理界面
  • 插件机制

RabbitMQ入门

GurFP0.png

RabbitMQ的模型架构如图,生产者Publisher通过TCP连接Connnection与RabbitMQ服务器Broker连接,每个Connection中有多个ChannelBroker服务器中有多个Virtual Host,每个Virtual Host各自独立。Publisher发布消息Message到Exchange交换器,Message包含label(路由键)+payload(消息体),Binding上带有绑定键,交换器根据自身性质和路由键和绑定键决定将消息投递到哪里。最终消息被保存在Queue队列中,Consumer监听队列获得消息。

注意:

  • 生产者将消息传到交换器后,交换器根据自身交换器类型和路由键、绑定键决定消息投递的方向。
  • 只有队列能存储消息,消息到达队列时已没有label了,只剩下消息体
  • 当多个Consumer连接到同一个队列时,队列上的消息将轮询发给每个Consumer而不是每个消息复制多份发给每个Consumer,即每个消息只能被成功消费一次

AMQP协议

Gu27y6.png

如上图,AMQP协议每次发送数据时的指令。

客户端开发向导

本章讲了RabbitMQ Java客户端的开发,只摘录我的部分理解在此。

创建RabbitMQ各个组件时可以有不同的参数。

  • Exchange交换器:type类型、durable是否持久化(持久化的Exchange重启时不会消失),autoDelete自动删除(当Exchange所绑定的queue都删除后,自动删除Exchange,默认不自动删除),internal是否内置(若是,客户端程序无法发信息到此交换器,只有交换器能发到此交换器)
  • queue队列:durable是否持久化、exclusive排他(同Connection可见,其他Conntection不能创建同名队列,Connection断掉自动删除)、autoDelete自动删除(有消费者订阅过此队列,之后所有消费者取消订阅,则删除,生产者创建队列后无客户端连接是不会删除的)

RabbitMQ的消息存储在队列中,交换器的使用并不真正耗费服务器的性能,而队列会。衡量RabbitMQ的QPS只需看队列即可。

  • 消息投递模式:发送消息处理指明交换器和路由键,还可以指定消息的一些属性,如投递模式为2时,消息可持久化。可以设置消息的优先级。
  • 消费消息:有两种模式,推模式Push和拉模式pull。消费消息时可以设置是否自动确认。当然,消息发送方也可以设置发送确认,RabbitMQ的exchange收到消息时可以回调发送方设置的监听。

消费端的确认和拒绝:消息订阅有推和拉两种模式,订阅时可以设置是否自动确认,自动确认的消息在RabbitMQ将消息发出时移除,非自动确认的消息需要客户端手动确认。也可以拒绝该消息,拒绝时传递一个requeue参数,可以设置是否将该消息重洗入队等待发送,或者将其移除。

RabbitMQ进阶

本章讲的是RabbitMQ的高级功能。

  • 交换器的属性:
    • mandatory属性为true时,交换器如果找不到消息的路由,会将消息返回生产者,为false则丢弃
    • immediate参数为true时,当路由器发现队列中不存在任何消费者,则不投递到该队列。若所有队列都无消费者,则将消息返回生产者。RabbitMQ 3.0去掉了该属性。

备份交换器AE:

  • 当mandatory为true时,无法路由的消息会返回生产者,为false时,无法路由的消息会被丢弃。除了这两者,还可以为交换器设置备份交换器,当消息无法路由时,会发送到备份交换器,备份交换器和mandatory一起使用,该参数无效。

过期时间TTL

  • 过期时间可以设置在队列,也可以单独设置在消息。一旦消息过期,就会变成“死信”。对于设置队列的TTL,一旦消息过期则从队列中抹去,而对于单独设置TTL的消息,过期后不会马上抹去,而是在消息投递给消费者之前判断的。

死信交互器DLX(也称死信队列):

  • 当消息变为死信之后,他能被发送到死信交换器。
  • TTL和DLX可以做延时队列
GtcFsg.png

持久化,RabbitMQ分为三部分:

  • 交换器持久化:交换器不持久化的话,重启后元数据丢失,但消息不会丢失,因为消息存在队列中
  • 队列持久化:队列不持久化的话,重启后队列会消失,消息也消失
  • 消息持久化:如果消息不持久化,那么重启时消息会丢失,队列持久化只能保证队列的元数据不丢失,不能保证消息不丢失。

消息的可靠性:

  • 生产者确认:默认情况下,生产者发送消息后不知道消息是否到达了RabbtMQ服务器。可以通过两种方式确认
    • 事务机制:如channel.txSelect将channel设置为事务模式,每次发送消息前都需要发送事务指令,严重影响性能
    • 发送方确认:类似tcp批量确认,每个消息都编号,RabbitMQ会确认一个序号表示这个序号之前的消息都已确认。相比上面的事务机制,这里是异步的,而事务是同步确认每一条消息的。
    • 当然,生产者确认只能保证消息传递到了服务器的交换器。如果消息没有匹配的队列,那么消息也会丢失,发送方可以配合mandatory参数或备份交换器解决没有匹配队列时的处理方式。
  • 消费端要点:默认队列中的消息会轮询分发到订阅同一队列的消费者,RabbitMQ并不管消费者是否确认了该消息,这会造成性能差的服务器处理过慢。可以使用channel.basicQos设定每个消费者最多持有未确认的消息数量,这种机制类似tcp的滑动窗口,这种机制对于拉模式的消息消费无效。
    • 消息顺序性:消息的顺序性是从存入队列是开始的,不能认为是从生产者发送时开始的,因为有网络抖动。
    • 消息传输保障:
      • 最多一次:生产者随意发送,消费者随意消费
      • 最少一次:生产者开启发送确认,生产者需要使用mandatory参数或备份交换器确保消息无法路由时能保存到队列。消息和队列都需要进行持久化。消费者需要手动确认消息。
      • 恰好一次:无法保证消息恰好一次被消费,因为网络原因,消费者消费之后发送确认消息时刚好网络断开,连接重新建立时消费者会重新消费到消息。RabbitMQ无法保证恰好一次,不仅RabbitMQ目前大多数主流的中间件都无法保证恰好一次。

RabbitMQ管理

RabbitMQ的应用工具:

  • rabbitmqctl:命令行工具
  • rabbitmq_management插件:图形化插件

多租户与权限

  • 添加vhost:rabbitmqctl add_vhost myhost
  • 显示vhost:rabbitmqctl list_vhosts
  • 删除vhost:rabbitmqctl delete_host myhost
  • 权限配置到vhost:rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read},如授予root用户可访问虚拟主机myhost并具备所有权限
    rabbitmqctl set_permissions -p myhost root ".*" ".*" ".*"
  • 清除权限:rabbitmqctl clear_permissions [-p vhost] {user}
  • 查看权限:rabbitmqctl list_user_permissions {user}

用户管理

  • 创建用户:rabbitmqctl add_user {username} {password}
  • 改密码:rabbitmqctl change_password {username} {password}
  • 清除密码:rabbitmqctl clear_password {username} {password}
  • 验证密码:rabbitmqctl authenticate_user {username} {password}
  • 删除用户:rabbitmqctl delete_user {username}
  • 查看用户:rabbitmqctl list_users
  • 设置角色:rabbitmqctl set_user_tags {username} {tags...}

用户分为五种角色:

  • none:无任何角色,新创建的用户默认为none角色
  • management:可以访问web管理页面
  • policymaker:包含management的所有权限,并可以管理策略和参数
  • monitoring:包含management的所有权限,并可以看到所有连接、信道和结点
  • administrator:管理员

web端管理

  • 启动插件命令:rabbitmq-plugins enable rabbitmq_management
  • 查看插件使用情况:rabbitmq-plugins list

应用与集群管理

  • 停止服务:rabbitmqctl stop,rabbitmqctl stop_app,rabbitmqctl shutdown
  • 重置:rabbitmqctl reset还原rabbitmq到最初状态

vhost、权限等都可以使用rabbitmqctl来创建,但交换器、队列和绑定关系却无法用rabbitmqctl来创建,只能通过web管理界面创建。然而,rabbitmq management还提供了命令行rabbitmqadmin来解决这个问题。如查看队列中的消息

rabbitmqadmin get queue=myqueue

rabbitmq management还提供了http api接口来方便调用。如创建一个队列,可以使用PUT方法调用/api/queues/vhost/name接口来实现。

RabbitMQ配置

三种方式配置:

  • 环境变量:如RABBITMQ_NODENAME=rabbit@node2 rabbitmq-server -detached,环境变量也可配置在RABBITMQ_HOME/etc/rabbitmq/rabbitmq-env.conf中
  • 配置文件:配置文件位于/opt/rabbitmq/etc/rabbitmq/rabbitmq.config
  • 运行时参数和策略:可以通过rabbitmqctl或management插件提供的http api来设置,如rabbitmqctl set_parameter

RabbitMQ运维

本章主要将集群的搭建和运维

跨越集群的界限

RabbitMQ可以通过3种方式实现分布式部署:

  • 集群
  • Federation:该插件的目的是使RabbitMQ在不同的Broker结点之间进行消息通信而无需创建集群
  • Shovel:该插件能够可靠、持续地从一个Broker中的队列拉取数据并转发至另一个Broker中的交换器。

RabbitMQ高阶

本章是将RabbitMQ的内部原理的,需要熟悉

流控

RabbitMQ可以对内存和磁盘使用量设置阈值,达到阈值后,生产者将阻塞。这是全局流控,面向所有连接的。当然RabbitMQ也可以面向单个Connection进行流控。

RabbitMQ使用一种基于信用证算法的流控机制来限制发送消息的速率。

镜像队列

生产者发送消息时,会将消息都发送到各个slave,除发送消息外的所有动作都只会向master发送,然后再由master将命令执行的结果广播给各个slave。

网络分区

在局域网环境下,网络设备出现故障时也会导致网络分区。当出现网络分区时,不同分区里的结点会认为不属于自身所在分区的结点都已经挂了。如果原集群中配置了镜像队列,每个网络分区中都会出现一个master结点。

RabbitMQ拓展

消息追踪:Firehose

负载均衡:轮询、加权轮询、随机、加权随机、源地址哈希、最小连接数

使用HAProxy实现负载均衡

使用Keepalived实现高考可靠负载均衡

使用keepalived+LVS实现负载均衡

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 什么叫消息队列? 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复...
    Agile_dev阅读 2,371评论 0 24
  • 1.connection可以用来创建多个channel实例,但是channel实例不能再线程间共享,应用程序应该为...
    神烦2阅读 478评论 0 1
  • RabbitMQ采用Erlang编写,需安装语言库才能运行RabbitMQ代理服务器。AMQP:高级消息队列协议。...
    JAVA觅音阁阅读 3,630评论 0 7
  • rabbitmqctl 命令的一些基础操作 rabbitmqctl add vhost {vhostName} -...
    _大叔_阅读 9,086评论 0 1
  • RabbitMQ 原理介绍及安装部署 标签:RabbitMQ 安装 简介 RabbitMQ 是一个用 Erlang...
    神仙CGod阅读 8,567评论 0 60