WS, ES e Remoting



Escolhendo entre WebServices, Enterprise Services e Remoting
Otavio Coelho - Arquiteto de Soluções - Microsoft Brasil

Uma das questões técnicas de maior popularidade desde o lançamento do .Net com certeza é:
- O que devo usar como middleware de comunicação entre minhas camadas de aplicação: WebService, Enterprise Services ou Remoting?

Esta questão, hoje em dia, é logo seguida de mais uma:
- E como será a portabilidade com a chegada do Indigo?

Estas, como muitas outras perguntas atuais no campo do software, estão carregadas de sentimentos fortes, trazendo à tona debates inflamados, que parecem ter a influência de experiências prévias com o COM+ e/ou o CORBA, da aposta com o futuro do Arquitetura Orientada a Serviços, ou da exigência de alta performance.

De fato, estes três tipos de mecanismos têm motivações distintas de arquitetura. Mesmo assim, todos os três mecanismos permitem extensões e/ou configurações que viabilizam seu uso em cenários diferentes do planejado inicialmente, o que reforça a confusão e dúvidas.

Para melhor entender estas diferentes motivações de cada middleware, utilizamos aqui 5 dimensões (ou aspectos) que parecem ser os mais relevantes na criação do espaço de soluções onde estas tecnologias podem ser usadas. São elas:
• Protocolo: protocolos suportados pelo middleware;
• Serialização/Deserialização: formato do dado transmitido entre cliente e servidor (usado no marshalling: processo formatação de envio de dados entre dois objetos/sistemas);
• Segurança: esquemas de proteção para criptografia, autenticação e autorização;
• Transacionalidade: capacidade de inserir uma tarefa dentro de um contexto transacional novo ou já iniciado;
• Modelo conversacional: paradigma usado na conversação entre cliente e servido. São eles: troca de mensagens entre cliente e serviço ou chamadas de métodos entre objetos remotos.

Observe que o desempenho não é considerado uma dimensão, mas sim uma resultante da configuração do middleware frente a estas dimensões. O mesmo se pode dizer da interoperabilidade.
Este artigo explicita para cada middleware (Remoting, WebServices ou EnterpriseServices) as forças que o motivam, os prós e contras de cada tecnologia, e o cenário ideal para seu uso.
O que este artigo não faz é explicar em profundidade estes middlewares, suas APIs e formas de programação. Outros textos discorrem com maiores detalhes sobre os aspectos mais técnicos do uso destas tecnologias.

Remoting
Este talvez seja o protocolo mais em moda na tecnologia .Net. Talvez por sua novidade, talvez pela resistência que se criou contra o COM+, este middleware é frequentemente citado e usado em condições para o qual não foi planejado idealmente.
O Remoting é um middleware criado para uma comunicação rápida, muito rápida. Para isto, ele conta com o protocolo tcp/ip e a serialização dos dados (marshalling) em formato binário. Nesta configuração, o Remoting é imbatível na sua performance.
Outras opções de protocolos oferecidas nativamente no .Net são os protocolos http e o https. Ambos os protocolos servem-se do tcp/ip para estabelecer, sobre este, protocolos de Pedido/Resposta (Request/Response) que abrem e fecham conexões tcp na porta 80 (http) ou 443 (https). O uso destes protocolos diminui o desempenho do Remoting, mas trazem a vantagem de passarem mensagens por firewalls e de poderem usar a infra-estrutura da Internet.

