标签: hangfire

使用NLog从Hangfire预定后台作业进行日志记录

所以我的问题如下:我正在调度/使用Hangfire的方法/功能使用NLog执行大量相关信息的记录.在没有hangfire的情况下运行方法时,我得到了我想要的所有日志记录信息,但是当我使用hangfire安排方法时,所有这些日志记录都将丢失.

我知道Hangfire使用NLog(或您喜欢的任何其他日志框架)来进行自己的日志记录.我正在使用ASP.NET MVC4 Web应用程序中的Hangfire.我正在使用Ninject并使用OWIN Startup类设置hangfire,目前看起来像这样:

public class Startup
{
  public void Configuration(IAppBuilder app)
  {
    app.UseHangfire(config =>
    {
        var kernel = new StandardKernel(new MyModule());
        config.UseNinjectActivator(kernel);
        config.UseSqlServerStorage("Context");
        LogProvider.SetCurrentLogProvider(new NLogLogProvider());
        config.UseServer();
    });
   }
}
Run Code Online (Sandbox Code Playgroud)

我想要完成的是Hangfire可以自己进行日志记录,而我的预定作业也可以完成所有日志记录,我并不关心它在一个或多个文件中.目前,Hangfire正在正确进行日志记录,即:

2015-02-25 14:32:41.4400|TRACE|Hangfire.Server.AutomaticRetryServerComponentWrapper|Sending start request for server component 'Server Bootstrapper'...
Run Code Online (Sandbox Code Playgroud)

等等

但是,从预定的工作中进行的记录无处可见.

我想问的是:我如何从预定的方法/工作中进行记录?我的猜测是我错过了某个地方的依赖/背景,但我真的没有任何线索.

.net c# nlog hangfire

8
推荐指数
1
解决办法
2522
查看次数

在HangFire中,我可以使用队列名称而不是使用队列属性进行排队吗?

文档说明您可以通过使用Queue要调用的方法的属性来指定队列.这假设您始终希望在同一队列上执行方法.是否有一种方法可以调用进程Enqueue来指定要将作业放入队列的名称(有效地将决策权交给作业生成器,而不是作业的定义).

hangfire

8
推荐指数
2
解决办法
6407
查看次数

HangFire延迟了日期任务

如何在HangFire任务中添加日期?例如,此代码添加了7天:

BackgroundJob.Schedule(
    () => Console.WriteLine("Reliable!"), 
    TimeSpan.FromDays(7));
Run Code Online (Sandbox Code Playgroud)

但是如果我需要在特定日期运行任务呢?

date task hangfire

8
推荐指数
2
解决办法
2112
查看次数

如何防止Hangfire重复作业在连续执行30分钟后重新启动

我正在使用asp.net mvc-5 Web应用程序,我在使用Hangfire工具运行长时间运行的后台作业时遇到了问题.问题是如果作业执行超过30分钟,那么hangfire会自动启动另一个作业,所以我最终会同时运行两个类似的作业.

现在我有以下内容: -

  1. Asp.net mvc-5
  2. IIS-8
  3. Hangfire 1.4.6
  4. Windows服务器2012

现在我已经定义了一个每天17:00运行的篝火重复工作.后台作业主要扫描我们的网络中的服务器和虚拟机并更新数据库,定期作业将在完成执行后发送电子邮件.经常性工作在执行时间不到30分钟时效果很好.但是今天随着我们的系统的发展,经常性的工作在40分钟后完成,而不是像过去那样在22-25分钟之后完成.我收到了2封电子邮件,而不是一封电子邮件(电子邮件之间的时间约为30分钟).现在我手动重新运行这个工作,我注意到问题如下: -

"当定期作业达到30分钟连续执行时,定期作业的新实例将启动,因此我将有两个实例而不是同时运行的实例,这就是我收到2封电子邮件的原因."

现在,如果定期工作不到30分钟(例如29分钟),我将不会遇到任何问题,但如果重复执行的工作超过30分钟,那么由于某种原因或其他原因,将启动新工作.虽然当我在执行作业期间访问hangfire仪表板时,我发现只有一个活动作业,当我监视我的数据库时,我可以从sql profiler看到有两个作业访问数据库.这种情况发生在经常性工作开始30分钟后(在我们的案例中是17:30),这就是为什么我收到2封电子邮件,这意味着2个重复工作在后台运行而不是一个.

那么有人可以提出这方面的建议吗,如果目前的重复工作执行时间超过30分钟,我怎么能避免因自动启动新的定期工作而导致绞火?谢谢

asp.net iis background-process asp.net-mvc-5 hangfire

8
推荐指数
4
解决办法
7390
查看次数

应用程序池的回收会杀死 Kestrel 但不会重新启动

背景

在 IIS 8+ 上托管(非核心)ASP.net 站点时,可以利用IIS 应用程序初始化模块在 IIS 启动时主动初始化(“预热”)Web 应用程序(或者,我相信,当应用程序池被回收时)。据我所知,在 IIS 上托管 .net Core 应用程序时这是不可能的。

我还注意到,在 IIS 上托管 .net Core (1.1) 应用程序时,dotnet.exe进程 (Kestrel) 作为应用程序池回收事件的一部分被终止。此过程仅在发出第一个新请求时才重新启动。

我问以下问题是因为我正在使用 Hangfire (Core) 和一个经常性的后台作业,并且希望在没有人长时间访问该站点时仍然执行该作业。

问题

  1. 在 IIS 上托管核心应用程序时,使用计划的应用程序池回收功能有什么意义吗?我能找到的唯一参考是 Github repo 上的一个问题

  2. 如果是这样,是否可以在应用程序池回收后自动初始化站点或启动 Kestrel(通常默认情况下每 29 小时发生一次)。

iis hangfire kestrel-http-server asp.net-core asp.net-core-2.0

8
推荐指数
0
解决办法
1668
查看次数

Hangfire:打开的连接太多

我们在生产中使用 Hangfire,结果发现我们确实达到了数据库连接最大限制。

我们有大约 45 个连接用于hangfire,这对于维护一些长时间运行的任务来说似乎有点太多了。

我想知道是否可以采取任何措施来更改连接数,但是,我在配置中找不到提供此类配置的任何内容。

c# postgresql hangfire .net-core

8
推荐指数
2
解决办法
3618
查看次数

Hangfire 中具有不同工作人员数量的多个队列(服务器)

我试图创建多个队列,每个队列应该只有一个工作人员计数。所以我做了下面的代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
            app.UseHangfireDashboard("/scheduler", new DashboardOptions
            {
                Authorization = new[] { new HangFireAuthorization() },
                AppPath = "/"
            });

            app.UseHangfireServer(new BackgroundJobServerOptions()
            {
                ServerName = string.Format("{0}:facebookqueue", Environment.MachineName),
                Queues = new[] { "facebookqueue" },
                WorkerCount = 1
            });

            app.UseHangfireServer(new BackgroundJobServerOptions()
            {
                ServerName = string.Format("{0}:googlequeue", Environment.MachineName),
                Queues = new[] { "googlequeue" },
                WorkerCount = 1
            });


            RecurringJob.AddOrUpdate<IScheduledJobs>(recurringJobId: 
            "FacebookExtractorJobYesterday",
            methodCall: services => services.RecurringJobYesterday(null, 
            JobCancellationToken.Null),
            cronExpression: cronExp, timeZone: TimeZoneInfo.Local, queue: "facebookqueue");

            RecurringJob.AddOrUpdate<IGoogleScheduledJobs>(recurringJobId: 
            "GoogleExtractorJobYesterday",
             methodCall: services => services.RecurringJobYesterday(null, 
             JobCancellationToken.Null),
             cronExpression: cronExp, timeZone: …
Run Code Online (Sandbox Code Playgroud)

hangfire asp.net-core

8
推荐指数
1
解决办法
2610
查看次数

关于 SlidingInvisibilityTimeout 的 Hangfire 澄清

hangfire 文档指出:

原始 SQL Server 作业存储实现的主要缺点之一——它使用轮询技术来获取新作业。从 Hangfire 1.7.0 开始,当设置了 SlidingInvisibilityTimeout 选项时,可以使用 TimeSpan.Zero 作为轮询间隔。

我按照建议使用这些 SqlServerStorageOptions:

var options = new SqlServerStorageOptions
{
    SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
    QueuePollInterval = TimeSpan.Zero
};
Run Code Online (Sandbox Code Playgroud)

它没有说明 SlidingInvisibilityTimeout 的实际含义,谁能澄清一下?
我的情况是,我每天早上有大约 1000 封电子邮件要发送,而且我一直在突破每分钟 30 封邮件的 Office365 限制并被拒绝,所以我使用 Hangfire 将它们排在一个工作线程中,并添加了一个每个任务结束时 2 秒 Thread.Sleep。这很好用,但我的 CPU 使用率增加了大约 20% 由 hangfire 引起(如此处报告的那样),并且在服务器繁忙时导致频繁超时。

我试图实现的行为是:

  1. 在每项工作结束时,立即检查是否还有另一项工作并进行下一项任务。
  2. 如果队列中没有作业,请在 5 分钟后回来检查,直到那时才接触 SQL 服务器。

感谢您的帮助。

hangfire

8
推荐指数
1
解决办法
1805
查看次数

DI 范围的范围是什么 - .NET Core 中的 Hangfire

想象一下,在 ASP.NET Core 中我注册了一个依赖项,如下Scoped所示:

IServiceCollection services = ...
services.AddScoped<IEmailService, EmailService>();
Run Code Online (Sandbox Code Playgroud)

然后我知道对于每个 HTTP 请求,scope都会创建一个新的请求,并且Email会重用一个新的服务实例。此外,同样的情况scope将在请求的生命周期内持续存在。

现在,假设我添加了一个 Hangfire 后台作业,如下所示:

RecurringJob.AddOrUpdate<IServiceA>("DoA", s => s.DoA(), Cron.Daily());
Run Code Online (Sandbox Code Playgroud)

在哪里

public class ServiceA: IServiceA {
    public ServiceA(IEmailService emailService) { ... }
    public void DoA() { ... }
}
Run Code Online (Sandbox Code Playgroud)

我想了解scopedhangfire工作术语中的含义,默认情况下,hangfire

  • 对所有作业和运行使用单一范围
  • 为每个作业创建单独的作用域,但同一作业的不同运行共享作用域
  • 为任何作业的每次运行创建单独的范围

有关如何配置它的解释的奖励积分。

hangfire asp.net-core

8
推荐指数
1
解决办法
2466
查看次数

Hangfire:全局添加 JobId 以记录到 Serilog

我正在尝试将 Hangfire JobId (和其他属性)添加到我的所有作业中,而不必将其添加到每个作业方法中。

在 Startup.cs 中,我添加了一个有前途的过滤器解决方案,但是我不知道如何将其应用到我的测试方法中,我什至不确定这是否是正确的方法。

启动.cs

...
GlobalJobFilters.Filters.Add(new JobLoggerAttribute());
Run Code Online (Sandbox Code Playgroud)

JobLoggerAttribute类 - 来自此处: 链接

我的任务是将 JobId 放置在列单元格当前为空白的位置,而无需手动将其添加到我的测试方法中: 在此输入图像描述

Program.cs(全局定义的Logger):

Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .WriteTo.Elasticsearch....
                .Enrich.FromLogContext()
                .CreateLogger();
Run Code Online (Sandbox Code Playgroud)

因为我还想检索方法名称等。我添加了这个类来调用我的工作中的 Here 方法。

LoggerExtensions.cs:

    public static class LoggerExtensions
    {
        public static ILogger Here(this ILogger logger,
            [CallerMemberName] string memberName = "",
            [CallerFilePath] string sourceFilePath = "",
            [CallerLineNumber] int sourceLineNumber = 0
            )
        {
            return logger
                .ForContext("MemberName", memberName)
                .ForContext("FilePath", sourceFilePath)
                .ForContext("LineNumber", sourceLineNumber)
                ;
        }
    }
Run Code Online (Sandbox Code Playgroud)

运行测试任务:

public void RunTestTask(PerformContext context)
        {

            // instead of …
Run Code Online (Sandbox Code Playgroud)

c# serilog hangfire

8
推荐指数
1
解决办法
937
查看次数