Я хочу ввести в своем приложении горизонтальное масштабирование вместо вертикального.
Сейчас мы используем Quartz .NET для фоновых задач, но в некластеризованном режиме, всего 1 экземпляр.< /p>Итак, я обнаружил возможность горизонтального масштабирования с помощью кластеризации. Затем настроил его в тестовом приложении и обнаружил, что два экземпляра просто участвуют в «крысиных бегах» и дважды обновляют каждую строку.
Есть идеи, как можно разделить нагрузку между многими экземплярами с помощью кварца и ядра ef? Как я могу «заблокировать» строки в БД, чтобы другие экземпляры не могли работать с ними и брать следующий пакет.
Код, который я использую для обновления БД, и код задания Quartz приведены ниже.< /p>
public async Task UpdateNameAndMarkHiddenLogsAfterReachingDate(DateTime date)
{
const int batchSize = 10;
int hidden = 0;
int hiddenInThisLoopCycle;
using (var transaction = await _context.Database.BeginTransactionAsync())
{
try
{
do
{
var logs = await _context.Logs
.Where(l => l.Created < date && l.IsHidden == false)
.Take(batchSize).ToListAsync();
foreach (var log in logs)
{
log.Message = "UpdatedLog";
log.IsHidden = true;
log.LogDetails.Add(new LogDetail()
{
ChangedByThread = Environment.CurrentManagedThreadId.ToString(),
LastChanged = DateTime.UtcNow,
Name = Thread.CurrentThread.Name
});
}
var result = await _context.SaveChangesAsync();
hiddenInThisLoopCycle = result;
Console.WriteLine($"Deleted {hiddenInThisLoopCycle} logs.");
hidden += hiddenInThisLoopCycle;
Console.WriteLine($"Hidden: {hiddenInThisLoopCycle}");
} while (hiddenInThisLoopCycle > 0);
await transaction.CommitAsync();
}
catch (Exception ex)
{
await transaction.RollbackAsync();
Console.WriteLine($"Transaction failed: {ex.Message}");
throw;
}
}
return hidden;
}
[DisallowConcurrentExecution]
public class DeleteLogsJob : IJob
{
private readonly ILogRepository _logRepository;
private readonly DateTime _date;
private readonly ILogger _logger;
public DeleteLogsJob(ILogRepository logRepository, IOptions options, ILogger logger)
{
_logRepository = logRepository;
_date = options.Value.DeleteAfterDate ?? throw new ArgumentException("DeleteAfterDate was not found in configuration");
_logger = logger;
}
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("About to delete old logs from the database");
var logsDeleted = await _logRepository.UpdateNameAndMarkHiddenLogsAfterReachingDate(_date);
_logger.LogInformation("Deleted {0} old logs from the database", logsDeleted.ToString());
}
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... nd-ef-core