在前面讲到了RabbitMQ高可用集群的搭建,但是我们知道只是集群的高可用并不能保证应用在使用消息队列时完全没有问题,例如如果应用连接的RabbitMQ集群突然宕机了,虽然这个集群时可以使用的,但是应用订阅的连接就断开了,如果有个机房外网出口带宽被挖掘机弄断了,那集群依然是不可用的。所以我们后面会介绍应用APP如何与连接集群来保证两者配合默契,以及如何实现跨机房的集群复制。

应用连接集群高可用

前面讲到应用服务器通过一个负载均衡服务将连接的流量分发到指定服务器,如果连接的节点宕机怎么办呢。应用服务器连接集群主要做两件事,订阅和发布,所以如果是发布消息每次都会重新初始化连接所以连接节点的切换对整个系统的可用性影响不大。如果是订阅消息就没有真么简单了。首先我们要做到如果连接出现问题应该是抛出异常而不是终止脚本,并且这时应该重新连接连接。 
好了不废话了,代码如下:

ColonyProduct

using System;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events; namespace ColonyProduct
{
class Program
{
static void Main(string[] args)
{
String exchangeName = "wytExchange";
String queueName = "wytQueue"; ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "192.168.63.130";
factory.Port = 5672;
factory.VirtualHost = "/wyt";
factory.UserName = "wyt";
factory.Password = "wyt"; using (IConnection connection=factory.CreateConnection())
{
using (IModel channel=connection.CreateModel())
{
channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null); channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: String.Empty, arguments: null); IBasicProperties properties = channel.CreateBasicProperties();
properties.Persistent = true; for (int i = 0; i < 10; i++)
{
Byte[] body = Encoding.UTF8.GetBytes("Hello World -- "+i); channel.BasicPublish(exchange: exchangeName, routingKey: String.Empty, basicProperties: properties, body: body);
}
}
} Console.WriteLine("发送完成");
Console.ReadKey();
}
}
}

ColonyConsumer

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text; namespace ColonyConsumer
{
class Program
{
static void Main(string[] args)
{
String exchangeName = "wytExchange";
String queueName = "wytQueue"; ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "192.168.63.133";
factory.Port = 5672;
factory.VirtualHost = "/wyt";
factory.UserName = "wyt";
factory.Password = "wyt"; using (IConnection connection=factory.CreateConnection())
{
using (IModel channel=connection.CreateModel())
{
channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null); channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: String.Empty, arguments: null); EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
var routingKey = ea.RoutingKey;
Console.WriteLine(" [x] Received '{0}':'{1}'", routingKey, message); channel.BasicAck(ea.DeliveryTag, multiple: false);
}; channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer); Console.WriteLine("等待接收消息");
Console.ReadKey();
}
}
}
}
}

所以通过以上的代码就可以保证服务器某节点宕机后订阅的连接自动重连切换。

RabbitMQ集群异地复制

基于warren的共享存储模式

这种方式其实并不是跨地区的远程复制,并且需要共享存储,如果感兴趣的同学可以百度下。

基于Shovel的远程复制

如果直接基于WAN来组建异地的集群的话,集群间大量的数据通讯会产生高昂的费用,另外Erlang也不允许这么高延迟的通讯。 
Shovel是RabbitMQ自带插件(2.7.0后),自带插件的好处就是可以在RabbitMQ服务启动时自动启动Shovel和自定义复制关系。 
Shovel运行的原理其实非常简单。通过定义RabbitMQ上一个队列和另外一个RabbitMQ上的交换机之间的复制关系来实现远程复制。也就是说它会在主服务上建立一个队列来监听交换机,所以这是到交换机所以的消息会投递到该队列,并且在从服务中订阅这个队列,使队列中的消息复制到从服务的交换机中。RabbitMQ是一个比较全面的消息队列解决方案,我们公司并没有用到该功能,只是在这提下,感兴趣的同学可以搜下。

