메시지를 다시 시도하기 전에 Azure 서비스 버스를 지연시킬 수 있습니까?
Azure 서비스 버스는 포기 메시지를 다른 읽기 시도에서 즉시 볼 수 있도록 하는 내장된 재시도 메커니즘을 지원합니다.이 메커니즘을 사용하여 일시적인 오류를 처리하려고 합니다만, 메시지는 포기된 직후에 사용할 수 있습니다.
이 경우 메시지가 폐기된 후 일정 시간 동안 표시되지 않도록 하고 가급적 기하급수적으로 증가하는 정책을 기반으로 합니다.
ScheduledEnqueueTimeUtc
메시지를 폐기할 때 속성을 표시하지만 효과가 없는 것 같습니다.
var messagingFactory = MessagingFactory.CreateFromConnectionString(...);
var receiver = messagingFactory.CreateMessageReceiver("test-queue");
receiver.OnMessageAsync(async brokeredMessage =>
{
await brokeredMessage.AbandonAsync(
new Dictionary<string, object>
{
{ "ScheduledEnqueueTimeUtc", DateTime.UtcNow.AddSeconds(30) }
});
}
});
를 전혀 이 만료되도록 이렇게 '잠금 만료'가 어떻게 알수 있어야 합니다.MessageReceiver
메시지의 잠금 기간을 지정했는데 API에서 이 값을 변경할 수 있는 항목을 찾을 수 없습니다.또한 잠금이 이미 필요할 때까지 메시지의 배달 횟수를 읽을 수 없습니다(따라서 다음 재시도를 기다리는 시간을 결정합니다).
메시지 버스의 리트라이 정책은 어떤 식으로든 영향을 받을 수 있습니까, 아니면 다른 방법으로 지연을 인위적으로 도입할 수 있습니까?
을 자동 리트라이 기능과 것 .Complete
/Abandon
의 OnMessage
이 실패했을 때 됩니다.내장 리트라이 메커니즘은 서비스 버스에 대한 콜이 실패했을 때 활성화됩니다.예를 들어, 메시지를 완료로 설정하기 위해 에 전화를 걸었을 때 실패했을 경우 재시도 메커니즘이 실행됩니다.메시지를 처리하는 경우 재시도 기능을 통해 재시도를 트리거하지 않는 예외가 자체 코드에서 발생합니다.에러가 코드에 의한 것인지, 또는 서비스 버스에의 접속을 시도하고 있는지에 대해서는, 질문이 명확해지지 않습니다.
하려고 할 때 했을 때 을 실제로 후 를 할 수 .RetryPolicy
로 되어 있다.MessageReciver
그 자체입니다. 게 있어요.RetryExponitial
인 것, 추상적인 것, 추상적인 것, 기본적으로 되고 있습니다.RetryPolicy
을 사용하다
당신이 원하는 것은 처리 중 예외를 발견했을 때 일어나는 일에 대한 더 많은 통제력이고, 당신은 그 메시지에 대한 작업을 미루고 싶어합니다.몇 가지 옵션이 있습니다.
메시지 핸들러를 작성할 때 OnMessageOptions를 설정할 수 있습니다.속성 중 하나는 "자동 완성"입니다.디폴트로는 이것은 true로 설정되어 있습니다.즉, 메시지 처리가 완료되는 즉시,Complete
이치노예외가 발생하면 포기가 자동으로 호출됩니다.자동 완료를 false로 설정하면 메시지 핸들러 내에서 사용자가 직접 Complete를 호출해야 합니다.이렇게 하지 않으면 메시지 잠금이 최종적으로 소진됩니다.이는 사용자가 찾고 있는 동작 중 하나입니다.
처리 했을 때 "예외"를 호출하지 를 쓸 수 .Complete
메시지는 잠금이 해제될 때까지 큐에 남아 있다가 다시 사용할 수 있게 됩니다.표준 데드 레터링 메커니즘이 적용되어 x회 시도 후 데드 레터 큐에 자동으로 들어갑니다.
이 방법으로 처리할 때 주의해야 할 점은 모든 유형의 예외가 이 방식으로 처리된다는 것입니다.어떤 유형의 예외가 이 작업을 수행하는지, 그리고 정말로 처리를 연기할 것인지 생각해 볼 필요가 있습니다.예를 들어 처리 중에 서드파티 시스템을 호출할 때 일시적인 예외로 간주되는 경우 매우 좋습니다.다만, 큰 문제가 되는 것을 알고 있는 에러가 발생했을 경우는, 메세지에 의지하는 것 이외에, 시스템에서 다른 조작을 실시할 수도 있습니다.
,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.Defer
method." 이 방법에서는 시퀀스 번호에 의해 특별히 풀되지 않는 한 해당 메시지가 큐에서 처리되지 않습니다.코드는 시퀀스 번호 값을 기억하고 당겨야 합니다.하지만 이건 네가 말한 것과 완전히 다르잖아.
또 다른 옵션은 OnMessage, 이벤트 기반 메시지 처리 스타일에서 벗어날 수 있습니다.이것은 매우 도움이 되지만, 당신은 사물을 잘 통제하지 못합니다.대신 자신의 처리 루프를 연결하고 포기/완료를 스스로 처리하십시오.또한 OnMessage 패턴이 제공하는 스레드/동시 통화 관리도 일부 처리해야 합니다.이것은 더 많은 작업이 될 수 있지만, 당신은 최고의 유연성을 가지고 있습니다.
이 지지에게 를 건 .AbandonAsync
수정하려는 속성을 전달해도 작동하지 않습니다. 이러한 속성이 Brokred Message의 표준 속성이 아닌 메서드의 메타데이터 속성을 참조하고 있습니다.
실제로 작년에 (실장과는 별도로) 이 질문을 했습니다. API를 검토할 수 있는 세 가지 접근방식을 생각할 수 있었습니다.@ClemensVasters는 SB팀에서 일하고 있습니다.Defer
정확하게 제어할 수 있는 유일한 방법이에요
세컨더리 큐를 사용하여 지연되어 메인 큐에서 다시 수신해야 하는 메시지를 저장하는 경우 구체적인 접근법에 대한 제 코멘트를 읽어보실 수 있습니다.에 '기다리다'를 '기다리다'로 할 수 .ScheduledEnqueueTimeUtc
재시도할 때까지의 대기시간을 정확하게 제어하기 위해서, 이러한 secondary messages를 사용합니다.
비슷한 문제에 부딪혔는데, 주문 선정 시스템이 레거시여서 매일 밤 유지보수 모드로 전환됩니다.
이 기사의 아이디어(https://markheath.net/post/defer-processing-azure-service-bus-message))를 사용하여 메시지가 재발송된 횟수를 추적하고 10회 시도 후 메시지를 수동으로 데드 레터링하는 커스텀 속성을 만들었습니다.메시지가 10회 재시도 미만일 경우 메시지는 커스텀속성을 증가시키고 새 메시지의 en 큐를 설정합니다.
using Microsoft.Azure.ServiceBus;
public PickQueue()
{
queueClient = new QueueClient(QUEUE_CONN_STRING, QUEUE_NAME);
}
public async Task QueueMessageAsync(int OrderId)
{
string body = JsonConvert.SerializeObject(OrderId);
var message = new Message(Encoding.UTF8.GetBytes(body));
await queueClient.SendAsync(message);
}
public async Task ReQueueMessageAsync(Message message, DateTime utcEnqueueTime)
{
int resubmitCount = (int)(message.UserProperties["ResubmitCount"] ?? 0) + 1;
if (resubmitCount > 10)
{
await queueClient.DeadLetterAsync(message.SystemProperties.LockToken);
}
else
{
Message clone = message.Clone();
clone.UserProperties["ResubmitCount"] = ++resubmitCount;
await queueClient.ScheduleMessageAsync(message, utcEnqueueTime);
}
}
이 질문에서는 Azure 함수에서 지수 백오프를 구현하는 방법을 묻습니다.내장된 RetryPolicy를 사용하지 않는 경우(다음 경우에만 사용 가능)autoComplete = false
지금까지 사용하고 있는 솔루션은 다음과 같습니다.
public static async Task ExceptionHandler(IMessageSession MessageSession, string LockToken, int DeliveryCount)
{
if (DeliveryCount < Globals.MaxDeliveryCount)
{
var DelaySeconds = Math.Pow(Globals.ExponentialBackoff, DeliveryCount);
await Task.Delay(TimeSpan.FromSeconds(DelaySeconds));
await MessageSession.AbandonAsync(LockToken);
}
else
{
await MessageSession.DeadLetterAsync(LockToken);
}
}
언급URL : https://stackoverflow.com/questions/21536722/can-the-azure-service-bus-be-delayed-before-retrying-a-message
'programing' 카테고리의 다른 글
프로세스 종료 코드를 기반으로 한 셸 스크립트 종료 (0) | 2023.04.21 |
---|---|
Bat 파일을 사용하여 Windows를 셧다운, 재시작 또는 로그오프하려면 어떻게 해야 합니까? (0) | 2023.04.21 |
Asp.net WebApi 커스텀 인증 - 엉망진창? (0) | 2023.04.21 |
내 구독의 파란색 저장소 계정에 사용된 공간 확인 (0) | 2023.04.21 |
ImportError: win32com.client라는 이름의 모듈이 없습니다. (0) | 2023.04.21 |