Outro fator que implica numa diminuição de performance é o marshalling no formato XML, em contraposição ao marshalling binário. O XML é famoso pela sua verborragia e tamanho, podendo comprometer boa parte do tempo de rede usado na comunicação entre as partes. Para contornar este problema você pode usar técnicas de compressão, mas nem sempre você terá isto de graça: seja por maior uso de CPU ou maior trabalho de programação.
Assim, podemos pensar que o Remoting oferece uma gama de opções que afetam o desempenho da conversação, tendo como opção mais rápida o tcp/ip com marshalling binário, e como a mais lenta o https com marshalling em XML.
Na dimensão segurança, o Remoting é falho, não oferecendo autorização e autenticação em sua forma nativa quando usado com o tcp/ip. Embora o Remoting não ofereça opção de criptografia dos dados sobre tcp/ip, o simples uso do protocolo ipsec, ao invés do ip simples, pode proporciona segurança adequada à maioria dos cenários - quando a infra-estrutura é homogênea e controlada. Por vezes você poderá encontrar máquinas clientes que não suportam o ipsec.
A autorização e a autenticação podem ser conseguidas de forma nativa via o uso do http/https.
Se você precisar, a arquitetura do Remoting permite a implementação de Channels que tratam da autorização e autenticação - isto é uma boa notícia. A ruim é que este é um trabalho difícil e deve ser feito por especialistas. Um erro e poderemos ter uma degradação substancial do desempenho ou um sério furo de segurança - daí frequentemente usarmos Remoting apenas dentro de DMZs ou aceitar o https como forma lenta para obter segurança no Remoting.
Uma quarta dimensão a ser considerada é a de transacionalidade. O Remoting não oferece contextos de transação, e se você precisar deles vai ter que implementar programação extra com o apoio do Banco de Dados, do DTC ou de outro coordenador de transações (como o do .Net Framework 2.0).
Por fim, o modelo de comunicação do Remoting ainda é o de um Object Request Broker. Isto é, temos dois objetos que se comunicam via proxy e stub. A idéia, como no COM+, é tornar invisível ao programador a questão da localidade dos objetos, deixando para a infra-estrutura o trabalho de ativar objetos e invocar métodos.
Neste ponto, o Remoting inova em relação ao COM+ na forma de liberar os objetos remotos. Enquanto no COM+ existe uma contagem de referência com uma coleção de lixo para os objetos com nenhuma referência, o Remoting funciona provendo um tempo de vida útil do objeto remoto - ao fim deste, o objeto é liberado da memória. Este mecanismo diminui a probabilidade de memory leak, que acontece com o COM+, mas obriga ao programador compreender bem o tempo de cada conversação entre objetos e programar o esquema de leasing que permite estender o seu tempo de vida de um objeto remoto.
Estas 5 dimensões (protocolo, serialização, segurança, transacionalidade e modelo de comunicação) tornam o Remoting ideal para a comunicação rápida (tcp/ip com serialização binária) dentro de uma DMZ (sem segurança), com comunicações statefull ou stateless segundo o modelo escolhido, com transação gerenciada unicamente pelo programador com ajuda do Banco de Dados ou outro monitor de transação.

WebServices
O WebServices é um middleware ainda em desenvolvimento mas que já pode contar com uma implementação padrão dada pelo Basic Profife do WS-I.

As grandes motivações do WebService são tanto a interoperabilidade, quanto o uso em cenários análogos às páginas Web (alta disponibilidade, grande número de acessos simultâneos, etc.). Imagine poder acessar o site da Amazon para procurar livris por ISBN - a sua aplicação pode fazer isto. A Amazon disponibiliza isto em WebServices pois é interoperável e seu protocolos possibilitam um grande número de usuários concorrentes devido ao uso de WebFarms.

Este cenário é a causa principal da adoção dos protocolos http/https, da serialização no formato XML e do uso de metadados como é o caso do WSDL. Hoje existem muitos sistemas, implementados em tecnologias diversas, que possuem mecanismos para operar sobre documentos XML (como XPath ou DOM) e enviar/receber mensagens via http/https. Isto torna o XML ideal para a interoperabilidade. Além disto, a infra-estrutura que temos para o http/https está comprovadamente habilitada para alta escalabilidade e disponibilidade.

De fato, o protocolo do WebServices como atualmente proposto pelo WS-I é mais rico do que isto, permitindo o uso de outros protocolos como meio de transporte das mensagens (como o simples tcp, o smtp ou outros) e está crescendo em número de mecanismos, como pode ser visto no www.ws-i.org (Federação, Workflow, etc). Conhecer todos os detalhes requer um estudo detalhado e está fora do objetivo deste artigo. Mas é interessante entender o seu destino final: que os sistemas futuros possam negociar protocolos, traduzir conteúdos de formatos diferentes, e permitir a comunicação entre sistemas independentes que expõe suas interfaces publicamente.

