Confiabilidade em Sistemas Conectados

Roger Wolter

Publicado em: 11 de outubro de 2006

Os aplicativos de sistemas conectados são compostos por vários serviços fracamente acoplados que geralmente estão espalhados em uma rede; portanto, a obtenção de altos níveis de confiabilidade e disponibilidade em aplicativos de sistemas conectados representa um conjunto único de desafios arquitetônicos. Por exemplo: se uma aplicação pára de funcionar por que um dos dez serviços executados em dez servidores diferentes não está disponível, a taxa de falha do aplicativo é cerca de dez vezes maior que a taxa de falha dos serviços individuais. A falha de dados torna esse problema muito mais crítico, já que uma fonte de dados pode ser usada por dezenas de serviços. Esse artigo trata dos problemas de confiabilidade que devem ser considerados ao arquitetar um aplicativo de serviços conectados e mostra como alguns dos novos recursos do SQL Server 2005 e dos produtos de troca de mensagens da Microsoft abordam esses problemas.

Nesta página

Um Peso para a Infra-estrutura
Entrega de Mensagens
Escolher uma infra-estrutura de mensagem
Confiabilidade na Execução
Mensagem Perdida
Confiabilidade dos Dados
Recursos
Sobre o Autor

Sob o ponto de vista do hardware, do software e da manutenção, a confiabilidade é cara - portanto, é muito importante entender os requisitos de confiabilidade de aplicativo. Embora um aplicativo sem requisitos de confiabilidade seja raro, a implementação de um aplicativ o com confiabilidade maior do que a necessária pode ser um desperdício de tempo e recursos. Por isso, é importante entender os problemas de confiabilidade dos sistemas conectados, para poder arquitetar uma solução que proporcione o nível adequado de confiabilidade, mas sem desperdiçar recursos com uma confiabilidade além do necessário.

Na SOA (Arquitetura Orientada a Serviços), também conhecida como sistemas conectados, os serviços se comunicam entre si por meio de formatos de mensagens bem-definidos; isso significa que a confiabilidade do aplicativo de sistemas conectados sofrerá uma grande influência da confiabilidade da infra-estrutura de mensagens que ele usa para fazer a comunicação entr e os serviços. Usaremos como ex emplo os serviços de um aplicativo de caixa eletrônico para ilustrar os diversos graus de confiabilidade do sistema de mensagens e como eles são obtidos. Geralmente, o processamento de mensagens entre serviços é mais complexo que o das mensagens entre cliente e servidor, porque as mensagens cliente/servidor podem contar com o usuário para tomar decisões sobre o modo de lidar com várias situações de erro e limites de tempo, ao passo que o servidor que inicia a troca nas mensagens de servidor a servidor precisa tomar todas as decisões que normalment e seriam tomadas pelo usuário final em uma interação cliente/servidor.

Um Peso para a Infra-estrutura

Muitas aplicações orientadas a serviços atingem uma taxa de transferência melhor usando um sistema de mensagens assíncrono.

Com esse sistema, um serviço envia uma mensagem a outro serviço sem esperar a resposta da mensagem para continuar. O serviço processa muito mais solicitações porque não perde tempo esperando respostas às solicitações que ele faz a outros serviços; em vez disso, deixa o encargo de garantir que a mensagem seja entregue e processada à infra-estrutura de mensagens. A opção pelo processament o síncrono ou assíncrono de mensagens geralmente é determinada pelos requisit os de negócio do aplicativo.

Por exemplo: se um cliente está tentando sacar dinheiro de um ATM (Caixa Eletrônico), o ato de fazer uma solicitação síncrona para verificar o saldo do cliente e liberar o dinheiro sem esperar a resposta do saldo bancário geralment e não é uma decisão de negócios correta. Entretanto, esse cenário não descarta solicitações assíncronas. O caixa eletrônico pode despachar uma solicitação de saldo assim que o cliente seleciona a opção de saque e, em seguida, permitir que o cliente digite a quantia enquanto a verificação do saldo é realizada de forma assíncrona. Assim que a quantidade do saque é digitada e o saldo é recebido, o aplicativo de caixa eletrônico pode tomar a decisão de liberar ou não o dinheiro.

