作者:don't | 来源:互联网 | 2022-12-29 16:43
rabbitMQ高可用+负载均衡
停掉rabbitmq1的keepalived,查看rabbitmq2的网络 漂移成功,再启动rabbitmq1的keepalived 回移成功 访问vip检查负载均衡,注意这里访问的是ip地址,而不是ip加端口号 停掉rabbitmq1的负载均衡,再次访问rabbitmq的web页面 访问失败,说明我们停掉了主的负载均衡,vip并没有飘移 这里是思路出了问题 原来以为haproxy+keepalived能自动解决健康检查,认为keepalived会在haproxy死掉的情况下自动漂移,但是并没有,因为没有做对haproxy健康状况的检测,keepalived甚至不会知道haproxy死了 然后再把rabbitmq的haproxy关掉,临时修改健康检查中的$start变量为 目的:测试haproxy起不来的情况下vip会不会漂移 再查看MQ2的ip 漂移成功,再次访问vip,得到正常显示rabbitmq的web页面 至此部署完成
RabbitMQ 镜像集群 宕机恢复、负载均衡、跨机房多活
起因:在实际项目开发过程中,需要使用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启动不起来了 RabbitMQv3.2版本以后提供了一个离线清除集群节点的命令参数,也就是节点无法启动状态下 HAProxy是一款提供高可用的负载均衡器(之前大家都是使用的Nginx居多,upstream反向代理实现负载均衡非常容易),HAProxy可以基于TCP四层(Lvs也是TCP四层的),HTTP七层(Nginx是HTTP七层)的负载均衡应用代理软件,免费高速可靠的一种LBS解决方案 HAProxy的并发连接完全可以支持以万为单位的 Nginx 优点: 1、工作在网络7层之上,可针对http应用做一些分流的策略,如针对域名、目录结构,它的正规规则比HAProxy更为强大和灵活,所以,目前为止广泛流行。
2、Nginx对网络稳定性的依赖非常小,理论上能ping通就能进行负载功能。
3、Nginx安装与配置比较简单,测试也比较方便,基本能把错误日志打印出来。 4、可以承担高负载压力且稳定,硬件不差的情况下一般能支撑几万次的并发量。 5、Nginx可以通过端口检测到服务器内部的故障,如根据服务器处理网页返回的状态码、超时等,并会把返回错误的请求重新提交到另一个节点。 6、不仅仅是优秀的负载均衡器/反向代理软件,同时也是强大的Web应用服务器。
可作为静态网页和图片服务器,在高流量环境中稳定性也很好。 7、可作为中层反向代理使用。 缺点: 1、适应范围较小,仅能支持http、https、Email协议。
2、对后端服务器的健康检查,只支持通过端口检测,不支持url来检测 3、负载均衡策略比较少:轮询、权重、IP_hash、url_hash HAProxy 优点: 1、HAProxy是支持虚拟主机的,可以工作在4、7层(支持多网段) 2、HAProxy的优点能够补充Nginx的一些缺点,比如支持Session的保持,COOKIE的引导;同时支持通过获取指定的url来检测后端服务器的状态。 3、HAProxy跟LVS类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。 4、HAProxy支持TCP协议的负载均衡转发,可以对MySQL读进行负载均衡,对后端的MySQL节点进行检测和负载均衡。
5、HAProxy负载均衡策略非常多,HAProxy的负载均衡算法现在具体有如下8种 缺点: 1、不支持POP/SMTP协议 2、不支持SPDY协议 3、不支持HTTP cache功能。现在不少开源的lb项目,都或多或少具备HTTP cache功能。 4、重载配置的功能需要重启进程,虽然也是soft restart,但没有Nginx的reaload更为平滑和友好。
rabbitmq 有了镜像队列 为什么还要有负载均衡
当部署了两台以上的服务器时,就可能会需要用到负载均衡器。通过服务器负均衡器,对流量进行合理分配,可以带来以下好处:1.负载均衡器优化了访问请求在服务器组之间的分配,消除了服务器之间的负载不平衡,从而提高了系统的反应速度与总体性能;2.负载均衡器可以对服务器的运行状况进行监控,及时发现运行异常的服务器,并将访问请求转移到其它可以正常工作的服务器上,从而提高服务器组的可靠性采用了负均衡器器以后,可以根据业务量的发展情况灵活增加服务器,系统的扩展能力得到提高,同时简化了管理。
RocketMQ消费者消息队列负载均衡
先从整体流程上简单梳理一下消息队列负载的过程。 消息队列负载由Rebalance线程默认每隔20s进行一次消息队列负载,获取主题队列信息mqSet与消费组当前所有消费者cidAll,然后按照某一种负载算法进行队列分配,分配原则为同一个消费者可以分配多个消息消息队列,同一个消息消费队列同一时间只会分配给一个消费者。
此时,可以计算当前消费者分配到消息队列集合,对比原先的负载队列与当前的分配队列。
如果新队列集合中不包含原来的队列,则停止原先队列消息消费并移除,如果原先队列中不包含新分配队列则创建PullRequest。 进行负载均衡是在RebalanceService线程中启动的,一个MQClientInstance持有一个RebalanceService实现,并随着MQClientInstance的启动而启动。 从上面可以看出,MQClientinstance遍历已注册的消费者,对消费者执行doRebalance方法。 上面是遍历订阅信息对每个主题的队列进行重新负载。
接下来将执行 rebalanceByTopic 方法,会根据广播模式或集群模式分别采用不同的方法进行处理。在此处,只解释集群模式下的方法。 获取该主题下的队列信息和该消费组内当前所有的消费者ID。
每个DefaultMQPushConsumerImpl都持有一个单独的RebalanceImpl对象。 对该主题下的队列信息和该消费组内当前所有的消费者ID进行排序,确保一个消费组的成员看到的顺序是一致的,防止同一个消费队列不会被多个消费者分配。 allocateResult 记录的是当前消费者的所分配的消息队列 调用 updateProcessQueueTableInRebalance 对比消息队列是否发生变化 从上面看, processQueueTable 记录的是当前消费者负载的消息队列缓存表,该方法里面的 mqSet 记录的的是当前消费者经过负载分配后的消息队列集合。
如果 processQueueTable 中的消息队列在 mqSet 中不存在,说明该消息队列已经被分配给其他消费者,所以需要暂停该消息队列消息的消费,通过** pq.setDropped(true); 该语句即可。 然后通过 removeUnnecessaryMessageQueue**方法判断是否该mq从缓存中移除。 之后,开始遍历本次负载分配给该消费者的消息队列结合mqSet。
如果processQueueTable中没有包含该消息队列,表示这是本次新增加的消息队列。 首先从内存中移除该消息队列的消息进度,然后调用 computePullFromWhere 从磁盘中读取该消息队列的消费进度,创建一个PullRequest对象。 从上面看出,主要有三种计算消息进度的方法,有些大同小异。 首先从磁盘中获取该消息队列的消费进度,如果大于0,说明该消息队列已经被消费过了,下次消费从该位置继续消费。
如果等于-1,尝试去操作消息存储时间戳作为消费者启动的时间戳,如果能找到则返回找到的偏移量,找不到则返回0;如果小于-1,则说明该消息进度文件中存储了错误的偏移量,返回-1。 在该方法的最后,会调用 dispatchPullRequest 方法,将PullRequest加入到PullMessageService中,以唤醒PullMessageService线程,进行消息拉取。 到这里,消费者负载均衡方面就结束了。
一文带你了解RabbitMQ到底是个什么鬼!
MQ全程为message queue,即消息队列。是一种跨进程、异步通信机制、用于上下游传递消息。
RabbitMQ是由Erlang语言开发,基于 AMQP 协议(Advanced Message Queuing Protocol 高级消息队列协议)实现的消息队列,它是一种应用程序之间的通信方法,消息队列在实际开发应用中有着非常广泛的使用。
下面主要介绍RabbitMQ的基础、架构以及在开发过程中遇到的一些常用问题,还有在面试过程中一些长问的问题。 RabbitMQ官网 : https://www.rabbitmq.com 2007年Rabbit公司基于AMQP标准协议开发的RabbitMQ1.0发布。AMQP的主要特性是面向消息、队列、路由、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性有着很高的要求场景,对性能和吞吐量的要求在其次。
RabbitMQ基础架构如下图: 来介绍下上图中一些名词相关的概念: RabbitMQ内置了几种常用的exchange,包含direct、topic、fanout、headers,下面主要介绍几种常用的exchange类型。 直连交换机,完全匹配路由key,所有发送到direct exchange的消息会被转发到routeKey中指定的queue中。消息传递时,routeKey必须要完全匹配才会被队列接手,否则消息会被抛弃。
主题交换机,根据匹配路由规则来分发消息, # 匹配一个或多个词, * 匹配不多不少一个词。比如“log.#”能够匹配到“log.info.test”,“log.*”能够匹配到“log.err”。 广播交换机,不处理路由,只需要将队列绑定到交换机上,发送到交换机的消息会被转发到与该交换机绑定的所有的队列上。
RabbitMQ提供了三种模式,分别为单机模式、普通集群模式、镜像集群模式,下面分别介绍下这三种模式。 这个就是demo级别的,即单机情况不做集群,一般也就是你本地启动玩玩写写测试用的,没有人在生产用这种模式的。 多台机器上启动多个RabbitMQ实例,以两个节点(node-1,node-2)为例来进行说明。
对于queue来说,消息实体只存在于其中一个节点node-1或者node-2,node-1和node-2两个节点仅有相同的元数据(即队列相关的结构)。当消息进入node-1后,consumer从node-2节点消费时,RabbitMQ会临时在node-1、node-2间进行消息传输,把A中的消息取出来并经过B在发送给consumer,所以consumer以ing改尽量连接每一个节点,从中获取消息。负责无论consumer连接node-1或者node-2,出口总在node-1,会产生瓶颈,如果当node-1节点故障后,node-2无法获取node-1的消息。如果做了持久化,那么必须要等到node-1恢复后,才能继续消费,如果消息没有做持久化,就会出小消息丢失的情况。
一般配合HAProxy配置为高可用集群,把需要的队列做成镜像队列,存在与多个节点属于 RabbitMQ的HA方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
完成镜像队列设置之后,每各队列会被复制到各个节点,各个节点状态保持一致。因为 RabbitMQ本身不提供负载均衡,需要搭建负载均衡器来提供负载转发,可以选择HAProxy 和Nginx。 采用 AMQP 高级消息队列协议的一种消息队列技术,最大的特点就是消费并不需要确保提供方存在,实现了服务之间的高度解耦。 消息持久化,当然前提是队列必须持久化。
在消息生产时,MQ内部针对每条生产者发送的消息生成一个 inner-msg-id ,作为去重的依据(消息投递失败并重传),避免重复的消息进入队列;在消息消费时,要求消息体中必须要有一个 bizId (对于同一业务全局唯一,如支付 ID、订单 ID、帖子 ID 等)作为去重的依据,避免同一条消息被重复消费。 将信道设置成 confirm 模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的ID。 一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一 ID)。
如果RabbitMQ发生内部错误从而导致消息丢失,会发送一条 nack(notacknowledged,未确认)消息。 发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息。
消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)。只有消费者确认了消息,RabbitMQ才能安全地把消息从队列中删除。 这里并没有用到超时机制,RabbitMQ仅通过Consumer的连接中断来确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMQ给了Consumer足够长的时间来处理消息。
保证数据的最终一致性; 下面列举几种特殊情况: 所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,最好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了10倍。但是关键时刻,用,还是得用的。