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. java学习第10天 (增加关于eclipse添项目)

    自己遇到一个问题..觉得有必要说下,就是如何将别人发给你的文件也就是项目如何导入到你的eclipse中,不是直接add那么简单,首先右键找到import,找到general,展开找到existing ...

  2. 3D图形学常用公式

    本篇内容来自于书籍<3D图形学基础:图形与游戏开发>,个人总结 1.数学背景与历史 笛卡尔数学由著名的法国哲学家.物理学家.生物学家.数学家"勒奈·笛卡尔"发明. 1. ...

  3. DEBUG STACK TRACE for PoolBackedDataSource.close().

    我使用generator生成的代码,xml里面的内容没有覆盖重写,而是在下面直接追加,所以需要把以前的全部删除,然后在用generator生成.如果这个不能解决问题,就查查别人的问题.

  4. KMP算法简明扼要的理解

    KMP算法也算是相当经典,但是对于初学者来说确实有点绕,大学时候弄明白过后来几年不看又忘记了,然后再弄明白过了两年又忘记了,好在之前理解到了关键点,看了一遍马上又能理解上来.关于这个算法的详解网上文章 ...

  5. markdown 的基本操作

    文档 http://mux.alimama.com/posts/620?spm=0.0.0.0.4VVnvp http://www.jianshu.com/p/1e402922ee32/ MdChar ...

  6. VC++ MFC 按钮的全部样式Style

    Button Styles BS_3STATE 与复选框一样本样式按钮可被单击变暗.变暗状态通常用于指示本样式的按键正处于禁用状态. BS_AUTO3STATE   与三状态的复选框一样当用户选中它本 ...

  7. oracle job草稿

    sa -- 声明job DECLARE job2014_12_16 NUMBER; BEGIN DBMS_JOB.SUBMIT(job2014_12_16, -- 这个参数是out类型 'syncv5 ...

  8. Tomcat启动过程中找不到JAVA_HOME解决方法

    在XP上明明已经安装了JDK1.5并设置好了JAVA_HOME,可偏偏Tomcat在启动过程中找不到. 报错信息如下:Neither the JAVA_HOME nor the JRE_HOME en ...

  9. wcf session开启

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] pu ...

  10. 解决winrar压缩软件弹出广告

    最近winrar每次打开压缩包就会弹出一个广告,那是因为winrar是收费软件,注册了就没有广告了.下面我教大家怎么注册来屏蔽广告. 解决方法 1.新建一个txt文件并命名为"rarreg. ...