起因:在实际项目开发过程中,需要使用RabbitMQ来实现消息队列的功能,但仅仅实现功能之后并不能对自己满足,既然学一次,就要更深的了解她,吃一吃架构方面的相关内容,提升自己。
RabbitMQ在镜像集群中,机器其实是平行关系,所有的节点都是互相复制的
场景描述:
A是Master
B是Slave
A正常运行,B宕机了,只需要启动B即可,B就会自动加入集群
A和B都宕机了,只要A在B之前启动就可以了
A和B都宕机了,A启动不起来了,即便是B启动了,有可以B直接启动不了啦
B和C都加入了A为Master的集群,这个时候都需要将B和C从A的集群中forget,B和C启动不起来了
RabbitMQv32版本以后提供了一个离线清除集群节点的命令参数,也就是节点无法启动状态下
HAProxy是一款提供高可用的负载均衡器(之前大家都是使用的Nginx居多,upstream反向代理实现负载均衡非常容易),HAProxy可以基于TCP四层(Lvs也是TCP四层的),>ThingsBoard设计为:
扩展性:可水平扩展的平台使用领先的开源技术构建。
容错性:没有单点故障集群中的每个节点都是相同的。
健壮性:单个服务器节点可以根据使用情况处理以万级别的设备,集群可以处理数百万级别设备。
自定义:使用可自定义的部件和规则引擎节点可以轻松添加新功能。
持久化:永远不会丢失你的数据。
参见如下架构图及关键组件和相关接口。
通信
ThingsBoard提供了基于MQTT、>前提:比如两个节点A和B组成一个镜像队列
场景1: A先停, B后停
方案1: 该场景下B是Master,只要先启动B,再启动A即可。或者先启动A,再30秒之内启动B接口恢复镜像队列
场景2: A、B同时停机
方案2:该场景可能由于机房断电等原因造成的,只需在30秒之内连续启动A和B即可恢复镜像
场景3:A先停,B后停,且A无法恢复
方案3: 该场景是1场景的加强版,因为B是Master,所以等B起来以后,在B节点调用控制台命令: rabbitmqctl forget_cluster_node A 解除与A的Cluster关系,再将新的Slave节点加入B即可重新恢复镜像队列
场景4: A先停,B后停,且B无法恢复
方案4:该场景是场景3的加强版,比较难处理,原因是因为Master节点无法恢复,早在31x时代之前没有什么好的解决方案,但是现在已经有解决方案了,在342以后的版本。因为B是主节点,所有直接启动A是不行的,当A无法启动的时候,也就没办法在A节点上调用之前的 rabbitmqctl forget_cluster_node B 命令了。新版本中 forget_cluster_node 支持--offline参数
这就意味着允许rabbitmqctl在理想节点上执行该命令,迫使RabbitMQ在未启动Slave节点中选择一个节点作为Master。当在A节点执行 rabbitmqctl forget_cluster_node --offline B 时,RabbitMQ会mock一个节点代表A,执行 forget_cluster_node 命令将B剔除cluster,然后A就可以正常的启动了,最后将新的Slave节点加入A即可恢复镜像队列
场景5:A先停、B后停,且A、B均无法恢复,但是能得到A或B的磁盘文件
方案5:这种场景更加难处理,只能通过恢复数据的方式去尝试恢复,将A与B的数据文件模式在$RABBIT_HOME/var/lib/目录中,把它拷贝到新的节点对应的mulxia,再将新的节点hostname改成A或B的hostname,如果是A节点(Slave)的磁盘文件,则按照场景4处理即可,如果是B节点(Master)的磁盘文件,则按照场景3处理即可,最后新的Slave加入新节点后完成恢复。
场景6:A先停、B后停,且A、B均无法恢复,且得不到A和B的磁盘文件
恩,你可以直接跑路了o(╯□╰)o
RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang 写成,因此也是继承了这些优点。
12、什么是AMQP
AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。它从生产者接收消息并递送给消费者,在这个过程中,根据规则进行路由,缓存与持久化。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如: Python 、Ruby、NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
13、RabbitMQ的基础概念
14、RabbitMQ的特性
21、环境:两台Ubuntu1604主机
1027053 rabbitmq-1
10270130 rabbitmq-2
必须保证各个主机名之间可以ping通
22、安装Erlang
23、安装rabbitmq
24、安装完成后,验证一下服务是否正常
搭建好的rabbitmq默认是没有配置文件的,需要我们来手动添加
Rabbitmq的一些运行脚本存放在 /usr/sbin 下面
25、开启web管理插件
251、创建一个用户nova,并设置密码为123456
252、查看现有用户表
这个时候nova用户是不能访问web管理插件的,需要配置用户角色,用户角色可分为五类,超级管理员, 监控者, 策略制定者, 普通管理者以及其他。
可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行 *** 作。
可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。但无法查看节点的相关信息。
仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。
无法登陆管理控制台,通常就是普通的生产者和消费者。
将nova添加到administrator用户组
此时的nova用户只能通过本地来登录其他的IP无法直接使用这个账号。所以需要对他进行授权,使用户nova /(可以访问虚拟主机) 中所有资源的配置、写、读权限以便管理其中的资源
查看用户授权
253、开启web管理插件并重启rabbitmq服务
以下为关闭插件命令
通过浏览器访问 [>现在的系统已经离不开消息队列,我们可以用他做异步,做解耦,做流处理,做可靠传输。市面上的消息队列也有很多,比如阿里云的oss,RocketMQ,ZeroMQ,RabbitMQ,Kafka等,甚至Java中的List也可以称为一个简单的消息队列,种类如此繁多,我们该如何选择呢?现在主流的消息队列可以分为两类,一类以kafka为代表,一类以RabbitMQ为代表,二者有很多相似的地方,也都有各自的优势。
那我们平时构建系统的时候,该选择哪种消息队列呢?这里我们将RbbitMQ与kafka做一下对比(因为他们都是spring默认集成的消息队列),以便于我们做出最优的选择。
RabbitMQ:关于rabbit的详细介绍这里不说,感兴趣的可以看我之前的文章,一句话rabbit作为传统意义上的消息队列,基于AMQP协议开发,倾向于做按各种规则的消息转发。
Kafka:关于kafka的详细介绍会在以后的文章里写,因为刚开始用,想深入了解后再写出来。kafka更倾向于一个流式管道的概念,消息从一处流向另一处,吞吐量比rabbit更高。
接下来通过俩张图来理解他俩的设计与区别。
首先来看rabbit,他通过broker来进行统一调配消息去向,生产者通过指定的规则将消息发送到broker,broker再按照规则发送给消费者进行消费,消费者方可以选择消费方式为pull或者是broker主动push,支持的消费模式也有多种,点对点,广播,正则匹配等。
Kafka主要为高吞吐量的订阅发布系统而设计,主要追求速度与持久化。kafka中的消息由键、值、时间戳组成,kafka不记录每个消息被谁使用,只通过偏移量记录哪些消息是未读的,kafka中可以指定消费组来实现订阅发布的功能。
了解了二者大体的区别以后,我们再来看具体的适用场景。
Kafka:
1从A系统到B系统的消息没有复杂的传递规则,并且具有较高的吞吐量要求。
2需要访问消息的历史记录的场景,因为kafak是持久化消息的,所以可以通过偏移量访问到那些已经被消费的消息(前提是磁盘空间足够,kafka没有将日志文件删除)
3流处理的场景。处理源源不断的流式消息,比较典型的是日志的例子,将系统中源源不断生成的日志发送到kafka中。
rabbit:
1需要对消息进行更加细粒度的控制,包括一些可靠性方面的特性,比如死信队列。
2需要多种消费模式(点对点,广播,订阅发布等)
3消息需要通过复杂的路由到消费者。
最后是关于性能方面,众所周知,kafka的吞吐量优于rabbit,大约是100k/sec,而rabbit大约是20k/sec,但是这个不应该成为我们选择的主要原因,因为性能方面的瓶颈都是可以通过集群方案来解决的。
最后要说的是,没有最好的队列,只有最合适的队列。
参考:Understanding When to use RabbitMQ or Apache Kafka消息总线屏蔽了消息发送、路由、分组、存储、消费负载、通信、高可用等一系列技术问题,对业务开发者来说只需要调用生产者或消费者SDK即可,简化了接入流程并提升了可靠性。
消息总线整体架构图如下图所示
为保证消息在整个流程中减少复杂度,将消息体设计为如下统一结构
通过前面的介绍,可以了解到生产者发送的消息在经过Broker(SKD)时进行了路由、分组,具体策略如下:
消息经过Broker默认会进入一个RealTime Queue的队列中,Deliver集群中会有多个Listener监听RealTime Queue,在Deliver服务内,通过Dispatcher来控制消息并发及总数,当某种消息的发送量超过阈值时,就会触发处罚策略,将消息转发到Async Queue中,避免消费Worker都被同一个类型的消息占用,而Async Queue会被独立的Deliver服务监听进行消费,不影响RealTime Queue的消费,如果投递失败则会进入Retry Queue,满足一定条件后将会继续投递
为了保证消费时的高可用,Deliever集群在负责进行消费协议转换之外,也做了一些策略来保证消费端的高可用
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)