Um último ponto relevante refere-se ao modelo de comunicação. O WebService não implementa o paradigma de conversação entre objetos, como o Remoting e o Enterprise Services, mas sim o da troca de mensagens, sem que o cliente possa ter uma referência a um objeto remoto. Como conseqüência, se nós precisarmos manter uma conversação prolongada com o servidor, temos que criar mecanismos análogos ao de uma sessão na Web - uma complexidade extra que pode diminuir a produtividade.

A amplitude do cenário de serviços na Web e a fama do XML faz com que o WebService seja hoje um nome muito falado e, por vezes usado pela força do marketing, sem pesar muito as conseqüências do seu uso. Um exemplo, é o costume muito comum de implementar o WebServices como a camada de comunicação entre a camada Web e a camada de negócios. Será este o melhor protocolo para esta comunicação?

Da análise do Remoting feita acima já sabemos que o uso da serialização em XML é verborrágico (e oneroso para a rede) e que o uso de http/https é lento. Além disto, o WebServices não contempla no Basic Profile a questão da transacionalidade.

Entre as vantagens temos: ele facilita o uso de Firewalls entres as duas camadas e permite que aplicações distintas de sistemas distintos possam reutilizar uma mesma regra de negócios.

A verdade é que muitas vezes não podemos nos dar ao luxo de desprezar a performance em nome da interoperabilidade. Mais realista é implementar fachadas (façades) distintas para que as interfaces entre as camadas dos nossos produtos tenham alta performance e que fachadas baseada em WebServices sejam disponibilizados para a interoperabilidade com sistemas que desconhecemos.

EnterpriseServices
O Enterprise Services utiliza o COM+ como meio de comunicação entre objetos. O COM+ utiliza o protocolo RPC como meio de comunicação, que é um protocolo rápido. Ele também pode ser configurado para trabalhar usando SOAP, o que não é comum (embora ele possa ser configurado para usar o protocolo RPC na porta http via COM Internet Services, esta configuração também não é comum). Além disto, ele tem nativamente a autorização, autenticação e criptografia, e pode usar o DTC para garantir transacionalidade entre tarefas. O modelo utilizado é o de objetos - isto é, o cliente mantém referência para o objeto no servidor durante a conversação entre ambos, deixando ao programador a escolha entre seu uso stateless ou statefull.

Todos estes atributos fazem do Enterprise Service o candidato natural para o middleware de uma aplicação interna que não esteja sujeita à limitação devido à restrições de configuração do RPC (Firewall).

Mas sendo tão completo, por que tanta ânsia para abandoná-lo pelo Remoting ou WebService?

Frequentemente quando faço esta pergunta a algum desenvolvedor observo como resposta um olhar triste, com um algo de sofrimento devido a experiências passadas. E quais costumam ser as principais dores?

1. COM+ é complexo: com seus apartments e incompatibilidades entre eles, dois tipos distintos de interfaces com linguagens (o que restringe os tipos de parâmetros passados);

2. COM+ utiliza registry, o que pode tornar complexa a instalação e controle de versão;

3. COM+ pode causar memory leak, se não houver o cuidado de remover a referência ao objeto remoto (ou se deixarmos ciclos de referência entre objetos);

4. COM+ por vezes pode ser lento (veremos adiante que na maior parte das vezes isto decorre de um problema de design da aplicação que usa o COM+);

5. Utiliza muitas portas, complicando a configuração de Firewalls;


Entender o porquê destas más experiências é importante por dois motivos: primeiro, você pode também não estar livre deles no Remoting ou no WebServices, já que muitos problemas advém de mau projeto da aplicação ou de questões estruturais comuns; segundo por que com a evolução do COM+ 1.5 e com o uso das linguagens .Net muito destas limitações foram minimizadas. Vejamos ponto a ponto:

1. COM+ é complexo: por ter muitas opções o COM+ é complexo, mas seu uso pode ser bastante simplificado. Por exemplo, se seu sistema não é acessado por linguagens de scripts, você não tem a limitação de tipos. Outro exemplo: se você só utilizar componentes .Net, você pode optar pelo apartment Multithread (ou Both) para todos os objetos dentro do COM+, o que minimiza problemas de apartments e possibilita um grande aumento do desempenho;

2. COM+ utiliza registry:

