Compartilhar via


Visão geral das filas

Esta seção apresenta os conceitos gerais e principais por trás da comunicação na 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 projetar 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 enfileirado 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 se 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 enfileirados fornecem isolamento, o que significa que, se o serviço ou o cliente falhar ou se 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 comunicantes. 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.

Modelo de comunicação em fila

Modelo conceitual de comunicação em fila

Na realidade, a fila é um conceito distribuído. Como tal, eles podem ser locais para 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 administrador 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 de filas do cliente que armazena mensagens para transmissão para a fila de destino. Em seguida, o gerenciador de filas encontra um caminho para o gerenciador de filas que possui a fila de destino e transfere a mensagem para ela. 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.

Diagrama de aplicativo enfileirado

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

Assim, o gerenciador de filas fornece o isolamento necessário para que o remetente e o receptor possam falhar 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 implica 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 forem retirados 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.

No sistema de 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, o resultado 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, o resultado será como se a mensagem nunca tivesse sido recebida. A mensagem permanece na fila a ser lida.

Devido à alta latência, quando você envia uma mensagem, não tem como saber quanto tempo leva para atingir sua fila de destino, nem sabe quanto tempo leva para o serviço processar a mensagem. Por isso, você não deseja 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 da transação na comunicação em fila típica.

Fila com transações

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

O cliente processa a transação 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. Aplicativos que enviam mensagens usando filas não podem esperar que a mensagem seja recebida e processada pelo receptor devido à alta latência introduzida pelo gerenciador de filas. As mensagens podem permanecer na fila por muito mais tempo do que o aplicativo pretendido. Para evitar isso, o aplicativo pode especificar um valor time-To-Live na mensagem. Esse valor especifica por 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 só chegou à fila de transmissão no remetente. Dessa forma, se houver uma falha ao levar a 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 os aplicativos enfileirados escrevam dois conjuntos de lógicas.

  • A lógica normal do cliente e do serviço de enviar e receber mensagens.

  • Lógica de compensação para tratar mensagens de falha na transmissão ou entrega.

As seções a seguir discutem esses conceitos.

Dead-Letter Programação de Fila

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 as medidas apropriadas, como corrigir os erros e reenviar a mensagem ou tomar nota dela.

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 que lê uma mensagem da fila em uma transação e atualiza 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 para o aplicativo. Nesse caso, a mensagem é considerada como "veneno". Essas mensagens são movidas para uma fila de venenos que pode ser lida por um aplicativo de tratamento de veneno.

Consulte também