Home    |    Login / Cadastro    |  Contato
 
Nossa Missão
 
 

SOA - Service Oriented Architecture

Arquitetura Orientada a Serviço

SOA se tornou um acrônimo bem conhecido e de certa forma questionável. Se uma pessoa pedir a duas outras que definam o que é SOA, provavelmente receberá duas respostas diferentes, possivelmente conflitantes. Alguns descrevem a SOA como uma infra-estrutura de TI para habilitação comercial; outros vêem a SOA como algo que aumenta a eficiência da TI. De muitas formas, a SOA é um pouco como o poema de John Godfrey sobre o homem cego e o elefante: cada homem descreve o elefante de uma forma um pouco diferente, pois cada um deles é influenciado por suas próprias experiências (por exemplo, o homem que toca a tromba acredita que se trata de uma cobra, ao passo que o que toca o marfim acredita que seja uma lança). O elefante do Sr. Saxe é muito mais fácil de descrever, pois ele existe como uma entidade física: a SOA, no entanto, é muito mais difícil de descrever, visto que as filosofias de design não estão disponíveis como manifestação física.

A SOA é uma abordagem de arquitetura para a criação de sistemas criados a partir de serviços autônomos. Com a SOA, a integração é uma previsão, e não algo em que não se pensa: a solução final provavelmente será composta de serviços desenvolvidos em diferentes linguagens de programação, hospedadas em plataformas diferentes, com uma variedade de modelos de segurança e de processos comerciais. Apesar de esse conceito parecer incrivelmente complexo, ele não é novo: alguns podem argumentar que a SOA evoluiu das experiências associadas ao projeto e ao desenvolvimento de sistemas distribuídos com base em tecnologias disponíveis anteriormente. Muitos dos conceitos associados à SOA, como serviços, descoberta e ligação tardia, foram associados ao CORBA e ao DCOM. Da mesma forma, muitos princípios de design de serviço têm muito em comum com técnicas OOA/PPD anteriores, baseadas em encapsulamento, abstração e interfaces claramente definidas.

O acrônimo SOA levanta uma questão óbvia: o que exatamente é um serviço? Simplesmente, serviço é um programa com que se pode interagir por meio de trocas de mensagens bem-definidas. Os serviços devem ser projetados para disponibilidade e estabilidade. Os serviços são criados para durar, enquanto as configurações e agregações de serviço são criadas para mudar. A agilidade muitas vezes é promovida como uma das maiores vantagens da SOA: uma organização com processos comerciais implementados em uma infra-estrutura menos rígida é muito mais aberta a mudanças que uma organização limitada por aplicativos monolíticos subjacentes que levam semanas para implementar uma pequena alteração. Os sistemas menos rígidos resultam em processos comerciais menos rígidos, visto que os processos comerciais não são mais restringidos por limitações da infra-estrutura subjacente. Os serviços e suas interfaces associadas devem permanecer estáveis, permitindo que sejam reconfigurados ou reagregados para atender às sempre novas necessidades das empresas. Os serviços permanecem estáveis, contando com interfaces baseadas em padrões e em mensagens bem-definidas: em outras palavras, esquemas SOAP e XML para definição de mensagens. Os serviços projetados para a execução de funções granulares simples com conhecimento limitado de como as mensagens são passadas a eles ou deles recuperadas provavelmente serão muito mais reutilizados dentro de uma infra-estrutura maior de SOA. Como já afirmado, relembramos que os princípios básicos de design OO relacionados ao encapsulamento e ao design da interface nos atenderão também quando projetarmos e criarmos Serviços da Web reutilizáveis. Podemos estender esses princípios OO ao mundo de serviços da Web, entendendo melhor as "quatro filosofias" da Orientação de serviço citadas com freqüência:

Filosofia 1: os limites são explícitos

Os serviços interagem por intermédio de passagem explícita de mensagens por limites bem-definidos. Cruzar limites de serviços pode ser caro, dependendo de fatores geográficos, de confiança ou de execução. Um limite representa a fronteira entre a interface pública de um serviço e sua implementação interna, privada. O limite de um serviço é publicado por meio do WSDL e pode incluir declarações que ditam as expectativas de determinado serviço. O cruzamento de limites é considerado uma tarefa cara por diversos motivos, entre os quais:

O local físico do serviço almejado pode ser um fator desconhecido.