RabbitMQ消息队列(十一)-如何实现高可用的更多相关文章

  1. RabbitMQ消息队列(十)-高可用集群部署实战

    前几章讲到RabbitMQ单主机模式的搭建和使用,我们在实际生产环境中出于对性能还有可用性的考虑会采用集群的模式来部署RabbitMQ. RabbitMQ集群基本概念 Rabbit模式大概分为以下三种 ...

  2. (十一)RabbitMQ消息队列-如何实现高可用

    原文:(十一)RabbitMQ消息队列-如何实现高可用 在前面讲到了RabbitMQ高可用集群的搭建,但是我们知道只是集群的高可用并不能保证应用在使用消息队列时完全没有问题,例如如果应用连接的Rabb ...

  3. (十)RabbitMQ消息队列-高可用集群部署实战

    原文:(十)RabbitMQ消息队列-高可用集群部署实战 前几章讲到RabbitMQ单主机模式的搭建和使用,我们在实际生产环境中出于对性能还有可用性的考虑会采用集群的模式来部署RabbitMQ. Ra ...

  4. RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列

    系列文章: RabbitMQ从零到集群高可用(.NetCore5.0) - RabbitMQ简介和六种工作模式详解 RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列 ...

  5. 使用EasyNetQ组件操作RabbitMQ消息队列服务

    RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现,是实现消息队列应用的一个中间件,消息队列中间件是分布式系统中重要的组件,主要解决应用耦合, ...

  6. RabbitMQ从零到集群高可用(.NetCore5.0) -高可用集群构建落地

    系列文章: RabbitMQ从零到集群高可用(.NetCore5.0) - RabbitMQ简介和六种工作模式详解 RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列 ...

  7. 基于ASP.NET Core 5.0使用RabbitMQ消息队列实现事件总线(EventBus)

    文章阅读请前先参考看一下 https://www.cnblogs.com/hudean/p/13858285.html 安装RabbitMQ消息队列软件与了解C#中如何使用RabbitMQ 和 htt ...

  8. RabbitMQ消息队列(一): Detailed Introduction 详细介绍

     http://blog.csdn.net/anzhsoft/article/details/19563091 RabbitMQ消息队列(一): Detailed Introduction 详细介绍 ...

  9. RabbitMQ消息队列1: Detailed Introduction 详细介绍

    1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有 ...

  10. RabbitMQ消息队列应用

    RabbitMQ消息队列应用 消息通信组件Net分布式系统的核心中间件之一,应用与系统高并发,各个组件之间解耦的依赖的场景.本框架采用消息队列中间件主要应用于两方面:一是解决部分高并发的业务处理:二是 ...

随机推荐

  1. js函数柯里化,实现bind

    1.柯里化: 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 举个栗子: 一个计算两数之和的函数,需要传递两个参数,柯里化 ...

  2. vue的登陆验证及返回登录前页面实现

    一.路由配置部分如下所示, 导出路由示例 let router = new VueRouter({ routes: [ // 登陆 { name: 'login', path: '/login', c ...

  3. python从入门到实践-9章类

    #!/user/bin/env python# -*- coding:utf-8 -*- # 类名采用的是驼峰命名法,即将类名中每个单词的首字母大写,而不使用下划线.# 对于每个类,都应紧跟在类定义后 ...

  4. web测试实践——day01

    一.任务进展情况 主要是找寻网站的bug,分析bug的严重程度.同时找了本专业的同学进行博客园系统的使用. 二.存在的问题 由于上线的网站做的比较完善,导致找寻bug比较困难. 三.解决方法 对此我们 ...

  5. 【mysql】must reset your password using ALTER USER statement before executing this statement

    问题描述: must reset your password using ALTER USER statement before executing this statement 登录centos服务 ...

  6. React Native 断点调试 跨域资源加载出错问题的原因分析

    写在前面 ————如果从头开始看还没解决,试试文章最后的绝招 闲来无事,折腾了一下React Native,相比之前,开发体验好了不少.但在真机断点调试那里遇到了跨域资源加载出错的问题,一番探索总算解 ...

  7. Mycat对MySQL进行垂直水平分表分库,读写分离

    1.   MyCAT概述 1.1 背景 随着传统的数据库技术日趋成熟.计算机网络技术的飞速发展和应用范围的扩充,数据库应用已经普遍建立于计算机网络之上.这时集中式数据库系统表现出它的不足: (1)集中 ...

  8. CountDownLatch使用场景

    正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.在Java并发中,countdownlatch的概念是一 ...

  9. 阿里面试题,深入理解Java类加载机制

    类的生命周期 包括以下 7 个阶段: 加载(Loading) 验证(Verification) 准备(Preparation) 解析(Resolution) 初始化(Initialization) 使 ...

  10. [Swift]LeetCode32. 最长有效括号 | Longest Valid Parentheses

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...