RabbitMQ---8、连接断开处理-断线重连
本文转载于: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 使用方式如下
- var factory = new ConnectionFactory() { HostName = "localhost", AutomaticRecoveryEnabled = true };
复制代码
具体的恢复机制如下
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---8、连接断开处理-断线重连的更多相关文章
- .net/c# RabbitMQ 连接断开处理-断线重连(转载)
Rabbitmq 官方给的NET consumer示例代码如下,但使用过程,会遇到connection断开的问题,一旦断开,这个代码就会报错,就会导致消费者或者生产者挂掉. 下图是生产者发送消息,我手 ...
- nodejs使用MYSQL连接池,断线重连
两种方式解决1.你可以配置mysql的连接池 var mysql = require('mysql'); var pool = mysql.createPool({ host: 'localhost' ...
- socket 如何判断远端服务器的连接状态?连接断开,需重连
fluent-logger-java is a Java library, to record events via Fluentd, from Java application. https://g ...
- Spring-Data-Redis 下实现jedis连接断开后自动重连
原先使用jedis的时候,处理手段是在从连接池获取连接时捕获JedisConnectionException异常,在异常处理部分重新获取连接,但是spring data redis似乎不会,如下所示: ...
- Netty(六):Netty中的连接管理(心跳机制和定时断线重连)
何为心跳 顾名思义, 所谓心跳, 即在TCP长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性. 为什么需要心跳 因为网络的不可靠性, 有可 ...
- 【问题记录】—SignalR连接断线重连
起因: ASP.NET Core SignalR是一个开源库,可简化向应用添加实时 SignalR Web 功能. 实时 Web 功能使服务器端代码能够立即将内容推送到客户端.(相信大家都用得比较多了 ...
- Android基于XMPP Smack Openfire下学习开发IM(五)连接断开重连
学习过程中大家都碰到过连接被断开的问题给困扰吧,下面教大家如何做到连接断开后,重新连接 首先要创建连接监听器,用来监听连接状态,这里我写了一个类 继承了ConnectionListener,重写了里面 ...
- zookeeper 大量连接断开重连原因排查
转自:http://blog.csdn.net/hengyunabc/article/details/41450003?utm_source=tuicool&utm_medium=referr ...
- netty4 断线重连
转载:http://www.tuicool.com/articles/B7RzMbY 一 实现心跳检测 原理:当服务端每隔一段时间就会向客户端发送心跳包,客户端收到心跳包后同样也会回一个心跳包给服务端 ...
随机推荐
- python中的基本数据类型(int,bool,str)及字符串操作
一. 基本数据类型概况 1. int 整数,主要用来进行数学运算 2. str 字符串,可以保存少量数据并进行相应的操作 3. bool 布尔值,判断真假,True,False 4. list ...
- Windows7 64位下SDK Manager.exe无法运行问题解决方法
我在Windows7 64位下运行SDK Manager.exe总是一闪而过,无法正常启动它,最后在网上找到一篇文章,修改系统“path”变量,把“path”变量中的第一项设置为我的JDK目录“C:\ ...
- SpringMVC框架 SpringMVC的获取01
---恢复内容开始--- SpringMVC通过实现MVC模式,很好地将数据.业务与展现进行了分离.从MVC的角度来说,SpringMVC和Struts2非常类似,但SpringMVC采用了可插拔的组 ...
- Sublime关于tab转空格的设置技巧
在编写大的工程的代码的时候,会要求一些多余的字符不应该存在,比如说末尾不应该有空格或者Tab这样的字符,比如说所有的Tab应该变成空格,这样工程不管在什么样的编辑器下看,格式都会比较统一,等等,可是如 ...
- hadoop-1.2.1-1.x86_64.rpm、jdk-7u45-linux-x64.tar.gz安装(64位)
一, 配置信息 机器是64位,所以操作系统.软件都是64位的. 操作系统:CentOS6.2(64位): Hadoop是hadoop-1.2.1-1.x86_64.rpm: JDK是jdk-7u4 ...
- [ActionScript 3.0] 幻灯片效果实例
package com.fylibs.components.effects { import com.fylibs.utils.LoaderQueues; import com.tweener.tra ...
- C语言多线程编程一
1. Windows下同时打开多个对话框: #include <Windows.h> #include <process.h> //创建线程 void runmsg(void ...
- [原创] Trie树 php 实现敏感词过滤
目录 背景 简介 存储结构 PHP 其他语言 字符串分割 示例代码 php 优化 缓存字典树 常驻服务 参考文章 背景 项目中需要过滤用户发送的聊天文本, 由于敏感词有将近2W条, 如果用 str_r ...
- 并发编程>>线程池的实现(四)
线程创建倾向 如果运行的线程的小于corePoolSize,当请求来时,创建新线程. 如果运行corePoolSize或多于,当请求来时,排队. 如果请求不能进行排队,且小于maximumPoolSi ...
- [ZJOI2019]Minimax搜索
先求出根节点的权值\(w\).根据套路,我们对于每个\(k\),计算\(w(s)\leq k\)的方案数,差分得到答案.为了方便,接下来考虑计算概率而不是方案数. 可以发现,对于一个给定的有解的子集, ...