• Isto traz a questão do controle de versões (que é também problemática para WebServices e Remoting). De fato, com o side-by-side e a possibilidade da convivência de objetos de versões diferentes dentro do COM+ 1.5, boa parte destes problemas se tornaram mais simples de administrar do que, por exemplo, no Remoting.;
• Muitos dos objetos colocados no COM+ não precisariam estar lá! Na minha experiência, é muito comum ver no COM+ um conjunto grande de componentes que não necessitam nem ser públicos nem estar em contexto transacional. Por que estão lá? Inércia e falta de planejamento: é mais simples colocar todos os objetos no COM+ do que classificá-lo de acordo com necessidade de transacionalidade ou de segurança no acesso. Este excesso de componentes torna o registro no COM+ mais penoso, o funcionamento da console administrativa mais lenta (MMC) e o desempenho do sistema como um todo pior, pois o gerenciamento do COM+ é obrigado a trabalhar excessivamente a cada conversação entre dois ou mais componentes em uma mesma tarefa. Ele estará garantindo segurança e coordenando transações quando não haveria necessidade.


3. COM+ pode causar memory leak: sim, isto é fato. O uso de mecanismos de linguagem que possibilitam a finalização automática de um objeto pode trazer mais conforto neste ponto;

4. COM+ pode ser lento: o COM+ é mais lento do que o Remoting! Mas se implementarmos segurança e transacionalidade no Remoting, muito provavelmente ele será mais rápido!! Porém, outros fatores genéricos podem influir na lentidão. Os mais comuns são:

• Excesso de comunicação entre camadas: Este é um problema corrente no design de sistemas distribuídos. Ele decorre de um design que utiliza muitas idas e vindas entre camadas de softwares distintas. Neste caso, o desempenho é pior quanto maior for o custo da comunicação. Por isto, se você teve más experiências com o COM+, tenha cuidado para não piorá-las com WebServices ou uso de http/https.
• Excesso de comunicação gerenciada pelo COM+: o COM+, como monitor transacional, precisa gerencia a intercomunicação entre dois objetos sob sua gerência. Com isto, ele garante, entre outros o contexto dos votos de cada objeto que participa de uma transação. Como já comentado anteriormente, esta comunicação pode ser diminuída com um bom projeto.
• Uso excessivo de comunicação entre processos (out-process): entender as fronteiras do seu sistema e o custo de comunicação entre elas é um passo importante para a boa performance. O COM+ permite o uso de Library Applications para facilitar o reuso de objetos na forma in-process que oferece um custo menor;
• Uso de comunicação statefull: qualquer que seja o protocolo usado, manter estados usualmente significa utilizar recursos e criar afinidade. Estes dois itens costumam ser mortais para o desempenho e escalabilidade de uma aplicação;
• Transações mal implementadas: muitos dos erros "DTC Time Out" ocorridos numa aplicação que usam o COM+ decorrem devido a problemas na lógica de acesso a banco de dados. Transações não otimizadas ou sujeitas a locks ou deadlocks são as causas mais comuns. Infelizmente, isto é algo que não vai mudar com a troca de middleware.


5. Utiliza muitas portas, complicando a configuração de Firewalls: Isto é fato. O uso do http/https pode ser uma solução, mas o impacto na performance é um grande limitante nesta escolha.

Escolhendo o middleware adequado
Se levarmos em conta as dimensões apresentadas, os cenários naturais para cada protocolo seriam:

• Remoting: Intercomunicação em ambientes protegidos que exigem alta velocidade e que utilizam a tecnologia .Net.
• Enterprise Services: Intercomunicação em ambientes de rede de velocidade média ou alta que exigem performance com segurança e/ou suporte transacional.
• WebServices: Intercomunicação que exigem alta interoperabilidade;

Como vimos, estender o uso destes protocolos em cenários diferentes dos apresentados acima é possível. O importante é saber o porquê, o que se está ganhando e o que se está perdendo.

O que está para chegar
O .Net Framework 2.0 chega em breve e oferecerá o recurso de lightweight transactions que implementa um coordenador de transações distribuídas que pode ser usado por aplicações que precisam do protocolo two-phase-commit, mas não estão sob o COM+ (e DTC) - ver http://msdn.microsoft.com/msdnmag/issues/05/02/DataPoints/. Com isto, será factível trabalhar com o remoting e realizar a lógica transacional no servidor com a participação de vários objetos e/ou processadores transacionais (Banco de Dados, Msmq, etc).