Os modelos de segurança e de confiança provavelmente mudarão a cada cruzamento de limites.

O empacotamento e a conversão de dados entre as representações pública e privada de um serviço podem exigir recursos adicionais; alguns deles podem ser externos ao próprio serviço.

Ainda que os serviços sejam criados para durar, as configurações de serviço são criadas para mudar. Esse fato implica que um serviço confiável possa sofrer repentinas quedas de desempenho em função de reconfigurações de rede ou de migração para outro local físico.

Os consumidores de serviço geralmente não sabem como os processos internos privados foram implementados. O consumidor de determinado serviço tem controle limitado sobre o desempenho do serviço que está sendo utilizado.

O padrão Integração orientada a serviços nos diz que "invocações de serviço estão sujeitas à latência da rede, à falha da rede e a falhas do sistema distribuído, mas uma implementação local não. Uma quantidade significativa de detecção de erros e lógica de correção pode ser escrita para antecipar os impactos do uso de interfaces de objetos remotos". Apesar de devermos considerar que cruzar limites seja um processo caro, também devemos ter cuidado ao implantar métodos locais projetados para minimizar esses cruzamentos de limites. Um sistema que implementa métodos e objetos locais monolíticos pode ganhar desempenho, mas duplicar a funcionalidade de um serviço previamente definido (essa técnica foi chamada de "recorte e colagem" em OOP e compartilha os mesmos riscos em relação à versão do serviço).

Há vários princípios a serem lembrados em relação à primeira Filosofia da SO:

Conheça seus limites. Os serviços oferecem um contrato para definir as interfaces públicas que eles apresentam. Toda a interação com o serviço ocorre por meio da interface pública. A interface consiste em processos públicos e em representações de dados públicas. O processo público é o ponto de entrada para o serviço, ao passo que a representação de dados pública simboliza as mensagens usadas pelo processo. Se usamos o WSDL para representar um contrato simples, <message> representa os dados públicos e <portType> representa os processos públicos

Os serviços devem ser fáceis de usar. Ao projetar um serviço, os desenvolvedores devem facilitar para outros desenvolvedores o seu uso. A interface (contrato) do serviço também deve ser projetada para permitir a evolução do serviço sem romper contratos com antigos consumidores. (Esse tópico será analisado mais detalhadamente em futuros artigos desta série.)

Evite interfaces RPC. A passagem explícita de mensagens deve ser favorecida em relação a um modelo como o RPC. Essa abordagem separa o consumidor da parte interna da implementação do serviço, permitindo que os desenvolvedores de serviço evoluam seus serviços ao mesmo tempo que minimizam o impacto sobre consumidores do serviço (encapsulamento pelo uso de mensagens públicas em vez de métodos disponíveis publicamente).

Mantenha reduzida a área da superfície de serviço. Quanto mais interfaces públicas um serviço expõe, mais difícil utilizá-lo e fazer sua manutenção. Forneça algumas interfaces públicas bem-definidas para o seu serviço. Essas interfaces devem ser relativamente simples, projetadas para aceitar uma mensagem de entrada bem-definida e para responder com uma mensagem de saída igualmente bem-definida. Depois que essas interfaces são projetadas, elas devem permanecer estáticas. Essas interfaces cumprem o "constante" requisito de design a que os serviços devem oferecer suporte, servindo de face pública para a implementação interna, privada, do serviço.

Os detalhes da implementação interna (privada) não devem ultrapassar o limite de um serviço. Se os detalhes da implementação ultrapassarem o limite do serviço, provavelmente ocorrerá uma maior união entre o serviço e os consumidores desse serviço. Os consumidores do serviço não devem ser informados da parte interna da implementação de um serviço, pois isso restringe as opções de versão e atualização do serviço. A seção Antipadrões deste artigo fornece um exemplo detalhado dessa questão.

Filosofia 2: os serviços são autônomos

Os serviços são entidades implantadas independentemente, com versões e gerenciadas. Os desenvolvedores devem evitar fazer suposições em relação ao espaço entre os limites de serviço, visto que esse espaço tem muito mais probabilidade de mudar do que os limites propriamente ditos. Por exemplo, os limites do serviço devem ser estáticos para minimizar o impacto da versão para o consumidor. Ainda que os limites de um serviço sejam bem estáveis, as opções de implantação desse serviço em relação à diretiva, ao local físico ou à topologia da rede provavelmente mudarão.

