本文转载于:https://www.itsvse.com/thread-4636-1-1.html;

参考文献:http://www.likecs.com/show-29874.html;https://stackoverflow.com/questions/41279186/guaranteed-publishing-of-messages-on-rabbitmq-on-network-loss;

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

下图是生产者发送消息,我手动停止了rabbitmq,然后又重新启动了rabbitmq,大概等启动成功以后,为了防止服务没有完全启动,我又等待了10秒钟

服务完全启动成功以后,我尝试重新发送一些消息,报错,如下:

************** 异常文本 **************
RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=320, text="CONNECTION_FORCED - broker forced connection closure with reason 'shutdown'", classId=0, methodId=0, cause=
   在 RabbitMQ.Client.Impl.SessionBase.Transmit(Command cmd)
   在 RabbitMQ.Client.Impl.ModelBase.ModelSend(MethodBase method, ContentHeaderBase header, Byte[] body)
   在 RabbitMQ.Client.Impl.ModelBase.BasicPublish(String exchange, String routingKey, Boolean mandatory, IBasicProperties basicProperties, Byte[] body)
   在 RabbitMQ.Client.Impl.ModelBase.BasicPublish(String exchange, String routingKey, IBasicProperties basicProperties, Byte[] body)
   在 rabbitMQ_Publish.Form1.button1_Click(Object sender, EventArgs e) 位置 C:\project\my\RabbitMQ-demo\rabbitMQ-Publish\Form1.cs:行号 37
   在 System.Windows.Forms.Control.OnClick(EventArgs e)
   在 System.Windows.Forms.Button.OnClick(EventArgs e)
   在 System.Windows.Forms.Button.PerformClick()
   在 System.Windows.Forms.Form.ProcessDialogKey(Keys keyData)
   在 System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
   在 System.Windows.Forms.Control.PreProcessMessage(Message& msg)
   在 System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
   在 System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)

<ignore_js_op>

那么如何会异常恢复呢?或者说断线重连呢?

RabbitMQ NET Client的源码,研究发现一种自动的错误恢复机制 AutomaticRecoveryEnabled = true 使用方式如下

  1. var factory = new ConnectionFactory() { HostName = "localhost", AutomaticRecoveryEnabled = true };

复制代码

具体的恢复机制如下

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

  1. public void init()
  2. {
  3. m_delegate = new Connection(m_factory, false, m_factory.CreateFrameHandler());
  4. AutorecoveringConnection self = this;
  5. EventHandler<ShutdownEventArgs> recoveryListener = (_, args) =>
  6. {
  7. lock (recoveryLockTarget)
  8. {
  9. if (ShouldTriggerConnectionRecovery(args))
  10. {
  11. try
  12. {
  13. self.BeginAutomaticRecovery();
  14. }
  15. catch (Exception e)
  16. {
  17. // TODO: logging
  18. Console.WriteLine("BeginAutomaticRecovery() failed: {0}", e);
  19. }
  20. }
  21. }
  22. };
  23. lock (m_eventLock)
  24. {
  25. ConnectionShutdown += recoveryListener;
  26. if (!m_recordedShutdownEventHandlers.Contains(recoveryListener))
  27. {
  28. m_recordedShutdownEventHandlers.Add(recoveryListener);
  29. }
  30. }
  31. }

复制代码

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

  1. protected void PerformAutomaticRecovery()
  2. {
  3. lock (recoveryLockTarget)
  4. {
  5. RecoverConnectionDelegate();
  6. RecoverConnectionShutdownHandlers();
  7. RecoverConnectionBlockedHandlers();
  8. RecoverConnectionUnblockedHandlers();
  9. RecoverModels();
  10. if (m_factory.TopologyRecoveryEnabled)
  11. {
  12. RecoverEntities();
  13. RecoverConsumers();
  14. }
  15. RunRecoveryEventHandlers();
  16. }
  17. }

复制代码

这个方法中调用的是

  1. protected void RecoverConnectionDelegate()
  2. {
  3. bool recovering = true;
  4. while (recovering)
  5. {
  6. try
  7. {
  8. m_delegate = new Connection(m_factory, false, m_factory.CreateFrameHandler());
  9. recovering = false;
  10. }
  11. catch (Exception)
  12. {
  13. // TODO: exponential back-off
  14. Thread.Sleep(m_factory.NetworkRecoveryInterval);
  15. // TODO: provide a way to handle these exceptions
  16. }
  17. }
  18. }

