RabbitMQ使用分析和高可用集群搭建
顶
原
荐
字数 3009
阅读 119
收藏 3
点赞 0
评论 0
华为云开发者4大福利:2核4G云主机、DevCloud、应用服务、培训课程 免费领取 >>>
一、RabbitMQ 基础理解
RabbitMQ,是一个使用 erlang 编写的 AMQP(高级消息队列协议)的服务实现,简单来说,就是一个功能强大的消息队列服务。
概念理解:
- Producer : 消息发送者
- RabbitMQ :
- Vhost: 相当于分组,每个vhost下数据是隔离的
- Exchange: 路由器,接收消息,本根据RoutingKey分发消息
- headers:消息头类型 路由器,内部应用
- direct:精准匹配类型 路由器
- topic:主题匹配类型 路由器,支持正则 模糊匹配
- fanout:广播类型 路由器,RoutingKey无效
- RoutingKey: 路由规则
- Queue: 队列,用于存储消息(消息的目的地)
- Consumer : 消息消费者
持久化:
一个好的消息队列当然需要消息持久化功能,服务宕机,未消费消息不丢失,RabbitMQ持久化分为Exchange、Queue、Message
Exchange 和 Queue 持久化 指持久化Exchange、Queue 元数据,持久化的是自身,服务宕机,Exchange 和 Queue 自身就没有了
Message 持久化 顾名思义 把每一条消息体持久化,服务宕机,消息不丢失
Durable 持久、Transient 临时,Queue新建类似
分析理解:
便于更直观的理解,把 RabbitMQ 的消息流对比与Http Rest接口更家熟悉形象
www.xxx.com/webappPath/trade/getOrder -> getOrder(message) GET
RabbitMQ Server:同比 域名 www.xxx.com,只有通过域名才能到达 Server
Vhost:同比 /webappPath,一个域名可能指向多个app
Exchange:同比 /trade,trade/* 下有多个method,但是需要先到达这个Class
RoutingKey:同比 /getOrder,只有完成的 URL 才是有效的,才能确定到具体的方法 Queue:同比 getOrder(message) 消息的最终目的地
Exchange Type: 同比 GET,但是Rest MethodType是整个URL的Type,而不是 Queue
以上只是为了更好理解,千万不要混淆
Producer / Consumer 就很好理解了,基于AMQP协议链接RabbitMQ Server,发送消息 / 接收消息
二、RabbitMQ 消息确认策略分析
Confrim / Transaction 概念应用
RabbitMQ 提供了两种可靠性的确认策略 Confrim / Transaction,Producer Client仅分析Spring-Amqp,两种机制主要影响发送:
Confrim: 简单说就是直接传送消息 client > mq, 接收到 mq > ack, mq 在异步的完成 接下来的事情
Transaction: client 请求开启事务 > 发送message > client 提交事务,整个过程是同步的,mq必须完成消息持久化、消息同步等。
spring-amqp 提供的发送客户端 默认是Confrim 异步Ack模式,不用特殊配置,Transaction 需要在默认的基础上增加 RabbitMQ事务管理器
// 1.向Spring中注册RabbitMQ事务管理器 @Bean public RabbitTransactionManager rabbitTransactionManager(ConnectionFactory connectionFactory) { return new RabbitTransactionManager(connectionFactory); } ... // 2.设置通道为Transaction类型 rabbitTemplate.setChannelTransacted(true); ... // 3.对应的方法添加@Transactional @Transactional public void send(String exchange, String routingKey, Object object) { rabbitTemplate.convertAndSend(exchange, routingKey, object); }
Confrim / Transaction 测试分析
模式 |
RabbitTemplate 实现 | RabbitMQ Server 宕机、掉电 持久化消息测试 (是否发送发送丢失) |
Confrim | 异步确认模式: 发送线程不会立即得到MQ反馈结果,发送后通过callback确认成功失败,类似线程池,效率高 |
发送线程:由于是异步确认模式,当RabbitMQ Server突然失联,发送线程仍会继续发送多条消息,之后发现链接断开,抛出异常 假设RabbitMQ Server 接收500挂掉 发送线程:700 实际接收 RabbitMQ Server:500 callback线程 失败:200(预期 未具体测试) 缺点:发送线程认为已经发送成功,但是却失败了,反馈结果只能通callback获得,多线程问题,如未处理callback,则消息丢失 优点:性能好 |
Transaction | 事务确认模式: 发送线程会立即得到MQ反馈结果,同一线程中,多个发送阻塞进行,同db Transaction一样支持失败回滚等,效率高 @Transactional 支持同时管理db、mq事务,意味用一个事务中可以操作db、mq,进行提交回滚 @Transactional 坑:
|
发送线程:由于是事务确认模式,当RabbitMQ Server突然失联,发送线程得不到当前正在发送消息的回执,直接抛出异常 假设RabbitMQ Server 接收500挂掉 发送线程:500 实际接收 RabbitMQ Server:500 缺点:同步发送,逐条确认,效率低 优点:同步发送,发送线程可以立即得到反馈结果,对于主线程消息不丢失 |
Consumer
消费的机制和发送差不多, 但流程变为 Consumer 处理消息,需要Ack MQ Server, Server 才会真正的删除消息,通常消费者不需要开启事务,当处理异常抛出,Ack无法发到Server到,消息就会回到队列中,继续重试,阻塞到直到消息被消费Ack掉,所说的消息阻塞
三、RabbitMQ 配置
RabbitMQ 安装
RabbitMQ是基于Erlang运行的,首先选择RabbitMQ版本,确定需要的Erlang版本,然后安装Erlang,自行百度、谷歌、 RabbitMQ官网 或者 Erlang官网 都会有相应的资源、教程(ps: Erlang 版本请严格按照所选RabbitMQ版本要求的Erlang范围安装,否则会有各种不治之症)
本文以 Erlang20.03,RabbitMQ 3.7为例,RabbitMQ为 linux 通用包,不同安装方式版本配置文件路径有差异,通用包好处,可移植性、控制性好
包目录结构:
./sbin/ rabbitmq 启动rabbitmq-server、插件rabbitmq-plugins、功能rabbitmqctl等脚本位置
./etc/rabbitmq/ rabbitmq 启动配置,包括随启动插件配置、环境配置、应用配置
RabbitMQ 配置文件
- rabbitmq-env.conf 环境配置 key = val 形式
# 指定节点的名字 默认 rabbit@${hostname},如指定了节点名,需配置 host ip cluster1 NODENAME=rabbit@cluster1 # 指定端口 默认 5672 NODE_PORT=5672 # 配置持久目录 MNESIA_BASE=/mnt/data1/rabbitmq/store # 配置日志目录 默认文件名字:${NODENAME}.log 可以用配置修改 LOG_BASE=/mnt/data1/rabbitmq/logs
- rabbitmq.conf 环境配置 key = val 形式
主要配置日志、默认用户信息、持久化相关等,没有定制化通常不用修改
# console log config 主要测试排查问题 log.console = false log.console.level = debug # log config log.file = rabbit.log log.file.level = info log.file.rotation.date = $D0 # web port management.listener.port = 15672
-
enabled_plugins 配置相应插件的名字 server start plugin也会启动
[rabbitmq_management].
具体请看官方配置说明, 详细的讲解了rabbitmq-env.conf 和 rabbitmq.conf 配置 官方配置说明
RabbitMQ 常用命令:
# 后台启动本地服务 ./rabbitmq-server –detached # 开启/关闭 服务 ./rabbitmqctl start_app {-n node_name} ./rabbitmqctl stop_app {-n node_name} # 开启/关闭某个插件 (重启服务器后生效) ./rabbitmq-plugins enable xxx ./rabbitmq-plugins disable xxx # 更改节点类型 ./rabbitmqctl change_cluster_node_type {disc/ram} {-n node_name} # 配置用户 ./rabbitmqctl add_user username password ./rabbitmqctl change_password username newpassword ./rabbitmqctl delete_user username ./rabbitmqctl set_user_tags username administrator Tag: none、management、policymaker、monitoring、administrator ./rabbitmqctl set_permissions -p /vhost1 username 'conf' 'write' 'read' conf 一个正则表达式match哪些配置资源能够被该用户配置 write 一个正则表达式match哪些配置资源能够被该用户写入 read 一个正则表达式match哪些配置资源能够被该用户读取
四、高可用的集群搭建
基础概念
RabbitMQ 集群分为两种 普通集群 和 镜像集群,可以说 镜像集群 是 普通集群 的晋升版
普通集群:
以两个节点(rabbit01、rabbit02)为例来进行说明。
rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构,但消息实体只存在于其中一个节点rabbit01(或者rabbit02)中。
当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
镜像集群:
在普通集群的基础上,把需要的队列做成镜像队列,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取,也就是说多少节点消息就会备份多少份。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用
由于镜像队列之间消息自动同步,且内部有选举master机制,即使master节点宕机也不会影响整个集群的使用,达到去中心化的目的,从而有效的防止消息丢失及服务不可用等问题
集群搭建
RabbitMQ 集群通信的验证机制是通过 erlang.cookie进行确认的,只有erlang.cookie一致的两个服务才能通信,创建cookie文件:
mkdir ~/.erlang.cookie echo 'SJJARLYPVRPMWFVGKWZZ' > ~/.erlang.cookie chmod 400 ~/.erlang.cookie
cluster1=10.0.0.1, cluster2=10.0.0.2 2台服务器为例,本地搭建需修改 tcp端口、web端口
写入hostes:
10.0.0.1 cluster1 10.0.0.2 cluster2
修改rabbitmq-env.conf:
# server1 NODENAME=rabbit@cluster1 ... # server2 NODENAME=rabbit@cluster2
启动server1:
./rabbitmq-server –detached
将server2加入到server形成集群:
./rabbitmqctl -n rabbit@cluster2 stop_app # 重置元数据、集群配置等信息 ./rabbitmqctl -n rabbit@cluster2 reset # cluster2 加入到 cluster1 的集群中 --ram表示cluster2为RAM节点 默认为disc ./rabbitmqctl -n rabbit@cluster2 join_cluster rabbit@cluster1 --ram ./rabbitmqctl -n rabbit@cluster2 start_app
普通集群就搭建完成了,普通集群并不是高可用的,基于普通集群升级为镜像集群 RabbitMQ HA方案
./rabbitmqctl set_policy <name> [-p <vhost>] <pattern> <definition> [--apply-to <apply-to>] name: 策略名称 vhost: 指定vhost, 默认值 / pattern: 需要镜像的正则 definition: ha-mode: 指明镜像队列的模式,有效值为 all/exactly/nodes all 表示在集群所有的节点上进行镜像,无需设置ha-params exactly 表示在指定个数的节点上进行镜像,节点的个数由ha-params指定 nodes 表示在指定的节点上进行镜像,节点名称通过ha-params指定 ha-params: ha-mode 模式需要用到的参数 ha-sync-mode: 镜像队列中消息的同步方式,有效值为automatic,manually apply-to: 可选值3个,默认all exchanges 表示镜像 exchange (并不知道意义所在) queues 表示镜像 queue all 表示镜像 exchange和queue eg: ./rabbitmqctl set_policy test "test" '{"ha-mode":"all","ha-sync-mode":"automatic"}' 测试: exchange = test, queue = test case1: pattern=test, apply-to=exchanges -> 结果 exchange被镜像 case2: pattern=test, apply-to=queues -> 结果 queue被镜像 case3: pattern=test, apply-to=all -> 结果 queue被镜像 结论: 不知道exchange被镜像的意义所在,镜像queue才是关键
ps:
保证集群的高可用,至少要有1个disc节点
RabbitMQ Cluster 全部挂掉,RAM节点无法先启动,必须先启动disc节点
推荐 2 RAM 1 DISC 集群搭建方式
总结:
RabbitMQ高可用集群还是非常有必要的,高可用的代价就是性能的降低,对可靠性要求比较高的企业务还是值得的,据我测试2R1D镜像集群(非压测, 压测结果绝对更高),达到1000QPS+还是没问题的,如果开启事务,保证同步发送应答,也可达500QPS+,绝对满足大多数可靠性要求高的业务。
写的不好,欢迎大家吐槽,一起讨论,我也会进一步的修改,没有附上demo项目代码,spring-ampq都有介绍,就不嫌丑了,如有需要留言,我会附上链接
© 著作权归作者所有
共有人打赏支持
相关文章 最新文章
摘要:实际生产应用中都会采用消息队列的集群方案,如果选择RabbitMQ那么有必要了解下它的集群方案原理 一般来说,如果只是为了学习RabbitMQ或者验证业务工程的正确性那么在本地环境或者测试...
癫狂侠 ⋅ 05/25 ⋅ 0
前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用。不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/category/855479.html 本来一直想写一...
andrewniu ⋅ 05/09 ⋅ 0
一、RabbitMQ集群(普通模式) 概念 将多个RabbitMQ节点构成一个集群,统一对外提供消息服务。 特点 集群中的消息队列并不会在所有节点中都创建一份,而是仅存在于最早创建队列的那个节点上。...
勇敢的飞石 ⋅ 2015/07/29 ⋅ 0
本章是《Docker下RabbitMQ四部曲》系列的第二篇,将详细简述 Docker 下制作RabbitMQ镜像的技术细节,包括以下内容: 1. 列举制作RabbitMQ镜像时用到的所有材料; 2. 编写Dockerfile; 3. 编写容...
boling_cavalry ⋅ 05/13 ⋅ 0
摘要:任何没有监控的系统上线,一旦在生产环境发生故障,那么排查和修复问题的及时性将无法得到保证 一、为何要对消息中间件进行监控? 上线的业务系统需要监控,然而诸如消息队列、数据库、...
癫狂侠 ⋅ 05/28 ⋅ 0
本章是《Docker下RabbitMQ四部曲》系列的终篇,今天的我们一起来体验Rabbit’MQ集群的高可用能力,看看RabbitMQ集群中的部分节点宕机时,是否还能生产和消费消息; 原文地址:https://blog....
boling_cavalry ⋅ 05/19 ⋅ 0
本文仅针对RabbitMQ与Redis做队列应用时的情况进行对比 具体采用什么方式实现,还需要取决于系统的实际需求 简要介绍 RabbitMQ RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,...
Edwyn王 ⋅ 2015/05/20 ⋅ 0
微服务架构与MQ RabbitMQ场景分析与优化 RabbitMQ在网易蜂巢中的应用和案例分享 1微服务架构与MQ 微服务架构是一种架构模式,它将单体应用划分成一组微小的服务,各服务之间使用轻量级的通信...
andrewniu ⋅ 05/10 ⋅ 0
本文仅针对RabbitMQ与Redis做队列应用时的情况进行对比 具体采用什么方式实现,还需要取决于系统的实际需求 简要介绍 RabbitMQ RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,...
凯文加内特 ⋅ 2015/05/20 ⋅ 0
简介 为了更好地支撑日益增长的庞大业务量,我们常常需要把服务进行整合、拆分,使我们的服务不仅能通过集群部署抵挡流量的冲击,又能根据业务在其上进行灵活的扩展。随着分布式的普及、服务...
osswangxining ⋅ 05/25 ⋅ 0
没有更多内容
加载失败,请刷新页面
加载更多NVIDIA Optimus 架构的显卡在 Windows Server 系统上无法正常工作,就算是强制使用也没有反应。其实很简单,我们都知道这驱动需要使用 AppInit_DLL 这东西,然后 Windows Server 系统默认要求...
Angus_Wong ⋅ 37分钟前 ⋅ 0
Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @Sharon啊:分享栗先达的单曲《繁华之处》如同一头麋鹿闯进一座花园,我是一个动物踏进你的眼里。 《繁华之处》- 栗先达 手机党少年们想听歌,...
小小编辑 ⋅ 今天 ⋅ 9
概述 性能监控是容器服务必不可少的基础设施,容器化应用运行于宿主机上,我们需要知道该容器的运行情况,包括 CPU使用率、内存占用、网络状况以及磁盘空间等等一系列信息。在我的前文《Doc...
CodeSheep ⋅ 今天 ⋅ 0
《jQuery零基础入门》系列博文是在廖雪峰老师的博文基础上,补充了个人的理解和日常遇到的点,用我的理解表述出来,主干出处来自廖雪峰老师的技术分享。 除了基本的选择器外,jQuery的层级选...
JandenMa ⋅ 今天 ⋅ 0
0、算法概述 0.1 算法分类 十种常见 排序算法 可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。 ...
o0无忧亦无怖 ⋅ 今天 ⋅ 0
go 基础之并发笔记 协程 与传统的系统级线程和进程相比,协程的大优势在于其“轻量级”,可以轻松创建上百万个而不会导致系统资源衰竭,而线程和进程通常多也不能超过1万个。这也是协程也叫轻...
D_Kim ⋅ 今天 ⋅ 0
sed是流式编辑器,是针对文档的行来操作的。grep只能实现查找功能,不能把查找的内容替换。vim可以实现替换,它只能在文本的内部操作,不能输出的屏幕上。而sed工具就可以替换文本并把它输出...
黄昏残影 ⋅ 今天 ⋅ 0
高并发系统的保护策略:限流、降级、缓存 限流算法: 漏桶算法(Leaky Bucket)概念:请求从漏桶的入口处流入到漏桶中,漏桶以一定的速率将请求从出口处流出,当漏桶已满时(请求的流入速度大...
A__17 ⋅ 今天 ⋅ 0
之前一直因为:反复讨论系统方案最终定下来的策略在实施时具体情况跟一开始想的并不一样,而导致对系统设计并不是很在意。但经过实践发现,系统设计是非常必需的,因为分析得很清楚会带来很多...
Mediv ⋅ 昨天 ⋅ 0
linux的命令操作 1、日常操作命令 **查看当前所在的工作目录 pwd **查看当前系统的时间 date **查看有谁在线(哪些人登陆到了服务器) who 查看当前在线 last 查看最近的登陆历史记录 **清理...
em_aaron ⋅ 昨天 ⋅ 0
没有更多内容
加载失败,请刷新页面
加载更多以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Elasticsearch 集群搭建和集群原理
- Zookeeper学习系列【二】Zookeeper 集群章节之集群搭建
- Spark集群环境搭建
- Zookeeper搭建集群
- FastDFS集群搭建
- Zookeeper集群环境搭建
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JS 压缩/解压工具
在线压缩/解压 JS 代码
HTML 编码/解码
HTML 编码/解码