fix: RabbitMQ 연결 실패 시 앱 크래시 방지 (#124)

- StartAsync에서 throw 제거, LogWarning으로 변경
- InitializeAsync 메서드 분리 (재시도 가능)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
seonkyu.kim 2026-02-10 19:05:13 +09:00
parent 975ed77d18
commit 4f806ecdb1

View File

@ -26,66 +26,67 @@ public class RabbitMQInitializer : IHostedService
{ {
try try
{ {
await using var channel = await _connection.CreateChannelAsync(cancellationToken); await InitializeAsync(cancellationToken);
// Exchange 선언: Direct, Durable
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 }
};
// Push Queue 선언
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);
// Schedule Queue 선언
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);
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "RabbitMQ Exchange/Queue 초기화 실패"); _logger.LogWarning(ex, "RabbitMQ 초기화 실패 — 서버는 계속 실행됩니다. 메시지 발송 시 재연결을 시도합니다.");
throw;
} }
} }
public 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);
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
} }