Obrigado pela ajuda!!! Sou novo no Artemis, mas fiquei realmente surpreso com seu potencial!
Estou trabalhando com o ActiveMQ Artemis e um cliente Python criado com o Qpid Proton (versão 0.39.0
). Estou tentando entender como rejeitar ou liberar uma mensagem no Proton Python para que o Artemis tente a reentrega , respeitando a <max-delivery-attempts>
configuração definida em broker.xml
.
Aqui está o contexto:
- Versão do Artemis: 2.40.0 (Docker)
- Versão do Qpid Proton Python: 0.39.0
- Cliente Python: Consome mensagens usando
proton.handlers.MessagingHandler
- Comportamento esperado: Se o cliente não conseguir processar uma mensagem (por exemplo, erro interno), ele deverá sinalizar ao Artemis para tentar novamente a entrega. Após o número configurado de tentativas (
max-delivery-attempts
), o Artemis deverá mover a mensagem para o DLQ .
seção relevante do broker.xml:
<address-setting match="#">
<max-delivery-attempts>5</max-delivery-attempts>
<redelivery-delay>5000</redelivery-delay>
<dead-letter-address>DLQ</dead-letter-address>
<auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
<dead-letter-queue-suffix>.DLQ</dead-letter-queue-suffix>
</address-setting>
Lógica do cliente Python:
Em on_message
, liberamos a mensagem quando o retorno de chamada HTTP falha:
self.release(event.delivery, delivered=True)
Também tentamos:
self.settle(event.delivery, state=Delivery.RELEASED)
Mas nenhuma das duas pareceu fazer Artemis aumentar a contagem de entregas . Artemis continua entregando a mesma mensagem infinitamente e nunca a move para o DLQ.
Também tentamos adicionar isso (sugerido na documentação do Artemis), mas o Artemis não conseguiu iniciar:
<persist-delivery-count-before-delivery>true</persist-delivery-count-before-delivery>
Pergunta:
Qual é a maneira correta de liberar ou rejeitar uma mensagem no Qpid Proton Python para que Artemis:
- Considera isso uma tentativa de entrega falhada e
- Eventualmente envia para o DLQ depois
max-delivery-attempts
?
Muito obrigado novamente!!
RESOLUÇÃO: Eu não estava atualizando o objeto de estado local antes de liberar a mensagem. Portanto, para usar a política max-delivery-attempts com o DLQ definido em broker.xml, é necessário preencher estas propriedades locais:
def on_message(self, evento): mensagem = evento.mensagem status = send_message_callback(self.inscrição["url_de_destino"], mensagem.corpo)
if 200 <= status < 300:
self.accept(event.delivery)
else:
# Explicitly NACK the message
local_state = event.delivery.local
local_state.failed = True
local_state.undeliverable = False
local_state.type = event.delivery.MODIFIED
event.delivery.update(local_state)
self.release(event.delivery, delivered=True)
Na maioria dos casos, você deve enviar uma disposição modificada com o sinalizador de falha de entrega definido como verdadeiro se quiser que o servidor trate a mensagem como uma tentativa malsucedida e aumente a contagem de entregas. Se fizer isso, não defina a opção "não entregue" aqui, a menos que queira que o servidor evite enviar a mensagem novamente na mesma conexão.