参考如下博客
C# 因IIS回收导致定时器失效的解决方案
https://blog.51cto.com/u_15127642/3637171
Quartz.Net 整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
https://blog.csdn.net/contact97/article/details/138992982
Quartz.net的快速简单上手使用以及防止IIS回收停止Job的处理
https://www.cnblogs.com/myron1024/p/13458806.html
IIS优化服务器性能导致QuartZ任务未运行
https://www.cnblogs.com/proxyz/p/6109884.html
问题:
IIS 为优化服务器性能,会自动对它认为休眠的应用程序进行资源回收,资源回收将会导致网站应用程序关闭
解决方案:
1、 设置闲置超时为0,固定回收时间间隔为0,即IIS不主动回收闲置进程
2、并设置每天固定凌晨2:00(错开访问高峰)回收进程,且在虚拟内存和专用内存占用超过1G(服务器16G内存)时回收进程,防止内存溢出。设置1G是基于目前CRM工作线程内存占用普遍不高,便于内存溢出时及时回收进程
3、在进程被回收后,程序监测到应用关闭事件,重新启动应用
关于内存溢出的说明
.NET的GC机制有这样两个问题:
首先,GC并不是能释放所有的资源。它不能自动释放非托管资源。
第二,GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性。
GC并不是实时性的,这会造成系统性能上的瓶颈和不确定性。所以有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句可以简化资源管理。
非托管资源:
ApplicationContext,Brush, Component, ComponentDesigner, Container, Context, Cursor, FileStream,Font, Icon, Image, Matrix, Object, OdbcDataReader, OleDBDataReader, Pen, Regex,Socket, StreamWriter, Timer, Tooltip, 文件句柄, GDI资源, 数据库连接等等资源。
我们知道关闭、重启网站或者IIS程序池是会执行Application_End事件的,Application_End 事件后 就跟刚部署到IIS的站点一样,在发送第一个针对该 Web 应用程序的 Http 请求后,IIS 才会自动启动 Web 应用程序,
既然IIS是因为程序闲置没有收到请求而回收进程的,那就在Application_End 事件里再提交一个请求给该 Web 应用程序,从而“激活”关闭的应用程序不就可以了?
“激活”程序之后,定时任务就又可以继续自动执行啦。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
//应用程序启动时加载log4net设置
XmlConfigurator.Configure();
Log.Info("Application_Start 触发");
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
// 初始化启动定时任务引擎
QuartzUtil.Init();
// 启动设定的任务
QuartzUtil.AddJob<GetRecordJob>("job1", "0/10 * * * * ?"); // 10s执行一次
Log.Info("Application_Start 启动设定的任务");
}
protected void Application_End(object sender, EventArgs e)
{
Log.Info("Application_End 触发\r\n");
Activate();
}
public static void Restart()
{
Log.Info("Restart() 卸载所有定时器... ");
QuartzUtil.Shutdown(false); //true 等待当前job执行完再关闭,false 直接关闭
Log.Info("Restart() 准备重启 ");
HttpRuntime.UnloadAppDomain(); //会触发Application_End 事件
Log.Info("Restart() 重启完成 ");
}
/// <summary>
/// “激活”程序
/// IIS回收后,将触发Application_End事件,需发起一次请求才会触发 Application_Start事件开始执行定时任务
/// </summary>
public static void Activate()
{
string host = System.Configuration.ConfigurationManager.AppSettings["WebUrl"].ToString();
string url = host.TrimEnd('/') + "/Home/Ping";
Log.Info("PING URL : " + url);
string res = HttpUtils.HttpGet(url);
Log.Info("PING RESULT:" + res + "\r\n");
}
}