Vamos ver como o caixa eletrônico processa a mensagem de solicitação de saldo. O serviço de caixa eletrônico enviará a mensagem de solicitação de saldo ao serviço de contas para obter o saldo da conta do cliente. Nesse ponto, uma dessas três coisas irá acontecer: O saldo será retornado com êxito, um erro será retornado ou o tempo limite da solicitação irá expirar porque o resultado não foi retornado no tempo certo. Se o saldo é retornado, o serviço de caixa continua com a transação. Se um erro é retornado, o caixa eletrônico usa a sua lógica de negócio para trabalhar com ele - talvez, usando uma cópia em cache do saldo ou liberando ou não o dinheiro dependendo da quantia solicitada. A situação mais difícil de trabalhar é o limite de tempo. O estouro do limite de tempo pode significar que a mensagem se perdeu em trânsito, a mensagem chegou ao serviço de contas, mas a resposta atrasou por alguma razão ou a resposta foi enviada e se per deu no caminho de volta.

Na maioria dos casos, a melhor resposta é tentar novamente e esperar que funcione melhor da próxima vez. Se a mensagem tiver se perdido na volta da primeira vez, pode chegar dessa vez. Se a resposta estava lenta a resposta original pode chegar antes do limite de tempo da segunda solicitação. A não ser que o sistema de contas esteja inacessível ou completamente inoperante, as novas tentativas acabam dando certo. Dependendo do problema, a solicitação de saldo pode ter sido processada várias vezes, ou vários resultados podem ser recebidos, mas, desde que o serviço de caixa eletrônico esteja preparado para trabalhar com eles, esses problemas não são graves.

Se a mensagem tiver sido enviada de forma assíncrona, o serviço de caixa eletrônico poderá não ter as informações à disposição para reenviar a mensagem quando se solicita uma nova tentativa - portanto, a infraestrutura de mensagens precisará manter uma cópia das mensagens enviadas e reenviá-las se necessário. Para esse tipo de mensagem de solicitação simples, manter uma cópia da mensagem na memória provavelmente é adequado porque, se o caixa eletrônico ficar sem energia, o cliente terá que começar novamente de qualquer forma. Se o serviço de caixa eletrônico precisar de uma resposta até mesmo depois de uma queda de energia, a mensagem terá que ser colocada em algum armazenamento persistente, e o sistema de mensagens terá que reenviá-la quando for reiniciado. A Figura 1 mostra três possíveis resultados de uma solicitação de saldo.

Entrega de Mensagens

Para a versão síncrona dessa solicitação, um serviço da Web simples em SOAP poporciona o grau necessário de confiabilidade. O processamento de erros e do limite de tempo é de responsabilidade do serviço de caixa eletrônico e, portanto, ele determinará o nível de confiabilidade da solicitação. Para a versão assíncrona da solicitação de saldo, ou o canal WS-RM do WCF (Windows Communication Foundation) ou a entrega expressa do MSMQ proporcionará a confiabilidade necessária se a solicitação não precisar "sobreviver" a falhas do sistema. Se a mensagem precisar sobreviver ao reinício do sistema, a entrega recuperável do MSMQ é a opção adequada. Esses sistemas de mensagem processarão os limites de tempo e as nov as tentativ as que se fizerem necessários para entregar a mensagem e a resposta, para que o serviço de ATM não tenha que incluir essa lógica.

Agora que entendemos os problemas de confiabilidade em uma solicitação de saldo, vamos passar à solicitação de alteração de saldo que acontece depois da liberação do dinheiro. Os requisitos de confiabilidade dessa mensagem são muito mais altos porque, se ela não for entregue com sucesso, o banco dará dinheiro ao cliente sem reduzir o saldo da conta dele. Embora o cliente provavelmente não vá reclamar, o banco não ficará satisfeito se essa situação acontecer regularmente.

A mensagem de alteração de saldo tem que ser entregue e processada, independentemente de qualquer falha de rede ou de sistema. O mecanismo de nova tentativa baseado na memória obviamente não é adequado para essa tarefa, porque, em uma falha do sistema, a cópia da mensagem mantida para novas tentativas é perdida. A manutenção de uma cópia persistente da mensagem para novas tentativas também pode ser um problema, por que é possível que várias cópias da mensagem sejam enviadas por causa das tentativas. Se a mensagem descontar $200.00 do saldo da conta do cliente, por exemplo, a entrega repetida da mensagem poderá causar insatisfação do cliente.

