qidao123.com技术社区-IT企服评测·应用市场
标题:
IIS的垃圾回收对背景任务及隐形背景任务的影响
[打印本页]
作者:
不到断气不罢休
时间:
2025-4-16 20:10
标题:
IIS的垃圾回收对背景任务及隐形背景任务的影响
IIS的垃圾回收引起的影响
错误排查
现象:在.net core api里创建的BackgroundService界说rabbitmq消耗的逻辑,在一段时间运行后常常会出现消耗任务中断,在日志里找了很久的原因但是依然没有结论。
通过日志发现异常出现在消耗后的消息确认阶段,在执行确认的时间对应的channel和connection都关闭了
_channel.BasicAckAsync(eventArgs.DeliveryTag, false);
复制代码
报错信息如下,体现rabbitmq连接中断的原因是:由应用程序主动发起关闭的。
RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Application, code=200, text='Goodbye', classId=0, methodId=0
at RabbitMQ.Client.Impl.SessionBase.ThrowAlreadyClosedException()
at RabbitMQ.Client.Impl.SessionBase.TransmitAsync[T](T& cmd, CancellationToken cancellationToken)
at ALC.Server.Infrastructur.RabbitMq.RabbitMQClient.<>c__DisplayClass15_0`1.<<ConsumeMqMessage>b__0>d.MoveNext()
复制代码
这个报错一般是因为channel的作用域有问题,但是一般发生在启动时,很容易发现。我们这是消耗很多消息后才出现的,显然不属于这种情况,继续排查。后续发现w3wp.exe的报错,查看
事件查看器
,
windows日志-系统
发现有一连的信息如下:
为应用程序池“net9”提供服务并且进程 ID 为“45552”的工作进程因不活动而被关闭。应用程序池超时配置被设置为 20 分钟。需要时将启动一个新工作进程。
复制代码
上述的“net9”是我配置的程序池名称
弹出应用程序: Visual Studio 实时调试器: [45552] w3wp.exe 中发生了未经处理的 win32 异常。 对此异常的实时调试失败,错误为: 进程 ID 无效。
有关详细信息,请参见文档索引中的“实时调试, 错误”。
复制代码
通过对上述报错发现,应该和资源池的回收机制有关,因为资源池默认的回收时间就是20分钟。于是继续百度找到如下问题对应背景任务会被回收事件打断。受资源池回收的影响,即使不利用backgroundservice,rabbitmq的消耗历程也会被打断:
.net core背景任务办理iis自动回收导致任务被终止的问题
BackgroundService引起的影响
应对措施:让背景任务类或者rabbitmq的消耗类实现IDiposable或者IAsyncDisposable,因为资源池在回收的时间会执行Diposable或AsyncDisposable方法。在此方法内,发起一次对本系统的http调用(如果没问题继续调用),即可重新唤醒。
/// <summary>
/// 释放托管资源,释放时触发
/// </summary>
public void Dispose()
{
Common.WriteEmailLog("定时任务被释放闭", "...Dispose...");
_timer?.Dispose();
//iis会回收这个定时任务,这边在回收的时候触发一个请求,来再次唤醒该服务
Thread.Sleep(5000);
HttpHelper.HttpGet(_configuration.GetSection("AwakenUrl").Value);
}
复制代码
对于Rabbitmq消耗端的影响
public async ValueTask DisposeAsync()
{
//异步关闭connection及channel
await _mQClient.DisposeAsync();
_logger.LogInformation("发起唤醒请求");
//iis会回收这个rabbitmq的消费任务,这边在回收的时候触发一个请求,来再次唤醒该服务
try
{
_logger.LogInformation("进入唤醒请求");
//注意:这时HttpSimpleHelper已经不能以注入的方式去生成了,注意如果是多个实例同时部署到IIS,需要配置不同的AwakenUrl
var result = await HttpSimpleHelper.GetAsync<bool>(_configuration.GetSection("AwakenUrl").Value);
_logger.LogInformation($"唤醒请求结束:{result}");
}
catch (Exception ex)
{
_logger.LogError($"调用苏醒请求出错:{ex}");
throw;
}
}
复制代码
对应的关闭channel及Connection的方法
public async ValueTask DisposeAsync()
{
if (_channel != null && _channel.IsOpen)
{
await _channel.CloseAsync();
}
if (_sendConnection != null && _sendConnection.IsOpen)
{
await _sendConnection.CloseAsync();
}
_channel?.DisposeAsync();
_sendConnection?.DisposeAsync();
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4