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)

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

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来等待一下,然后再次执行连接恢复。

转载自: https://www.itsvse.com/thread-4636-1-1.html

.net/c# RabbitMQ 连接断开处理-断线重连(转载)的更多相关文章

  1. RabbitMQ---8、连接断开处理-断线重连

    本文转载于:https://www.itsvse.com/thread-4636-1-1.html: 参考文献:http://www.likecs.com/show-29874.html:https: ...

  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. RabbitMQ 连接断开处理-自动恢复

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

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

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

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

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

  7. 我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比(转载)

    转载自:https://www.sojson.com/blog/48.html 前言: MQ 是什么?队列是什么,MQ 我们可以理解为消息队列,队列我们可以理解为管道.以管道的方式做消息传递. 场景: ...

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

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

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

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

随机推荐

  1. DDR SDRAM芯片DQS的作用以及读写DQS/DQ对齐方式不同的原因

    节选内容转载自https://www.design-reuse.com/articles/13805/the-love-hate-relationship-with-ddr-sdram-control ...

  2. 判断大小端的方法(java和c++)

    首先我们给出大小端的定义: 小端:较高的有效字节存放在较高的的存储器地址,较低的有效字节存放在较低的存储器地址. 大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址. 将 ...

  3. Mysql数据库事务及隔离级别学习测试

    参考了这篇文章的一些内容: http://xm-king.iteye.com/blog/770721 记住以下这张表: 我在springdemo库里面建了一个表: CREATE TABLE `tx` ...

  4. iOS开发-音乐播放

    现在的各种App大行其道,其实常用也就是围绕着吃喝玩乐基本的需求,视频,音乐在智能手机出现之前更是必不可少的功能,每个手机都会有一个自带的音乐播放器,当然公众也有自己的需求所以也就造就了各种音乐播放软 ...

  5. 搭建个人博客-hexo+github

    自己也算是摸爬滚打搭建成功,然后自己再重新安装部署一遍,把完整步骤分享给大家,同时最后有一些连接,如果我的步骤不行,大家可以参考其他人的(这个有点花费时间,大家提前有个心理准备 - _-) 一.第一步 ...

  6. [LeetCode] Distinct Subsequences [29]

    题目 Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequen ...

  7. Java之对象构造过程

    先来运行一段代码 class A { public A() { init(); } public void init() { } public static void main(String[] ar ...

  8. 【statistics】查看2018.4.25日理想论坛某ID在一天中的活跃情况

    用于统计的sum.py代码: import re import pymysql # 入口函数 def main(): dic={'00':0,'01':0,'02':0,'03':0,'04':0,' ...

  9. MYSQL 表中汉字写入或字段赋值时乱码情况排误

    -- 当改动字段值.或是直接写入时,汉字变成乱码情况 .[可注意一下数据库名,记得改动] -- 当字符顺序对汉字不兼容时,可能直接导致乱码情况发生. 最好做到库.表.字段(字符类型)排序规则是否一致 ...

  10. PHP 自学之路-----XML编程(Dom技术)

    上一节,讲了Xml文件基本语法及元素,实体及Dtd约束技术,下面就正式进入PHP的Xml编程 使用PHP技术对Xml文件进行操作 常用的有以下三种技术: 1.PHP dom 2.PHP结合XPath操 ...