As tentativas necessárias para garantir a entrega confiável da mensagem só funcionam se as mensagens forem idempotentes. Uma mensagem idempotente pode ser entregue várias vezes sem violar as restrições de negócio do aplicativo. Algumas mensagens são naturalmente idempotentes. Por exemplo: uma mensagem que altera o endereço do cliente pode ser executada várias vezes sem efeitos prejudiciais. Outras mensagens não são naturalmente idempotentes então, o sistema de mensagens precisa torná-las idempoten es para evitar o dano que pode resultar do processamento repetido de uma mensagem (consulte as Figuras 2 e 3). Normalmente, essa transação é feita mantendo-se uma lista das mensagens que já foram processadas; se a mesma mensagem for recebida mais de uma vez, ela não será processada mais de uma vez.

A maioria dos sistemas de mensagem não mantém uma cópia das mensagens que entram, mas o remetente atribui um identificador a cada mensagem e o destinatário faz o acompanhamento dos identificadores que já viu. Esses identificadores devem ser mantidos até que o destino da mensagem tenha certeza de que a origem descartou a mensagem porque, se a origem falhar, a mensagem será enviada novamente dias depois, quando a origem for reiniciada. A lista de mensagens processadas também deve ser persistente porque o serviço de destino pode falhar entre as tentativas. O destino também precisa rastrear a mensagem que foi enviada em resposta à mensagem de entrada, porque a origem ficará enviando a mensagem original até receber a resposta; o motivo da nova tentativa pode ser a perda da mensagem de resposta original.

Bb245677.fig01(pt-br,MSDN.10).png

Figura 01

Escolher uma infra-estrutura de mensagem

A não ser que você queira persistir e rast ear as mensagens na lógica do seu serviço, precisará de uma infra-estrutura de mensagem confiável para proporcionar esse nível de confiabilidade. A Microsoft oferece três opções para essa infra-estrutura: mensagem recuperável do MSMQ, SQL Server Service Broker e Bizalk. A opção escolhida depende dos requisitos de confiabilidade e do projeto do aplicativo.

O Service Broker e o BizTalk oferecem um armazenamento de mensagens mais confiável que o do MSMQ, porque ele armazena mensagens em um banco de dados SQL Server, ao passo que o MSMQ as armazena em um arquivo. Se o seu aplicativo puder funcionar com a perda ocasional de mensagens quando um arquivo é perdido ou corrompido, o MSMQ é adequado às suas necessidades. Alguns aplicativos MSMQ protegem contra a possível perda de mensagens, armazenando uma cópia da mensagem em um banco de dados. Se você for armazenar mensagens, o uso do Service Broker, que já armazena mensagens no banco de dados normalmente, é muito mais eficiente.

O Service Broker e o BizTalk proporcionam praticamente o mesmo grau de confiabilidade e defesa contra a perda de mensagens porque ambos as armazenam no banco de dados. O processamento de mensagens do Service Broker está incorporado à lógica de processamento do banco de dados e, portanto, o Service Broker conversa diretamente do processo do SQL Server com os soquetes de TCP/IP algo muito mais eficiente que a abordagem do BizTalk, na qual um processo externo chama o banco de dados para armazenar as mensagens em uma tabela. Embora o Service Broker consiga entregar muito mais mensagens por segundo que o BizTalk, o BizT alk oferece uma grande quantidade de recursos transformação de mensagens, roteamento de mensagens de acordo com os dados, vários transportes de mensagens, orquestração etc, - que o Service Broker não oferece.

Em geral, se o seu aplicativo só precisa de uma transferência confiável de mensagens entre os bancos de dados, o Service Broker é a melhor opção, por ser mais leve e eficiente na transferência de mensagens que o BizTalk. Por outro lado, se o seu aplicativo requer os recursos de manipulação de mensagens e as integrações de dados que o BizTalk oferece, o Service Broker provavelmente não é a solução correta.

