Share via


Visão geral de filas

Esta seção apresenta os conceitos gerais e principais por trás da comunicação em fila. As seções subsequentes entram em detalhes sobre como os conceitos de enfileiramento descritos aqui são manifestados no WCF (Windows Communication Foundation).

Conceitos básicos de enfileiramento

Ao criar um aplicativo distribuído, é importante escolher o transporte certo para comunicação entre serviços e clientes. Vários fatores afetam o tipo de transporte a ser usado. Um fator importante – o isolamento entre o serviço, o cliente e o transporte – determina o uso de um transporte na fila ou de um transporte direto, como TCP ou HTTP. Devido à natureza dos transportes diretos, como TCP e HTTP, a comunicação será interrompida completamente se o serviço ou o cliente parar de funcionar ou a rede falhar. O serviço, o cliente e a rede devem estar em execução ao mesmo tempo para que o aplicativo funcione. Os transportes e, fila fornecem isolamento, o que significa que, se o serviço ou o cliente falhar, ou os links de comunicação entre eles falharem, o cliente e o serviço poderão continuar funcionando.

As filas fornecem comunicação confiável mesmo com falhas nas partes de comunicação ou na rede. As filas capturam e entregam mensagens trocadas entre as partes de comunicação. As filas normalmente são apoiadas por algum tipo de repositório, que pode ser volátil ou durável. As filas armazenam mensagens de um cliente em nome de um serviço e, posteriormente, encaminham essas mensagens para o serviço. As filas de indireção fornecem isolamento garantido de falha por qualquer uma das partes, tornando-se assim o mecanismo de comunicação preferido para sistemas de alta disponibilidade e serviços desconectados. A indireção vem com o custo de alta latência. Latência é o atraso de tempo entre a hora em que o cliente envia uma mensagem e a hora em que o serviço a recebe. Isso significa que, depois que uma mensagem é enviada, você não sabe quando essa mensagem pode ser processada. A maioria dos aplicativos na fila lida com alta latência. A ilustração a seguir mostra um modelo conceitual de comunicação na fila.

Model of queued communication

Modelo conceitual de comunicação em fila

Na realidade, a fila é um conceito distribuído. Como tal, eles podem ser locais para qualquer uma das partes ou remotos para ambas as partes. Normalmente, a fila é local para o serviço. Nessa configuração, o cliente não pode depender da conectividade com a fila remota para estar constantemente disponível. Da mesma forma, a fila deve estar disponível independentemente da disponibilidade da leitura do serviço da fila. Um gerenciador de filas gerencia uma coleção de filas. Ele é responsável por aceitar mensagens enviadas para suas filas de outros gerenciadores de filas. Ele também é responsável por gerenciar a conectividade com filas remotas e transferir mensagens para essas filas remotas. Para garantir a disponibilidade de filas, apesar das falhas do aplicativo de cliente ou serviço, o gerenciador de filas normalmente é executado como um serviço externo.

Quando um cliente envia uma mensagem para uma fila, ele endereça a mensagem para a fila de destino, que é a fila gerenciada pelo gerenciador de filas do serviço. O gerenciador de filas no cliente envia a mensagem para uma fila de transmissão (ou saída). A fila de transmissão é uma fila no gerenciador do cliente que armazena mensagens para transmissão para a fila de destino. Em seguida, o gerenciador de fila encontra um caminho para o gerenciador que possui a fila de destino e transfere a mensagem para ele. Para garantir uma comunicação confiável, os gerenciadores de fila implementam um protocolo de transferência confiável para evitar a perda de dados. O gerenciador de filas de destino aceita mensagens endereçadas às filas de destino que possui e armazena as mensagens. O serviço faz solicitações para ler da fila de destino, momento em que o gerenciador de filas entrega a mensagem para o aplicativo de destino. A ilustração a seguir mostra a comunicação entre as quatro partes.

Queued Application Diagram

Comunicação e, fila em um cenário de implantação típico

Assim, o gerenciador de filas fornece o isolamento necessário para que a falha de emissor e receptor ocorram independentemente, sem afetar a comunicação real. O benefício da indireção extra que as filas fornecem também permite que várias instâncias de aplicativo sejam lidas da mesma fila, de modo que o trabalho de farm entre os nós atinja maior taxa de transferência. Portanto, não é incomum ver filas sendo usadas para atingir requisitos de maior escala e taxa de transferência.

Filas e transações

As transações permitem agrupar um conjunto de operações para que, se uma operação falhar, todas as operações falhem. Um exemplo de como usar transações é quando uma pessoa usa um caixa eletrônico para transferir US$ 1.000 de sua conta poupança para sua conta corrente. Isso envolve as seguintes operações:

  • Retirando $1.000 da conta poupança.

  • Depositando $1.000 na conta corrente.