复制代码

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

RabbitMQ---8、连接断开处理-断线重连的更多相关文章

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

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

  2. nodejs使用MYSQL连接池,断线重连

    两种方式解决1.你可以配置mysql的连接池 var mysql = require('mysql'); var pool = mysql.createPool({ host: 'localhost' ...

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

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

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

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

  5. Netty(六):Netty中的连接管理(心跳机制和定时断线重连)

    何为心跳 顾名思义, 所谓心跳, 即在TCP长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性. 为什么需要心跳 因为网络的不可靠性, 有可 ...

  6. 【问题记录】—SignalR连接断线重连

    起因: ASP.NET Core SignalR是一个开源库,可简化向应用添加实时 SignalR Web 功能. 实时 Web 功能使服务器端代码能够立即将内容推送到客户端.(相信大家都用得比较多了 ...

  7. Android基于XMPP Smack Openfire下学习开发IM(五)连接断开重连

    学习过程中大家都碰到过连接被断开的问题给困扰吧,下面教大家如何做到连接断开后,重新连接 首先要创建连接监听器,用来监听连接状态,这里我写了一个类 继承了ConnectionListener,重写了里面 ...

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

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

  9. netty4 断线重连

    转载:http://www.tuicool.com/articles/B7RzMbY 一 实现心跳检测 原理:当服务端每隔一段时间就会向客户端发送心跳包,客户端收到心跳包后同样也会回一个心跳包给服务端 ...

随机推荐

  1. 4-C#格式处理

    本篇博客对应视频讲解 前言 前几篇文章及对应视频是带大家快速体验了一下C#,了解编程语言最基础的内容及面向对象的概念. 接下来我会进一步演示和说明C#还能做些什么. 实际上,C#就一门语言来讲,除去面 ...

  2. RabbitMq初探——消息确认

    消息确认机制 前言 消息队列的下游,业务逻辑可能复杂,处理任务可能花费很长时间.若在一条消息到达它的下游,任务刚处理了一半,由于不确定因素,下游的任务处理进程 被kill掉啦,导致任务无法执行完成.而 ...

  3. cnVCL的安装

    cnVCL是cnpack组件中的不可视组件库,里面包含很多有用的组件,网址:http://www.cnpack.org/showdetail.php?id=739&lang=zh-cn 安装步 ...

  4. “全栈2019”Java第一百一十三章:什么是回调?回调应用场景详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. Spring中 使用注解+c3p0+事物 《模拟银行转账》

    使用注解的方式  模拟转账 要么都成功 要么都失败 !保持一致性! 准备工作: jar包:  需要的类:       UserDao: package com.hxzy.spring.c3p0.Dao ...

  6. [Objective-C语言教程]数据封装(27)

    所有Objective-C程序都由以下两个基本要素组成 - 程序语句(代码) - 这是执行操作的程序的一部分,它们被称为方法(函数). 程序数据 - 数据是受程序功能影响的程序信息. 封装是一种面向对 ...

  7. HTML实例(四)

    实例一:有序列表,无序列表,<dl>,<dt>,<dd>,div块级标签等,实现上面的效果. <!DOCTYPE html> <html lang ...

  8. Modbus通用数据读取工具设计及使用

    一.公共功能码定义 二.能读取的数据类型 1.bit类型,比如01功能码,读到的就是位的状态,是ON 还是OFF,也就是对应着0或1. 2.byte类型,比如03功能码. 3.short类型,比如03 ...

  9. 【性能测试】jmeter的坑(1)——如何在多网卡情况下正确连接

    问题现象: 性能测试时,使用的服务器配置了双网卡,windows客户机配置了四网卡,坑爹的配置,内外网的隔离,导致在使用jmeter进行分布式测试的时候总是连接失败. 原因分析: Jmeter采用了r ...

  10. Oracle ltrim() rtrim() 函数详细用法

    今天在论坛里看了一篇帖子,讨论ltrim() 函数的详细用法,下面我借几个高手的回答总结一下: 先看几个实例: SQL> select ltrim('109224323','109') from ...