Os serviços são tratados dinamicamente por meio de URIs, permitindo que seus locais subjacentes e topologias de implantação mudem ou evoluam com o tempo, com pouco impacto em relação ao próprio serviço (isso também é válido em relação aos canais de comunicação de um serviço). Ainda que essas alterações possam ter pouco impacto sobre o serviço, elas podem ter um impacto devastador sobre aplicativos que o utilizem. E se um serviço que você estava usando hoje passar para uma rede na Nova Zelândia amanhã? A alteração no tempo de resposta pode ter impactos esperados ou inesperados sobre os consumidores do serviço. Os designers de serviço devem adotar uma visão pessimista sobre o uso de seus serviços: os serviços falharão e seus comportamentos associados (níveis de serviço) estarão sujeitos a mudança. Níveis apropriados de tratamento de exceções e de lógica de compensação deverão ser associados a qualquer invocação de serviço. Além disso, consumidores de serviço podem precisar modificar suas diretrizes para declarar tempos de resposta mínimos de serviços a serem utilizados. Por exemplo, os consumidores de um serviço podem exigir níveis variados de serviço em relação à segurança, ao desempenho, às transações e a muitos outros fatores. Uma diretriz configurável permite que um único serviço ofereça suporte a vários SLAs em relação à invocação de serviço (diretrizes adicionais podem se concentrar em versão, localização e outras questões). A comunicação das expectativas de desempenho no nível de serviço preserva a autonomia, visto que os serviços não precisam estar familiarizados com as implementações internas um do outro.

Os consumidores de serviço não são os únicos que devem adotar visões pessimistas do desempenho: os provedores de serviço devem ser da mesma forma pessimistas ao antecipar como seus serviços serão utilizados. Deve-se esperar que os consumidores de serviço falhem, algumas vezes sem notificar o próprio serviço. Os provedores de serviço também não podem confiar que os consumidores "farão a coisa certa". Por exemplo, os consumidores podem tentar se comunicar usando mensagens mal-elaboradas/mal-intencionadas ou tentar violar outras diretrizes necessárias para uma interação de serviço bem-sucedida. Os funcionários internos do serviço devem tentar compensar esse uso inapropriado, independentemente da intenção do usuário.

Apesar de os serviços serem projetados para serem autônomos, nenhum serviço é uma ilha. Uma solução baseada na SOA é fractal, consistindo em vários serviços configurados para uma solução específica. Pensando de forma autônoma, logo se percebe que não há autoridade dirigindo em um ambiente orientado a serviços: o conceito de "condutor" de orquestra é falho (implicando mais ainda que o conceito de "reduções de preços" nos serviços é falha, mas esse tópico será tratado em outro artigo). As chaves para executar serviços autônomos são isolamento e separação. Os serviços são projetados e implantados independentemente um do outro e só podem se comunicar usando mensagens e diretrizes controladas por contrato.

Como ocorre com outros princípios de design de serviço, podemos aprender com nossas experiências passadas com o design OO. O trabalho de Peter Herzum e de Oliver Sims sobre fábricas de componentes comerciais apresenta idéias interessantes sobre a natureza dos componentes autônomos. Apesar de grande parte de seu trabalho ser mais apropriada a soluções baseadas em componentes menos detalhados, os princípios básicos de design ainda se aplicam ao design de serviço.

Feitas essas considerações, veja aqui alguns princípios de design simples que o ajudarão a garantir a compatibilidade com o segundo princípio da SO:

Os serviços devem ser implantados e ter a versão atualizada, independentemente do sistema em que sejam implantados e utilizados.

Os contratos devem ser projetados pressupondo-se que, uma vez publicados, não possam ser modificados. Essa abordagem força os desenvolvedores a criarem flexibilidade em seus designs de esquema.

Proteja os serviços contra falhas, adotando uma visão pessimista. Da perspectiva do consumidor, planeje níveis pouco confiáveis de disponibilidade e de desempenho do serviço. Da perspectiva do fornecedor, espere que seu serviço seja usado de forma errada (deliberadamente ou não) e espere que os consumidores do serviço falhem, talvez sem notificar o serviço.

Filosofia 3: os serviços compartilham esquema e contrato, não a classe

