- RabbitMQInitializer를 BackgroundService로 변경 (30초 간격 재시도) - RabbitMQConnection에 IsConnected 속성 추가 - Health check에 RabbitMQ 연결/초기화 상태 반영 - DI 등록 변경 (Singleton + HostedService 패턴) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
101 lines
3.4 KiB
C#
101 lines
3.4 KiB
C#
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using RabbitMQ.Client;
|
|
using SPMS.Application.Settings;
|
|
|
|
namespace SPMS.Infrastructure.Messaging;
|
|
|
|
public class RabbitMQInitializer : BackgroundService
|
|
{
|
|
private readonly RabbitMQConnection _connection;
|
|
private readonly RabbitMQSettings _settings;
|
|
private readonly ILogger<RabbitMQInitializer> _logger;
|
|
private static readonly TimeSpan RetryInterval = TimeSpan.FromSeconds(30);
|
|
|
|
public bool IsInitialized { get; private set; }
|
|
|
|
public RabbitMQInitializer(
|
|
RabbitMQConnection connection,
|
|
IOptions<RabbitMQSettings> settings,
|
|
ILogger<RabbitMQInitializer> logger)
|
|
{
|
|
_connection = connection;
|
|
_settings = settings.Value;
|
|
_logger = logger;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
await InitializeAsync(stoppingToken);
|
|
IsInitialized = true;
|
|
_logger.LogInformation("RabbitMQ 초기화 완료");
|
|
return;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "RabbitMQ 초기화 실패 — {RetrySeconds}초 후 재시도합니다.", RetryInterval.TotalSeconds);
|
|
await Task.Delay(RetryInterval, stoppingToken);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task InitializeAsync(CancellationToken cancellationToken)
|
|
{
|
|
await using var channel = await _connection.CreateChannelAsync(cancellationToken);
|
|
|
|
await channel.ExchangeDeclareAsync(
|
|
exchange: _settings.Exchange,
|
|
type: ExchangeType.Direct,
|
|
durable: true,
|
|
autoDelete: false,
|
|
arguments: null,
|
|
cancellationToken: cancellationToken);
|
|
|
|
_logger.LogInformation("Exchange 선언 완료: {Exchange}", _settings.Exchange);
|
|
|
|
var queueArgs = new Dictionary<string, object?>
|
|
{
|
|
{ "x-message-ttl", _settings.MessageTtl }
|
|
};
|
|
|
|
await channel.QueueDeclareAsync(
|
|
queue: _settings.PushQueue,
|
|
durable: true,
|
|
exclusive: false,
|
|
autoDelete: false,
|
|
arguments: queueArgs,
|
|
cancellationToken: cancellationToken);
|
|
|
|
await channel.QueueBindAsync(
|
|
queue: _settings.PushQueue,
|
|
exchange: _settings.Exchange,
|
|
routingKey: "push",
|
|
cancellationToken: cancellationToken);
|
|
|
|
_logger.LogInformation("Queue 선언 및 바인딩 완료: {Queue} → {Exchange} (routing_key: push)",
|
|
_settings.PushQueue, _settings.Exchange);
|
|
|
|
await channel.QueueDeclareAsync(
|
|
queue: _settings.ScheduleQueue,
|
|
durable: true,
|
|
exclusive: false,
|
|
autoDelete: false,
|
|
arguments: queueArgs,
|
|
cancellationToken: cancellationToken);
|
|
|
|
await channel.QueueBindAsync(
|
|
queue: _settings.ScheduleQueue,
|
|
exchange: _settings.Exchange,
|
|
routingKey: "schedule",
|
|
cancellationToken: cancellationToken);
|
|
|
|
_logger.LogInformation("Queue 선언 및 바인딩 완료: {Queue} → {Exchange} (routing_key: schedule)",
|
|
_settings.ScheduleQueue, _settings.Exchange);
|
|
}
|
|
}
|