O próximo passo será o Indigo. Indigo é o nome da tecnologia e modelo de objetos que irá unificar as várias alternativas de middleware que a Microsoft tem hoje e irá implementar o WebServices no padrão WS-I mais atualizado. Com ele será possível utilizar atributos para especificar o protocolo e todo nível de serviços (segurança, transacionalidade, etc) que você precisar - o que simplifica em muito a programação de serviços. O Indigo trata a forma de comunicação como aspectos que podem ser incorporados à sua lógica de serviço, deixando o seu código mais simples e com custo menor de manutenção.

Portanto, o Indigo não acaba com a distinção entre WebServices, Remoting e EnterpriseServices - ele apenas torna mais simples programar para usá-los quando o objetivo for usar o WS-I como protocolo fim a fim .

É importante dizer também que no futuro, se você quiser migrar seu código atual para usar o Indigo, isto poderá ser feito com um pouco de trabalho. Na maior parte das vezes você estará removendo código extra para obter um novo mais simples, baseados nos atributos do Indigo. O pior caso que você pode ter é o caso em que o seu código atual implementa protocolos adicionais ao padrão (por exemplo, usar o mecanismo de Channels do Remoting para implementar segurança). Neste caso, seu código poderá ficar incompatível com a arquitetura do Indigo obrigando-o a mudanças mais radicais ou a não utilização desta nova tecnologia.

Uma Boa Prática para Hoje e Amanhã
Implementar um código de serviços remotos em duas partes - o Façade (ou Fachada) e o serviço propriamente dito - tem suas vantagens:

1. Você pode criar Façades para tecnologias diferentes e ofertá-las aos softwares clientes. Isto é, você pode criar uma camada de abstração que isola o serviço em si da sua conexão com o middleware que servirá para acesso.
2. Você está mais preparado para mecanismos futuros;

Você pode sempre pensar que o Façade é o nível onde ficam definidos:
• Formatos dos parâmetros
• Verificação sintática dos parâmetros
• Controle de Autorização e Autenticação
• Implementação do Contexto de transacionalidade
• Definição do tempo de vida do objeto que implementa o serviço
• Chamada ao código do serviço de negócio

Um exemplo do uso desta lógica é o EDRA (Enterprise Development Reference Architecture) que pode ser encontrado em http://go.microsoft.com/fwlink/?LinkId=31529.

Conclusão
A definição do middleware deve ser feita avaliando prós e contras de cada tecnologia. Isto implica não só conhecer virtudes e limites de cada tecnologia, mas também compreender o impacto do seu uso e do design mais condizente com a sua natureza.

Middlewares são ferramentas que têm usos diferentes para cenários - sua idade não é um bom argumento nem contra nem a favor. Como numa caixa de ferramentas, temos que escolher a correta para cada uso.

Como arquiteto, o importante é entender o cenário corrente e planejar os cenários futuros. Entender a estratégia de interoperabilidade que sua aplicação deve oferecer e aonde performance e/ou segurança pode ser mais relevante do que a interoperabilidade. Performance, Orientação a Serviços, Segurança, etc, são todos itens que devem ser pesados numa escolha que deve ser pautada por racionalidade - não pela emoção.

Agradecimentos: Obrigado ao Mauro Sant'Anna, Pedro Manfredi e Fernando Gebara pelos comentários e sugestões.

Artigos Relevantes sobre o tema

Remoting
.Net Remoting Overview:
Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Comm..:
.NET Remoting Authentication and Authorization Sample - Part I:
.NET Remoting Authentication and Authorization Sample - Part II:

Web Services
An Introduction to the Web Services Architecture and Its Specifications:

Comparando WebServices e Remoting
Performance Comparison: .NET Remoting vs. ASP.NET Web Services:

Enterprise Services
Understanding Enterprise Services (COM+) in .NET:
Windows Server 2003 and Enterprise Services:

Performance do Enterprise Services
.NET Enterprise Services Performance:

Boas Práticas para Middlewares
Chapter 13 - Code Review: .NET Application Performance:

Indigo
A Guide to Developing and Running Connected Systems with Indigo:

Comentários

Postagens mais visitadas deste blog

Redação Ti Nota 10 - Klauss

Prova Discursiva nota 10 - Banca Cespe

Portugues - Orações