В Hangfire не хватает рабочихC#

Место общения программистов C#
Anonymous
В Hangfire не хватает рабочих

Сообщение Anonymous »

Мы используем службы связи Azure для отправки пользователям электронных писем и SMS-сообщений. У нас есть задание Hangfire EmailNotificationJob/SmsNotificationJob для каждого сообщения. Мы часто превышаем лимит в 100 писем в час, и задания Hangfire зависают в обработке на час.
Изображение

Код: Выделить всё

services.AddHangfire((serviceProvider, globalConfiguration) => globalConfiguration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseRecommendedSerializerSettings()
.UseRedisStorage(redisConnectionString, redisStorageOptions)
.UseBatches()
.UseThrottling(ThrottlingAction.RetryJob, 1.Seconds())
.UseTagsWithRedis(new() { TagsListStyle = TagsListStyle.Dropdown }, redisStorageOptions)
.UseApplicationInsightsTelemetry(serviceProvider));

services.AddHangfireServer((provider, options) =>
{
options.Activator = new HangfireJobActivator(provider);
options.WorkerCount = Environment.ProcessorCount * 5;
options.HeartbeatInterval = 10.Seconds();
options.SchedulePollingInterval = 1.Seconds();
options.Queues = new[] { "critical", "default", "notifications" };
options.ServerName = Environment.MachineName;
});

Код: Выделить всё

backgroundJobClient.Enqueue(x => x.Perform(new(notificationMessage.Email, notificationMessage.Subject, notificationMessage.Body), null));

...
[Queue("notifications")]
[AutomaticRetry(Attempts = 3)]
public class EmailNotificationJob
{
readonly IServiceProvider _serviceProvider;

public EmailNotificationJob(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;

public async Task Perform(EmailNotificationJobOptions jobOptions, PerformContext? performContext)
{
using var scope = _serviceProvider.CreateScope();
var emailClient =  scope.ServiceProvider.GetRequiredService();

if (string.IsNullOrWhiteSpace(jobOptions.Email))
{
throw new InvalidArgumentException("Email address is empty.");
}

var content = jobOptions.Body.ToHtml();
await emailClient.SendAsync(jobOptions.Subject, content, jobOptions.Email);
}
}

public sealed class AzureEmailClient
{
readonly ILogger _logger;
readonly string _sender;
readonly EmailClient _emailClient;

public AzureEmailClient(ILogger logger, IConfiguration configuration)
{
_logger = logger;
_sender = configuration[ConfigurationKeys.AzureCommunicationServicesFromEmail];
_emailClient = configuration.CreateEmailClient();
}

public async Task SendAsync(string subject, string htmlContent, string recipient, CancellationToken cancellationToken = default)
{
try
{
_logger.LogInformation("{ClientName}: Initiating sending of an email to {Recipient} with subject: {Subject}",
nameof(AzureEmailClient), recipient, subject);

var emailSendOperation = await _emailClient.SendAsync(WaitUntil.Completed, _sender, recipient, subject, htmlContent, null, cancellationToken);

var operationId = emailSendOperation.Id;
_logger.LogInformation("{ClientName}: Email Sent. Status = {Status}. Operation ID = {OperationId}",
nameof(AzureEmailClient), emailSendOperation.Value.Status, operationId);
}
catch (RequestFailedException ex)
{
_logger.LogError("{ClientName}: Email send operation failed with error code: {ErrorCode}, message: {Message}",
nameof(AzureEmailClient), ex.ErrorCode, ex.Message);
throw;
}
}
}
Проблема, с которой мы столкнулись, заключается в том, что работники выбирают элементы с низким приоритетом из очереди «уведомлений», а затем задания приостанавливаются в обработке на час (из-за ограничения скорости). на Azure, но пока игнорируем этот факт). В то же время «критические» задания помещаются в критическую очередь, но над ними невозможно работать, поскольку все рабочие заняты.
Следует ли нам увеличить количество рабочих или как это сделать? мы работаем над решением этой проблемы?

Подробнее здесь: https://stackoverflow.com/questions/786 ... n-hangfire

Вернуться в «C#»