Embora as mensagens recuperáveis do MSMQ não proporcionem os níveis de confiabilidade que os recursos baseados no SQL Server oferecem, elas têm a vantagem de não precisar do SQL Server nas duas extremidades das mensagens. Se o suporte a um banco de dados nas duas extremidades está fora de cogitação e os requisitos de confiabilidade da aplicação podem ser cumpridos pelo MSMQ, o MSMQ é provavelmente a opção correta para a infra-estrutura de mensagens. Entretanto, se os dois sistemas de comunicação exigirem armazenamento de dados, a confiabilidade extra obtida com o armazenamento de mensagens no banco de dados vale à pena.

Bb245677.fig02(pt-br,MSDN.10).png

Figura 02

Bb245677.fig03(pt-br,MSDN.10).png

Figura 03

No nosso exemplo de caixa eletrônico, o serviço requer armazenamento local de dados para auditoria, armazenamento local para o peração offline e armazenamento de dados de referência; portanto, provavelmente haverá um banco de dados no caixa eletrônico de qualquer forma, e uma das opções baseadas no SQL Server é adequada. A escolha entre o Service Broker e o BizTalk depende dos requisitos do aplicativo que não estão relacionados a mensagens, dos recursos disponíveis no caixa eletrônico e dos requisitos de volume de mensagens.

Confiabilidade na Execução

Abordamos anteriormente a confiabilidade na entrega de mensagens de um serviço a outro. Não é de se surpreender que tenhamos constatado que o nível necessário de confiabilidade depende do que o aplicativo está fazendo e da importância dos dados da mensagem para o aplicativo. Neste texto, iremos pressupor que as mensagens sejam transferidas com o grau necessário de confiabilidade a um serviço e analisar os requisitos de confiabilidade para o serviço que processa as mensagens.

Um dos requisitos específicos de um serviço que processa mensagens assíncronas é que o recebimento de uma mensagem da fila é uma operação de "recepção". Em outras palavras, quando a mensagem chega a uma fila, ela fica lá até que o aplicativo execute uma operação de "recepção" para recuperar e processar a mensagem. Esse requisito significa que um serviço síncrono deve garantir a execução quando há mensagens na fila para ser em processadas. A forma mais comum de cumprir esse requisito é transformar o serviço em um serviço Windows gerenciado pelo Windows SCM (Service Control Manager). O SCM irá garantir que o serviço seja iniciado quando o Windows for iniciado pode ser configurado para reiniciar o serviço caso ele falhe por alguma razão.

Embora essa configuração geralmente proporcione o nível de confiabilidade necessário e, em geral, seja a solução preferida quando as mensagens chegam em um ritmo constante, ela pode causar problemas se a carga de mensagens variar de forma significativa. Se o serviço for configurado com recursos suficientes para processar picos de carga, isso será um desperdício de recursos quando a carga estiver baixa; se estiver configurado para processar a carga média, não conseguirá dar conta dos picos de carga. As mensagens do BizT alk operam como um serviço Windows e, portanto, um aplicativo com o BizTalk pode contar com o serviço Windows para processar as mensagens de entrada.

O MSMQ trata do problema da carga de mensagens por meio de disparadores que iniciam um serviço de processamento de mensagens sempre que uma mensagem chega à fila. Embora esse processamento funcione bem quando as mensagens chegam com pouca freqüência, quando a carga de mensagens é alta, a sobrecarga de iniciar mil cópias dos serviços pode ser maior que o da própria lógica do serviço.

Para resolver esse problema, o Service Broker o ferece um recurso chamado ativação. Quando uma mensagem chega a uma fila vazia, o Service Broker inicia um procedimento armazenado para processar a mensagem. Esse procedimento armazenado aguarda a chegada de mais mensagens em um loop e continua nesse loop até que a fila esteja vazia. Se o Service Broker determinar que o procedimento armazenado não está dando conta das mensagens que entram, ele iniciará cópias adicionais do procedimento armazenado até que haja cópias suficientes em execução. Quando a taxa de chegada de mensagens diminuir, a fila ficará vazia e as cópias extras sairão. Portanto, sempre haverá aproximadamente o número adequado de recursos disponíveis para trabalhar com as mensagens que entram. Com o o Service Broker inicia es ses procedimentos, ele será notificado se um deles falhar e substituirá a cópia com defeito. Se o serviço for um aplicativo externo em vez de um procedimento armazenado, o Service Broker o ferecerá ev entos, nos quais o aplicativo externo pode se inscrever, que notificarão o serviço quando houver necessidade de mais recursos para processar as mensagens de uma fila.