Como já afirmado, a interação com o serviço deve se basear somente nas diretrizes, no esquema e nos comportamentos baseados no contrato de um serviço. O contrato de um serviço geralmente é definido usando-se o WSDL, e contratos para agregações de serviços podem ser definidos usando-se o BPEL (que, por sua vez, usa o WSDL para cada serviço agregado).

A maioria dos desenvolvedores define classes para representar as várias entidades dentro de determinado espaço problemático (por exemplo, Cliente, Pedido e Produto). As classes combinam comportamento e dados (mensagens) em uma única linguagem de programação ou construção específica à plataforma. Os serviços dividem esse modelo para maximizar a flexibilidade e a interoperabilidade. Os serviços que se comunicam usando mensagens baseadas no esquema XML não reconhecem as linguagens e as plataformas de programação, garantindo níveis mais amplos de interoperabilidade. O esquema define a estrutura e o conteúdo das mensagens, ao passo que o contrato de serviço define o comportamento do próprio serviço.

Resumindo, o contrato de um serviço consiste nos seguintes elementos:

Formatos de troca de mensagens definidos com o Esquema XML.

Padrões de troca de mensagens (MEPs) definidos com o WSDL.

Recursos e requisitos definidos com a especificação WS-Policy.

O BPEL pode ser usado como contrato no nível de processo comercial para agregar vários serviços.

Os consumidores de serviço contarão com um contrato de serviço para invocar um serviço e interagir com ele. Havendo essa confiança, o contrato de um serviço deve permanecer estável com o passar do tempo. Os contratos devem ser projetados da forma mais explícita possível, ao mesmo tempo tirando proveito da natureza extensível do esquema XML (xsd:any) e do modelo de processamento SOAP (cabeçalhos opcionais).

O maior desafio da Terceira filosofia é sua permanência. Depois que um contrato de serviço é publicado, é extremamente difícil modificá-lo e ao mesmo tempo minimizar o impacto sobre antigos consumidores do serviço. A linha entre as representações de dados interna e externa é fundamental para a implantação e a reutilização bem-sucedida de determinado serviço. Os dados públicos (dados passados entre serviços) devem se basear em padrões organizacionais ou verticais, garantindo ampla aceitação entre diferentes serviços. Os dados privados (dados dentro de um serviço) são encapsulados em um serviço. De alguma maneira, os serviços são como representações menores de uma organização que conduz transações de e-business. Assim como uma organização deve mapear uma Ordem de compra externo em seu formato interno de OC, um serviço também deve mapear uma representação de dados sob contrato em seu formato interno. Mais uma vez, nossas experiências com encapsulamento de dados OO podem ser reutilizadas para ilustrar um conceito semelhante: a representação interna dos dados de um serviço só pode ser manipulada por meio do contrato do serviço.

Feitas essas considerações, veja aqui alguns princípios de design simples que o ajudarão a garantir a compatibilidade com o terceiro princípio da SO:

Garanta que o contrato de um serviço permaneça estável para minimizar o impacto sobre os consumidores do serviço. O contrato nesse sentido se refere à representação de dados pública (dados), ao padrão de troca de mensagens (WSDL) e a recursos e níveis de serviço configuráveis (diretriz).

Os contratos devem ser o mais explícitos possível para minimizar a má interpretação. Além disso, os contratos devem acomodar a futura versão do serviço por meio da extensibilidade da sintaxe XML e do modelo de processamento SOAP.

Evite manchar a linha entre as representações de dados pública e privada. O formato interno dos dados de um serviço deve ficar oculto para os consumidores e o esquema de dados público deve ser imutável (preferencialmente com base em um padrão organizacional, de facto ou de indústria).

Serviços de versão quando há alterações no contrato de serviço são inevitáveis. Essa abordagem minimiza a ruptura de implementações do antigo consumidor.

Filosofia 4: a compatibilidade com o serviço se baseia na diretriz

Ainda que seja muitas vezes considerada a filosofia de design menos compreendida, talvez seja uma das mais eficazes em termos de implementação de serviços da Web flexíveis. Não é possível comunicar alguns requisitos para interação de serviço somente no WSDL. As expressões de diretriz podem ser usadas para separar a compatibilidade estrutural (o que é comunicado) da compatibilidade semântica (como ou para quem uma mensagem é comunicada).

