Rabbitmq 官方给的NET consumer示例代码如下,但使用过程,会遇到connection断开的问题,一旦断开,这个代码就会报错,如果你的消费者端是这样的代码的话,就会导致消费者挂掉。

using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text; class ReceiveLogs
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare("logs", "fanout"); var queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queueName, "logs", "");
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(queueName, true, consumer); Console.WriteLine(" [*] Waiting for logs." +
"To exit press CTRL+C");
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] {0}", message);
}
}
}
}
}

那么如何会异常恢复呢?

之前我的操作方式是,建立一个ConnectionPool,在出现异常后,重建channel,也就是说,整个的异常恢复过程是自己处理的。最近研究因为研究Orleans,担心RabbitMQ的NET client使用Task时,会遇到Orleans的坑,所以顺手研究了下RabbitMQ NET Client的源码,研究发现一种自动的错误恢复机制 AutomaticRecoveryEnabled = true 使用方式如下

using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text; class ReceiveLogs
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost", AutomaticRecoveryEnabled = true };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare("logs", "fanout"); var queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queueName, "logs", "");
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(queueName, true, consumer); Console.WriteLine(" [*] Waiting for logs." +
"To exit press CTRL+C");
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] {0}", message);
}
}
}
}
}

具体的恢复机制如下

1.在AutoRecoveringConnection初始化时,在链接关闭事件委托上增加断开处理

public void init()
{
m_delegate = new Connection(m_factory, false, m_factory.CreateFrameHandler()); AutorecoveringConnection self = this;
EventHandler<ShutdownEventArgs> recoveryListener = (_, args) =>
{
lock (recoveryLockTarget)
{
if (ShouldTriggerConnectionRecovery(args))
{
try
{
self.BeginAutomaticRecovery();
}
catch (Exception e)
{
// TODO: logging
Console.WriteLine("BeginAutomaticRecovery() failed: {0}", e);
}
}
}
};
lock (m_eventLock)
{
ConnectionShutdown += recoveryListener;
if (!m_recordedShutdownEventHandlers.Contains(recoveryListener))
{
m_recordedShutdownEventHandlers.Add(recoveryListener);
}
}
}

观察调用的方式BeginAutomaticRecovery,可以看到这个方法内部调用了PerformAutomaticRecovery方法。我们直接看这个方法的内容,其中第一个调用的是方法RecoverConnectionDelegate

protected void PerformAutomaticRecovery()
{
lock (recoveryLockTarget)
{
RecoverConnectionDelegate();
RecoverConnectionShutdownHandlers();
RecoverConnectionBlockedHandlers();
RecoverConnectionUnblockedHandlers(); RecoverModels();
if (m_factory.TopologyRecoveryEnabled)
{
RecoverEntities();
RecoverConsumers();
} RunRecoveryEventHandlers();
}
}

这个方法中调用的是

protected void RecoverConnectionDelegate()
{
bool recovering = true;
while (recovering)
{
try
{
m_delegate = new Connection(m_factory, false, m_factory.CreateFrameHandler());
recovering = false;
}
catch (Exception)
{
// TODO: exponential back-off
Thread.Sleep(m_factory.NetworkRecoveryInterval);
// TODO: provide a way to handle these exceptions
}
}
}

可以看出,它是执行了死循环,直到连接重新打开,当然,如果遇到异常,它会调用Thread.Sleep来等待一下,然后再次执行连接恢复。

RabbitMQ 连接断开处理-自动恢复的更多相关文章

  1. Spring-Data-Redis 下实现jedis连接断开后自动重连

    原先使用jedis的时候,处理手段是在从连接池获取连接时捕获JedisConnectionException异常,在异常处理部分重新获取连接,但是spring data redis似乎不会,如下所示: ...

  2. .net/c# RabbitMQ 连接断开处理-断线重连(转载)

    Rabbitmq 官方给的NET consumer示例代码如下,但使用过程,会遇到connection断开的问题,一旦断开,这个代码就会报错,就会导致消费者或者生产者挂掉. 下图是生产者发送消息,我手 ...

  3. RabbitMQ连接池、生产者、消费者实例

    1.本文分享RabbitMQ的工具类,经过实际项目长期测试,在此分享给发家,各位大神有什么建议请指正 !!! 2.下面是链接池主要代码: import java.util.HashMap; impor ...

  4. htc M8 无法自动恢复数据连接(4g)的问题解决

    情况如下:htc m8 tdd-lte的双待手机,4g.2g同时在线. 本月出现,在短时间没有信号的情况后,无法恢复数据连接,哪怕是edge,更不论4g了. 尝试各种方法无解.最后咨询10086解决此 ...

  5. 【RMAN】TSPITR--RMAN表空间基于时间点的自动恢复

    [RMAN]TSPITR--RMAN表空间基于时间点的自动恢复 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其 ...

  6. tmux会话断电保存自动恢复

    tmux可以用于会话管理,通过建立session,可以保证当前设备和服务期断开连接之后,会话中的指令继续运行,非常适合用于执行需要长时间运行的任务. 但是tmux也有一个问题,那就是session在服 ...

  7. socket 如何判断远端服务器的连接状态?连接断开,需重连

    fluent-logger-java is a Java library, to record events via Fluentd, from Java application. https://g ...

  8. zookeeper 大量连接断开重连原因排查

    转自:http://blog.csdn.net/hengyunabc/article/details/41450003?utm_source=tuicool&utm_medium=referr ...

  9. [办公自动化]计算机突然死机后asd自动恢复文档未能恢复,如何打开使用

    今天计算机突然死机,但是word未能提示自动恢复窗格.所以无法自动恢复word文档.但是在文档所在的文件夹看到了一个“自动恢复”开头的asd恢复文档. 该如何使用这个文档呢? 按照以前的惯例,尝试了如 ...

随机推荐

  1. PYTHON入门知识

    基本数据类型 注:查看对象相关成员 var,type,dir 一.整数 如: 18.73.84 每一个整数都具备如下功能: class int(object): """ ...

  2. Egret 摇一摇功能

    一  什么是重力感应 二 什么是陀螺仪 三 Egret中的摇一摇是利用什么原理实现的 四 摇一摇代码 一 什么是重力感应 二 什么是陀螺仪 三 Egret中的摇一摇是利用什么原理实现的 大概是利用手机 ...

  3. gulp-htmlmin压缩html

    通过一条命令用Npm安装gulp-htmlmin: npm install gulp-htmlmin --save-dev 安装完毕后,打开gulpfile.js文件,我们里面编写一个task用来专门 ...

  4. <img>标签

    <img src="w3school.jpg" width="104" height="142" />注释:图像的名称和尺寸是以 ...

  5. 数据库记录转换成json格式 (2011-03-13 19:48:37) (转)

    http://blog.sina.com.cn/s/blog_621768f30100r6v7.html 数据库记录转换成json格式 (2011-03-13 19:48:37) 转载▼ 标签: 杂谈 ...

  6. java线程的理解

    java thread类都是native方法实现的,所以没有用平台无关的方法实现,怎么实现的呢? 线程的实现: 第一种:使用内核线程实现. 内核线程就是直接使用操作系统内核支持的线程,由内核完成切换. ...

  7. 《机器学习实战》学习笔记——第14章 利用SVD简化数据

    一. SVD 1. 基本概念: (1)定义:提取信息的方法:奇异值分解Singular Value Decomposition(SVD) (2)优点:简化数据, 去除噪声,提高算法的结果 (3)缺点: ...

  8. [转] linux虚拟带库操作笔记

    原文来自:“王旺的书房” ---- http://blog.itpub.net/271063/viewspace-1059840/ 分类: Linux 查看设备[root@node1 ~]# lssc ...

  9. iOS AFNetworking “Request failed: unacceptable content-type: text/html”问题

    使用AFNetworking出现报错: error=Error Domain=com.alamofire.error.serialization.response Code=-1016 "R ...

  10. grep 相关

    1) -q 参数,本意是 Quiet; do not write anything to standard output.  Exit immediately with zero status if ...