【问题标题】:asp.net core hosted service sleeps after api inactivityapi 不活动后,asp.net 核心托管服务休眠
【发布时间】:2019-01-23 18:46:28
【问题描述】:

我有一个托管服务,每分钟检查一个电子邮件帐户。我还将 MVC 与 Web API 2.1 一起使用。为了让我的托管服务启动,我必须通过调用 API 方法来“唤醒它”。在 Web API 一段时间不活动后,托管服务进入睡眠状态并停止检查电子邮件。就像它正在收集垃圾一样。如何让它连续运行?

我们将不胜感激。

Startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {Title = "CAS API", Version = "v1"});

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            })

            .AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder.WithOrigins(Configuration["uiOrigin"])
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials());
            })
            .AddHostedService<EmailReceiverHostedService>()
            .Configure<EmailSettings>(Configuration.GetSection("IncomingMailSettings"))
            .AddSingleton<IEmailProcessor, MailKitProcessor>()
            .AddSingleton<IEmailRepository, EmailRepository>()


          ...

EmailReceiverHostedService.cs:

using CasEmailProcessor.Options;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading;
using System.Threading.Tasks;

public class EmailReceiverHostedService : IHostedService, IDisposable
{
    private readonly ILogger _logger;
    private readonly Timer _timer;
    private readonly IEmailProcessor _processor;
    private readonly EmailSettings _emailConfig;


    public EmailReceiverHostedService(ILoggerFactory loggerFactory,
        IOptions<EmailSettings> settings,
        IEmailProcessor emailProcessor)
    {
        _logger = loggerFactory.CreateLogger("EmailReceiverHostedService");
        _processor = emailProcessor;
        _emailConfig = settings.Value;
        _timer = new Timer(DoWork, null, Timeout.Infinite, Timeout.Infinite);
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is starting.");
        StartTimer();
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is stopping.");
        StopTimer();

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }

    private void StopTimer()
    {
        _timer?.Change(Timeout.Infinite, 0);
    }
    private void StartTimer() { _timer.Change(TimeSpan.FromSeconds(_emailConfig.TimerIntervalInSeconds), TimeSpan.FromSeconds(_emailConfig.TimerIntervalInSeconds)); }

    private void DoWork(object state)
    {
        StopTimer();
        _processor.Process();
        StartTimer();
    }
}

【问题讨论】:

  • 您使用什么来托管您的 API?可能配置了一个空闲超时,上面写着if I do not receive any requests in x minutes, shut down to save memory
  • 我正在使用 IIS 来托管
  • 在应用程序池中有 20 分钟的“空闲”超时。我将查看日志以查看它是否在 20 分钟后超时,然后将超时增加到 40 分钟。最终,我可能需要在 win 服务中托管电子邮件部分。
  • 您可以将您的应用程序配置为始终运行,阅读这篇文章:docs.hangfire.io/en/latest/deployment-to-production/…

标签: asp.net-core asp.net-core-webapi asp.net-core-2.1 asp.net-core-hosted-services


【解决方案1】:

正如您所想,根本原因是在 IIS 中托管时,由于应用程序池回收,您的主机可能会被关闭。这已在下面指出:

请务必注意,部署 ASP.NET Core WebHost 或 .NET Core 主机的方式可能会影响最终解决方案。例如,如果您在 IIS 或常规 Azure 应用服务上部署您的 WebHost,您的主机可能会因为应用程序池回收而关闭。

Deployment considerations and takeaways

对于可能的解决方法,您可以尝试将空闲超时设置为零以禁用默认回收。

由于 IIS 默认回收,您可以考虑不同的托管方法:

  • 使用 Windows 服务

  • 使用 Docker 容器(Windows 容器),但为此,您需要 Windows Server 2016 或更高版本。

  • 使用 Azure Functions

对于你的场景,你可以试试Host ASP.NET Core in a Windows Service

【讨论】:

    【解决方案2】:

    我在 Windows 事件调度程序上创建任务以访问 URL 以唤醒服务。

    powershell.exe -command {Invoke-WebRequest http://localhost:8080}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-13
      • 2021-01-27
      • 2016-08-28
      • 2019-06-17
      • 2020-12-23
      • 2020-09-26
      • 2022-12-22
      • 1970-01-01
      相关资源
      最近更新 更多