Mensagem Perdida

O outro problema de confiabilidade com o qual a execução do serviço tem que trabalhar é uma falha de serviço durante o processamento de uma mensagem. Se o serviço excluir uma mensagem da fila assim que a receber e, em seguida, falhar antes de processá-la completamente, essa mensagem estará efetivamente perdida. Da mesma forma, se o serviço aguardar o processamento completo da mensagem para removê-la da fila, uma falha entre a etapa do processamento e a remoção da mensagem fará com que a mensagem ainda esteja na fila, quando o serviço for reiniciado, e seja processada novamente.

Como já se mencionou anteriormente, o processamento da mesma mensagem várias vezes não é um problema se ela for uma consulta de saldo, mas o processamento de um saque duas vezes pode irritar o cliente. A única forma real de garantir que cada mensagem seja processada "exatamente uma vez" é fazer com que o processamento da mensagem e a exclusão da fila façam parte da mesma transação. Se houver uma falha no processamento, as alterações no processamento e a exclusão da mensagem serão retrocedidas, de forma que tudo volte a ser como era antes da recepção da mensagem.

Uma operação única de confirmação confirma as ações de recebimento e processamento da mensagem. Da mesma forma, se o processamento da mensagem gerar uma mensagem de saída, o "envio" da mensagem de saída deve fazer parte da transação, para evitar a situação em que o serviço é retrocedido, mas a mensagem é enviada assim mesmo. Esse tipo de processamento de mensagem é chamado de mensagem transacional. A maioria das infra-estruturas de mensagens confiáveis oferece suporte a mensagens transacionais.

Como as mensagens são armazenadas em um arquivo que não é o banco de dados, as mensagens transacionais do MSMQ requerem uma confirmação em duas fases para garantir que as duas partes da transação sejam confirmadas. Já que os comandos SEND e RECEIVE do Service Broker são comandos TSQL, as operações de mensagens e atualizações de dados em um serviço do Service Broker podem ser executadas na mesma conexão do SQL Server e fazer parte da mesma transação do SQL Server. Portanto, não há necessidade da confirmação em duas fases, e isso torna a implementação de mensagens transacionais do Service Broker muito mais eficiente do que a implementação do MSMQ.

Também nesse caso, as mensagens transacionais são necessárias para fazer um serviço não idempotente comportar-se como um serviço idempotente para eliminar os problemas causados pelas tentativas repetidas das mensagens. Se o serviço é idempotente por natureza, não há necessidade de mensagens transacionais. Se as mensagens transacionais não forem usadas, a pesso a que solicitou o serviço pr ecisa estar preparada para receber a resposta várias vezes e, ocasionalmente, ao longo de um grande intervalo de tempo.

Confiabilidade dos Dados

Agora abordaremos o impacto dos dados sobre a confiabilidade do serviço. A maioria dos serviços acessa dados enquanto processa as mensagens de serviço portanto, a confiabilidade dos dados está estreitamente ligada à confiabilidade dos serviços.

Um dos aspectos diferenciados da execução assíncrona do serviço é que em muitos casos, as mensagens de serviço são importantes objetos de negócio. No nosso serviço de caixa eletrônico, por exemplo, se as mensagens de alteração do saldo forem perdidas por causa de falhas, o saldo da conta não será alterado e o banco não perderá dinheiro. Por isso, armazenar mensagens no banco de dados para que tenham as mesmas proteções à confiabilidade, redundância e disponibilidade que restante dos dados a rmazenados no mesmo faz muito sentido. Se as mensagens de alteração do saldo, no nosso exemplo, forem armazenadas no mesmo banco de dados das contas, elas só serão perdidas se as contas também forem. Os backups, backups de registro e os recursos de SAN (Rede de Armazenamento) usados para garantir que as informações das contas bancárias não se percam também se aplicam às mensagens de alteração de saldo, tornando a confiabilidade do serviço extremamente alta. Se os seus requisitos de confiabilidade das mensagens forem altos, o Service Broker e o BizTalk têm vantagens significativas quanto à confiabilidade , já que armazenam as mensagens no banco de dados.

