Connection request timed out与Adding the specified count to the semaphore would cause it to excee问题排除-爱代码爱编程
一,问题描述
C#开发的控制系统、Oracle数据库,在00:13用户反馈系统宕机,连上服务器查看,发现日志不再打印,准备重启服务,但重启失败,服务一直在Stopping中无法中止,无奈之下重启服务器后正常。
二,问题排除:
- 查看控制系统日志,发现从前一天的22:15:10,开始断断续续出现数据库连接失败的错误。到00:04时,彻底无法连接,服务假死。
查绚查询SLCTrackmaintian数据数据表发生异常,异常信息:Connection request timed out
- 在数据库排查连接日志发现连接数正常,并未出现锁表,并且Oracle所在是另一台服务器,只是重启应用后恢复,故排除数据库问题。
3. 继续排查应用连接池,发现存在连接池报错。
查绚包号数据表发生异常,异常信息:Adding the specified count to the semaphore would cause it to exceed its maximum count.
底线是信号锁定问题似乎与ASP.NET的连接池有关。资源被锁定在池中,然后没有被释放,所以Application尝试访问池且没有可用的可用资源,连接无法创建了。
可参考:http://jwcooney.com/2012/08/13/asp-net-error-adding-the-specified-count-to-the-semaphore-would-cause-it-to-exceed-its-maximum-count/
但,是什么导致了连接池的锁被保留并没有释放,可能应用程序的问题、网络波动、系统问题(内存、I\O等)。
-
继续系统日志,没有发现异常。
-
发现应用程序的日志中,发现从18:31开始连接MQ 抛 OOM,并且MQ在出现OOM后也连接中断。
2020-12-05 18:31:27,783 [2807] DEBUG NormalDebug [(null)] - WIPBuffer dock failure ,message:System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark& stackMark)
at System.Threading.Thread.Start(StackCrawlMark& stackMark)
at System.Threading.Thread.Start()
at Apache.NMS.ActiveMQ.Threads.DedicatedTaskRunner..ctor(Task task)
at Apache.NMS.ActiveMQ.SessionExecutor.Wakeup()
at Apache.NMS.ActiveMQ.MessageConsumer.Start()
at Apache.NMS.ActiveMQ.Session.CreateConsumer(IDestination destination, String selector, Boolean noLocal)
at Apache.NMS.ActiveMQ.Session.CreateConsumer(IDestination destination)
at AGVLibrary.Bussiness.WIPBuffer.ActiveMQHelper.Call(String sendQueue, String replyQueue, String content, Int32 timeOut)
2020-12-05 18:32:23,557 [2811] DEBUG NormalDebug [(null)] - WIPBuffer dock failure ,message:Apache.NMS.NMSException: Could not connect to broker URL: tcp://10.1.4.67:61616/. Reason: Exception of type 'System.OutOfMemoryException' was thrown. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark& stackMark)
at System.Threading.Thread.Start(StackCrawlMark& stackMark)
at System.Threading.Thread.Start()
at Apache.NMS.ActiveMQ.Transport.Tcp.TcpTransport.Start()
at Apache.NMS.ActiveMQ.Transport.TransportFilter.Start()
at Apache.NMS.ActiveMQ.Transport.TransportFilter.Start()
at Apache.NMS.ActiveMQ.Transport.WireFormatNegotiator.Start()
at Apache.NMS.ActiveMQ.Transport.TransportFilter.Start()
at Apache.NMS.ActiveMQ.Transport.TransportFilter.Start()
at Apache.NMS.ActiveMQ.ConnectionFactory.CreateConnection(String userName, String password)
--- End of inner exception stack trace ---
at Apache.NMS.ActiveMQ.ConnectionFactory.CreateConnection(String userName, String password)
at AGVLibrary.Bussiness.WIPBuffer.ActiveMQHelper.Call(String sendQueue, String replyQueue, String content, Int32 timeOut)
同时MQ中也抛出OOM异常。
2020-12-05 22:02:54,748 | WARN | Transport Connection to: tcp://10.1.4.67:57594 failed: java.io.IOException: An existing connection was forcibly closed by the remote host | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ NIO Worker 104
2020-12-05 22:03:35,297 | WARN | Transport Connection to: tcp://10.1.4.67:57761 failed: java.io.IOException: An established connection was aborted by the software in your host machine | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ NIO Worker 12
三,问题解决
查看 MQ 配置,发现使用的 MQ 配置了 transportConnectors
其配置了 wireFormat.maxInactivityDuration=0
,心跳参数,这样设置就是客户端永远不和服务器断开。
问题根因:代码中不断创建新的连接,再销毁,但因为MQ配置了连接不断开,使得原先的连接线程是一直等待的状态。随着任务不断创建,也不断创建新的连接向MQ发消息,进程中等待的线程数也在不断增加。最后导致线程池溢出,使得数据库也无法再创建新的连接,最后导致系统锁死。
解决方案:
- 优化代码逻辑,ConnectFactory使用单例模式,connect使用连接池,并尝试将生产者发送与消费者监听剥离,全局使用一个消费者监听队列并处理后续逻辑。
- 配置MQ参数,去除长连接
wireFormat.maxInactivityDuration=0
。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/weixin_41422086/article/details/110851031