记一次rabbitmq队列阻塞
一,问题
通过rabbitmq可视化界面看到其中有一个队列未消费数量有5万多,而且在持续增加中
二,分析
1,上网了解了rabbitmq原理后,从未消费的队列中看到unacked一直没有变化,而consumers中有存在消费者,所以应该是程序有收到消息,却一直卡主,没有返回ack给rabbitmq。
2,通过不断测试后发现,程序中确实有一个会发生堵塞地方,就是tcp链接中readline方法。每当有远程主机断开强制断开连接时,有几率发生readline一直堵塞,具体原因未知
三,解决问题
知道了原因,就好解决了,
解决方法1:目前未找到微软有提供的流读取操作有超时设置的地方,因此暂时自己先弄一个线程来对操作进行超时限制,实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /// <summary> /// 超时处理 /// </summary> /// <param name="time">超时时间,单位毫秒</param> /// <param name="func">发生堵塞的方法</param> /// <returns></returns> public static Tuple< bool , string > TimeOutCommand( int time, Func< string > func) { var cts = new CancellationTokenSource(); var token = cts.Token; var task = Task.Factory.StartNew(() => { try { using (token.Register(Thread.CurrentThread.Interrupt)) { return func(); } } catch (Exception) { } return string .Empty; }); var result = string .Empty; //结果 var loop = 100; //等待时间,单位毫秒 var waitTime = 0; //已经等待时间 bool flag = task.Wait(1); //是否执行成功 while (!flag) { waitTime += loop; flag = task.Wait(loop); if (!flag) { if (waitTime > time) { try { cts.Cancel(); } catch (Exception) { } break ; } } } if (flag) { result = task.Result; } return new Tuple< bool , string >(flag, result); } |
解决方法2:使用TcpClient,设置ReceiveTimeout和SendTimeout超时时间就行
/// <summary> /// 连接远程服务器 /// </summary> public void ReConnect() { if (this.LocalEndPoint != null && this._tcpClient != null) { this.Dispose(); } try { this._tcpClient = new TcpClient(this._host, this._hostPort); this._tcpClient.ReceiveTimeout = 10000; this._tcpClient.SendTimeout = 10000; this._ntkStream = this._tcpClient.GetStream(); this._sReader = new StreamReader(this._ntkStream, Encoding.Default); this.LocalEndPoint = this._tcpClient.Client.LocalEndPoint; this.SetConnectionState(true); } catch (Exception lastError) { this.LastError = lastError; this.SetConnectionState(false); } }
注意:并且服务器有可能会不断的写入空值流,如果不判断的话有可能造成死循环不断读取流
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了