Os requisitos operacionais para provedores de serviço podem ser manifestados na forma de expressões de diretriz legíveis em máquina. As expressões de diretriz oferecem um conjunto configurável de semânticas interoperáveis que regem o comportamento e as expectativas de determinado serviço. A especificação WS-Policy define uma estrutura de diretriz legível em máquina capaz de expressar diretrizes no nível de serviço, permitindo que elas sejam descobertas ou impostas em tempo de execução. Por exemplo, um serviço de segurança do governo pode exigir uma diretriz que imponha determinado nível de serviço (fotos de passaporte que satisfaçam critérios estabelecidos devem ser consultadas em um sistema de identificação de terroristas, por exemplo). As informações de diretriz associadas a esse serviço podem ser usadas com vários outros cenários ou serviços relacionados à condução de uma verificação de antecedentes. A especificação WS-Policy pode ser usada para impor esses requisitos sem exigir uma única linha de código adicional. Esse cenário ilustra como uma estrutura de diretriz fornece informações adicionais sobre os requisitos de um serviço ao mesmo tempo fornecendo um modelo de programação declarativa para definição e execução do serviço.

Uma declaração de diretriz identifica um comportamento que é requisito (ou capacidade) de um assunto da diretriz. (No cenário anterior, a declaração é a verificação de antecedentes no sistema de identificação de terroristas.) As declarações possuem semântica específica ao domínio e serão posteriormente definidas em especificações separadas, do próprio domínio, em várias indústrias verticais (estabelecendo o conceito de "estrutura" da WS-Policy).

Apesar de os serviços controlados por diretriz continuarem evoluindo, os desenvolvedores devem assegurar que suas declarações de diretriz sejam o mais explícitas possível em relação às expectativas do serviço e às compatibilidades semânticas do serviço.

Padrões e antipadrões da SOA

Agora que você já tem conhecimento dos conceitos da SOA (incluindo as filosofias de design da SO), chegou a hora de aplicar o que aprendeu. O restante deste artigo apresenta dois antipadrões e três padrões. Esses antipadrões e padrões foram projetados de acordo com os conceitos analisados anteriormente.

Por que padrões e antipadrões?

As pessoas tendem a pensar e se comunicar em padrões. Christopher Alexander, autor de vários livros sobre linguagens de padrões, definiu padrões como "uma abstração de uma forma concreta que continua se repetindo em contextos específicos, não-arbitrários". Os padrões e as linguagens de padrões são meios de descrever melhores práticas, designs testados e capturar experiências passadas de forma que os outros aprendam com essas experiências. Os padrões são uma abordagem testada para entender rapidamente as diretrizes de design e os vários contextos em que devem ser aplicadas. Os antipadrões são, como se pode esperar, o oposto dos padrões. Enquanto os padrões oferecem orientação testada e melhores práticas, os antipadrões ilustram falhas comuns de design e servem como método de aprendizado com os erros dos outros. O restante deste artigo contém uma revisão informal de dois antipadrões e de três padrões, todos projetados para servir como guia para o desenvolvimento de serviços da Web mais eficazes.

Os antipadrões e padrões deste artigo seguem o formato listado a seguir.

Contexto: uma breve explicação introdutória do padrão ou do antipadrão. O contexto é fornecido de modo que os leitores possam reconhecer possíveis oportunidades para aplicar um modelo ou reconhecer as características de um antipadrão antes que ele seja totalmente instanciado.

Problema: uma declaração simples, projetada para estruturar os objetivos associados ao padrão ou antipadrão.

Forças: considerações adicionais que devem ser levadas em conta na aplicação de determinado padrão ou no reconhecimento de um antipadrão.

Solução: uma descrição da resolução de determinado antipadrão ou as etapas necessárias à aplicação do padrão associado.

Sintomas e conseqüências: no caso dos antipadrões, os fatores que fazem um antipadrão existir. No caso dos padrões, os sintomas e as conseqüências podem voltar-se para outros fatores ou questões a serem consideradas antes da aplicação do padrão associado.

Os antipadrões incluem uma recomendação adicional sobre como suas falhas de design associadas podem ser aprimoradas.

Fonte:http://www.microsoft.com/brasil/msdn/Tecnologias/arquitetura/SOADesign_US.mspx

Tópicos Relacionados: