У меня есть приложение Hangfire, написанное на .NET 8 и размещенное на IIS. Он используется для выполнения ежедневного запланированного задания. Проблема в том, что через некоторое время приложение закрывается и больше не запускается, поэтому задание не запускается.
Я все сделал в разделе документации Hangfire "Если у вас ничего не работает…, но все равно не работает. Я перезапускаю пул приложений/перезапускаю, но приложение не запускается снова.
ИИС:
installed Application Initialization module
пул приложений:
set .NET CLR version to 4.0
set managed pipeline mode to 4.0
set start mode to AlwaysRunning
set Idle Time-Out (minutes) to 0
сайт:
set Preload Enabled to true
Configuration Manager → system.webServer/applicationInitialization
From: ApplicationHost.config
set doAppInitAfterRestart to True
added hostName and initializationPage to Collection Editor
Что мне не хватает?
Windows Server 2019, IIS версии 10.
Есть ли какие-либо сообщения об ошибках или журналы? Вам нужно получить некоторую информацию, чтобы сузить проблему.
@LexLi спасибо за самый бесполезный ответ.
@XudongPeng привет, нет, ошибок нет, просто не работает.
Не уверен, связано ли это с версией Core, возможно, вы можете попробовать .NET 6/7. Или службу Windows, упомянутую сообществом ниже, для удовлетворения ваших потребностей.
Вам следует разместить свой сервер Hangfire в другом приложении - например, в службе Windows. И используйте веб-API только для размещения панели мониторинга Hangfire.
Настройка будет выглядеть примерно так:
Для службы Windows:
var hostbuilder = Host.CreateDefaultBuilder(args);
var host = hostbuilder.UseWindowsService().
ConfigureServices((hostContext, services) =>
{
var storageOptions = new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(30),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true,
EnableHeavyMigrations = true,
};
services.AddHangfire(c => c
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(() => new SqlConnection(connectionString), storageOptions));
services.AddHangfireServer(a =>
{
a.WorkerCount = Math.Min(Environment.ProcessorCount * hangfireConfiguration.WorkerCount, 10);
a.Queues = new[] { "default", "lowprio" };
});
}).Build();
await host.RunAsync();
А для веб-API вы просто настраиваете панель Hangfire, используете тот же код, что и выше, только без добавления серверов Hangfire.
Что-то вроде этого:
var builder = WebApplication.CreateBuilder(args);
var storageOptions = new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(30),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
PrepareSchemaIfNecessary = false
};
builder.Services..AddHangfire(c => c
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(() => new SqlConnection(connectionString), storageOptions));
var app = builder.Build();
var hangfireStorage = new SqlServerStorage(() => new SqlConnection(connectionString), storageOptions);
var dashboardOptions = new DashboardOptions { Authorization = new[] { new AllowAllAuthorizationFilter() } };
app.UseHangfireDashboard("/dashboard", dashboardOptions, hangfireStorage);
await app.RunAsync();
}
public class AllowAllAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize(DashboardContext context)
{
return true;
}
}
PS Не забудьте использовать ту же строку подключения. Ваш сервер и ваша панель управления будут обращаться к одной и той же базе данных.
Обеспечить постоянное включение IIS действительно сложно и зависит от множества вещей — этот способ намного проще — служба вдов всегда работает.
К сожалению, разработчики Hangfire не указали такую информацию в своей документации.
Значит, мне следует разместить сервер как службу Windows, а панель мониторинга — как веб-приложение IIS? И я предполагаю, что все задания и логика будут находиться в серверном приложении, а приложение Dashboard будет содержать только Program.cs или что-то в этом роде.
Что-то в этом роде - да.
Эй, хотел сообщить тебе новости. У меня это работает. Разделите решение на два проекта — панель мониторинга и сервер. На то, чтобы заставить его работать, ушел целый день, в основном пришлось переконфигурировать Program.cs, но он работает. Я бы хотел, чтобы разработчики Hangfire обновляли свою документацию. Спасибо.
Здорово - рад, что смог помочь :)
Еще одно обновление. Судя по всему, Microsoft что-то изменила в .NET 7 или 8, точно не знаю, но теперь DefaultHostBuilder сначала считывает переменные среды с префиксом «DOTNET_». Я не мог понять, почему моя служба Windows продолжала видеть среду разработки/тестирования как рабочую, вот почему. Источник: Learn.microsoft.com/en-us/aspnet/core/fundamentals/host/… Итак, если у кого-то еще возникают проблемы с тем, что ваше приложение видит неправильную среду хостинга, убедитесь, что у вас установлена переменная среды DOTNET_ENVIRONMENT.
Вам не следует использовать Hangfire с самого начала.