Se a primeira operação for bem-sucedida, e US$ 1.000 for retirado da conta poupança, mas a segunda operação falhar, os US$ 1.000 serão perdidos porque já foram retirados da conta poupança. Para manter as contas em um estado válido, se uma operação falhar, ambas as operações deverão falhar.

Em mensagens transacionais, as mensagens podem ser enviadas para a fila e recebidas da fila em uma transação. Portanto, se uma mensagem for enviada em uma transação e a transação for revertida, será como se a mensagem nunca tivesse sido enviada para a fila. Da mesma forma, se uma mensagem for recebida em uma transação e a transação for revertida, será como se a mensagem nunca tivesse sido recebida. A mensagem permanece na fila a ser lida.

Devido à alta latência, ao enviar uma mensagem, você não tem como saber quanto tempo leva para atingir sua fila de destino, nem quanto tempo leva para o serviço processar a mensagem. Por isso, não convém usar uma única transação para enviar a mensagem, receber a mensagem e processar a mensagem. Isso cria uma transação que não é confirmada por um período indeterminado de tempo. Quando um cliente e um serviço se comunicam por meio de uma fila usando uma transação, duas transações são envolvidas: uma no cliente e outra no serviço. A ilustração a seguir mostra os limites de transação na comunicação em fila típica.

Queue with transactions

Comunicação em fila mostrando transações separadas para captura e entrega

A transação do cliente processa e envia a mensagem. Quando a transação é confirmada, a mensagem está na fila de transmissão. No serviço, a transação lê a mensagem da fila de destino, processa a mensagem e confirma a transação. Se ocorrer um erro durante o processamento, a mensagem será revertida e colocada na fila de destino.

Comunicação assíncrona usando filas

As filas fornecem um meio assíncrono de comunicação. Os aplicativos que enviam mensagens usando filas não podem esperar que a mensagem seja recebida e processada pelo destinatário devido à alta latência introduzida pelo gerenciador de filas. As mensagens podem permanecer na fila por muito mais tempo do que o aplicativo pretendia. Para evitar isso, o aplicativo pode especificar um valor de tempo de vida na mensagem. Esse valor especifica quanto tempo a mensagem deve permanecer na fila de transmissão. Se esse valor de tempo for excedido e a mensagem ainda não tiver sido enviada para a fila de destino, a mensagem poderá ser transferida para uma fila de mensagens mortas.

Quando o remetente envia uma mensagem, o retorno da operação de envio implica que a mensagem apenas chegou à fila de transmissão do remetente. Assim, se houver uma falha na obtenção da mensagem para a fila de destino, o aplicativo de envio não poderá saber disso imediatamente. Para anotar essas falhas, a mensagem com falha é transferida para uma fila de mensagens mortas.

Qualquer erro, como uma falha de mensagem ao atingir a fila de destino ou a expiração do Vida Útil, deve ser processado separadamente. Não é incomum, portanto, que aplicativos em fila escrevam dois conjuntos de lógica:

  • O cliente típico e a lógica de serviço de envio e recebimento de mensagens.

  • Lógica de compensação para lidar com mensagens da transmissão ou entrega com falha.

As seções a seguir discutem esses conceitos.

Programação de fila de Mensagens Mortas

As filas de mensagens mortas contêm mensagens que falharam ao atingir a fila de destino por vários motivos. Os motivos podem variar de mensagens expiradas a problemas de conectividade que impedem a transferência da mensagem para a fila de destino.

Normalmente, um aplicativo pode ler mensagens de uma fila de mensagens mortas em todo o sistema, determinar o que deu errado e tomar a ação apropriada, como corrigir os erros e reenviar a mensagem ou anotá-la.

Programação da Fila de Mensagens Suspeitas

Depois que uma mensagem chega à fila de destino, o serviço pode falhar repetidamente ao processar a mensagem. Por exemplo, um aplicativo lendo uma mensagem da fila em uma transação e atualizando um banco de dados pode encontrar o banco de dados temporariamente desconectado. Nesse caso, a transação é revertida, uma nova transação é criada e a mensagem é relida da fila. Uma segunda tentativa pode ter êxito ou falhar. Em alguns casos, dependendo da causa do erro, a mensagem pode falhar repetidamente na entrega ao aplicativo. Nesse caso, a mensagem é considerada "suspeita". Essas mensagens são movidas para uma fila suspeita que pode ser lida por um aplicativo de manipulação de mensagens suspeitas.

Confira também