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();
}

IIS的垃圾回收对后台任务及隐形后台任务的影响的更多相关文章

  1. Java中的引用类型(强引用、弱引用)和垃圾回收

    Java中的引用类型和垃圾回收 强引用Strong References 强引用是最常见的引用: 比如: StringBuffer buffer = new StringBuffer(); 创建了一个 ...

  2. JAVA引用和垃圾回收

    1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.如下: 1 Object o=new Object();   //  强引用 ...

  3. C4 垃圾回收

    使用C4垃圾回收器可以有效提升对低延迟有要求的企业级Java应用程序的伸缩性. 到目前为止,stop-the-world式的垃圾回收视为影响Java应用程序伸缩性的一大障碍,而伸缩性又是现代企业级Ja ...

  4. JVM 垃圾回收机制

    首先JVM的内存结构包括五大区域: 程序计数器.虚拟机栈.本地方法栈.方法区.堆区.其中程序计数器.虚拟机栈和本地方法栈3个区域随线程启动与销毁, 因此这几个区域的内存分配和回收都具有确定性,不需要过 ...

  5. 浅谈PHP5中垃圾回收算法

    原文链接:http://www.cnblogs.com/leoo2sk/archive/2011/02/27/php-gc.html PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源 ...

  6. JVM 性能优化, Part 4: C4 垃圾回收

    ImportNew注:本文是JVM性能优化 系列-第4篇.前3篇文章请参考文章结尾处的JVM优化系列文章.作为Eva Andreasson的JVM性能优化系列的第4篇,本文将对C4垃圾回收器进行介绍. ...

  7. V8的垃圾回收和内存限制

    V8的垃圾回收和内存限制 前言 在第三次浏览器大战中,来自Google的Chrome浏览器凭借优异的性能成为聚光灯下的焦点.而Chrome的成功离不开站在其背后的JavaScript引擎V8. 随着V ...

  8. PHP垃圾回收深入理解

    转摘于http://www.cnblogs.com/lovehappying/p/3679356.html PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源的分配与释放(使用C编写P ...

  9. JVM 专题二十一:垃圾回收(五)垃圾回收器 (二)

    3. 回收器 3.1 Serial回收器:串行回收 3.1.1 概述 Serial收集器是最基本.历史最悠久的垃圾收集器了.JDK1.3之前回收新生代唯一的选择. Serial收集器作为Hotspot ...

  10. 垃圾回收机制GC知识再总结兼谈如何用好GC

    一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般 ...

随机推荐

  1. yum repo和rpm,添加阿里repos

    RPMRPM(Red-hat Package Manager),是一个由红帽最早开发出来的包管理器,目前已经是大多数Linux发行的默认包管理器.RPM管理的包都是以.rpm结尾,其中存储了该软件的安 ...

  2. Flink同步kafka到iceberg数据延迟,两个checkpoint后才可查询

    一.问题描述 用户配置了高级参数很多,观察kafka增量数据不多,flink负载不高情况下两个checkpoint后才可查询到数据.   排查时hdfs有数据文件产生,但是mainfast文件中最新快 ...

  3. 项目中途引入Mybatis-plus后报错,报错Caused by: java.lang.ClassNotFoundException: org.mybatis.logging.LoggerFactory

    一.报错原因 mybatis-plus和pagehelper jar包冲突,注释mybatis-spring和pagehelper插件即可 <!-- SpringBoot集成mybatis框架 ...

  4. Luogu P9055 [集训队互测 2021] 数列重排 题解 [ 紫 ] [ 构造 ] [ 数学 ]

    数列重排:差点就场切的神仙构造,最后一步想假了,导致我模拟赛荣获 25+5+0 的好成绩! 这题部分分很有启发性,跟着一步一步打基本能想到正解的构造,但也有可能想偏部分分的意思,想假策略. 构造 先看 ...

  5. centos 8 mysql 更改数据存储位置

    登录mysql后,先切换到myql数据库下通过show global variables like '%datadir%'; 可以查看数据默认的存储路径(一般在 /var/lib/mysql) 新建数 ...

  6. 快速配置Azure DevOps代理服务器

    快速配置Azure DevOps代理服务器(CentOS 7) Azure DevOps非常好用,但是代理服务器的配置相对有点麻烦而且易出问题,接下来笔者分享一下如何快速配置Azure DevOps的 ...

  7. [SDOI2008] Sandy的卡片 题解

    讲一种自认为最暴力的方法. 首先肯定还是用差分的思想,对于每一张卡片进行重新标号,在卡片串与卡片串中插入特殊字符,然后找重复了 \(n\) 次的子串. 这里我们对于每一个子串开一个大小为 \(n\) ...

  8. Sort operation used more than the maximum 33554432 bytes of RAM

    在数据量超大的情形下,任何数据库系统在创建索引时都是一个耗时的大工程,下面这篇文章主要给大家介绍了关于MongoDB排序时内存大小限制与创建索引的注意事项的相关资料,需要的朋友可以参考下

  9. webgpu学习问题,遇到了create graphics pipeline state failed错误

    在学习webgpu并渲染图像时发生create graphics pipeline state failed with E_INVALIDARG (0x80070057)错误,图像无法成功渲染. ht ...

  10. 启动Eclipse时报错如何解决?

    启动Eclipse出现弹框,弹框报错内容如下: A Java Runtime Enviroment(JRE)or Java Development Kit(JDK) must be available ...