自定义保活功能后,网站停止工作



我最近部署了一个在共享托管环境中运行的站点。问题是站点接收到零星的流量:我想20分钟后服务器会关闭实例,所以当站点加载第一个请求时,速度通常很慢。所以我决定添加一个每隔几分钟加载一次网页的功能。我用new CodeKeepAlive.KeepAliveManager().SetKeepAlive();调用Global.asax中的代码,这是完整的代码:

public class KeepAliveManager
{
Timer KeepAliveTimer;
public void SetKeepAlive()
{
KeepAliveTimer = new Timer(DoKeepAliveRequest, null, new Random().Next(200000, 900000), Timeout.Infinite);
}
public void DoKeepAliveRequest(object state)
{
string TheUrl = "https://www.the_website_url.com";
HttpWebRequest TheRequest = (HttpWebRequest)WebRequest.Create(TheUrl);
HttpWebResponse TheResponse = (HttpWebResponse)TheRequest.GetResponse();
KeepAliveTimer.Change(new Random().Next(200000, 900000), Timeout.Infinite);
}
}

出于某种原因,由于我添加了此功能,网站偶尔会锁定一次;加载30秒后,服务器表示页面无法加载。我还有一个在Application_Error上触发的错误日志记录功能,但没有日志。

我的代码有什么问题吗?

问题是在asp.net中,没有可靠的方法来运行后台任务,而IIS会杀死你的线程。一旦请求完成,IIS就没有理由让您生成的任何线程保持活动状态。

有几种方法可以做到这一点,比如在亚马逊或谷歌云的免费层上使用一些简单的服务来充当你的心跳。

但假设你只想使用你的共享主机

你可以使用像HangFire这样专门从事这方面的东西,但它们有其局限性,请参阅入门文档:

GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage("Database=Hangfire.Sample; Integrated Security=True;", new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
})
.UseBatches()
.UsePerformanceCounters();
//Queue the job
BackgroundJob.Enqueue(() => Console.WriteLine("Hello, world!"));
//run it
using (var server = new BackgroundJobServer())
{
Console.ReadLine();
}

注意:Hang Fire本身有其局限性IIS会关闭任何长时间运行的线程,例如耗时超过90或180秒的线程(我忘记了限制)。因此,请确保在收到的每个请求上都对心跳任务进行排队。如果你想确保不会触发太多,可以在请求中添加一个标头,并验证它是否在请求中。

请参阅新的.Net核心后台任务中的此答案,因为它与IIS 有关,因此适用

在PhantomJs中添加一个测试程序,随机或定期截屏url并将其部署在同一服务器上。IT将为u 做这项工作

最新更新