O DBM (Espelhamento de Banco de Dados) é um dos nov os recursos do SQL Server 2005 que pode aumentar a confiabilidade do serviço. O DBM proporciona confiabilidade mantendo uma cópia secundária do banco de dados que se mantém consistente quant o às transações do banco de dados primário, aplicando à cópia secundária todas as transações confirmadas no primário, antes de devolver o controle do serviço. Se o primário falhar, a cópia secundária do banco de dados poderá se tornar a primária em poucos segundos.

O Service Broker usa o espelhamento de banco de dados para melhorar a confiabilidade das mensagens. Se o banco de dados de contas for um par de bancos de dados em DBM, o banco de dados do Service Broker no caixa eletrônico abrirá conexões de rede para os bancos de dados primário e secundário e enviará mensagens ao primário. Se o banco de dados secundário se tornar o primário, o Service Broker será notificado imediatamente e as mensagens serão roteadas para o novo primário, sem interrupção nem intervenção do usuário.

Os serviços com intensa utilização de dados podem apr oveitar outro recurso do SQL Server 2005 para melhorar a confiabilidade. A integração do CLR (Common Language Runtime) ao mecanismo do servidor do SQL Server significa que a lógica do serviço pode ser executada também no banco de dados. Portanto, para um serviço do Service Broker, lógica, mensagens, ambiente de execução, context o de segurança e dados de serviço podem ficar no mesmo banco de dados.

Esse armazenamento em um único local apr esenta várias vantagens em um sistema que tem altos requisitos de confiabilidade. Geralmente, os servidores de bancos de dados têm os recursos de hardware e software para manter a alta confiabilidade exigida por um banco de dados. Agora essa confiabilidade pode ser aplicada a todos os aspectos da implementação do serviço. No caso improvável de uma falha de sistema, é possível restaurar todo o ambiente do serviço para um estado consistente em termos de transações por meio dos recursos de recuperação de banco de dados. Os dados são salvos e, além disso, odas as operações em andamento são retrocedidas e reiniciadas no mesmo ambiente de segurança e execução em que estavam no momento da falha.

A natureza assíncrona e livremente acoplada das aplicações voltadas a serviços apresenta requisitos específicos de confiabilidade. Ao arquitetar serviços, o nível de confiabilidade de que o serviço precisa deve ser compreendido elevado em conta. A Microsoft oferece várias infraestruturas para implementação de serviços, que oferecem diversos níveis de confiabilidade. A escolha da infra-estrutura correta envolve a correspondência entre o nível de confiabilidade necessário e os recursos da infra-estrutura. Os novos recursos do SQL Server 2005 proporcionam uma infra-estrutura de hospedagem de serviços que oferece níveis inéditos de confiabilidade a serviços que requerem níveis muito altos de confiabilidade.

Recursos

Arquitetura Orientada a Serviços

http://msdn.microsoft.com/architecture/soa/

"An Overview of SQL Server 2005 for the Database Developer," Matt Nunn (Microsoft Corporation, 2005)

http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnsql90/html/sql_ovyukondev.asp

"Building Reliable, Asynchronous Datab ase Applications Using Service Broker," Roger Wolter (Microsoft Corporation, 2005)

http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnsql90/html/sql2k5_SrvBrk.asp

Revista MSDN

Distributed .NET "Learn the ABCs of Programming Windows Communication Foundation, " Aaron Skonnard Microsoft Corporation, 2006)

http://msdn.microsoft.com/msdnmag/issues/06/02/WindowsCommunicationFoundation/

Microsoft Windows Server System - Microsoft BizTalk Server

http://www.microsoft.com/biztalk/

Sobre o Autor

Roger Wolter é arquiteto de soluções da equipe da Microsoft Architecture Strategy. Roger tem 30 anos de experiência em diversos aspectos do setor de informática, como trabalhos na Unisys, Infospan, Fourth Shift, e os últimos sete anos como ger ente de programa da Microsoft. Seus projetos na Microsoft englobam o SQLXML, o SOAP Toolkit, o SQL Server Service Broker e o SQL Server Express. Seu interesse pelo Service Broker surgiu por causa de um sistema de fabricação baseado em mensagens no qual ele trabalhou. Ele também escreveu The Rational Guide to SQL Server 2005 Service Broker Beta Preview (Rational Press, 2005).

Mostrar: