BALANCEAMENTO DE CARGA EM WEB SERVICES Sabrina …F... · para o uso de e-mail e sites...

115
UNIVERSIDADE FEDERAL DE SANTA CATARINA DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA CURSO DE BACHARELADO EM SISTEMAS DE INFORMAÇÃO BALANCEAMENTO DE CARGA EM WEB SERVICES Sabrina da Silva Leandro Trabalho de conclusão de curso submetido à Universidade Federal de Santa Catarina como parte dos requisitos para obtenção do grau de Bacharel em Sistemas de Informação. Florianópolis - SC 2005/1

Transcript of BALANCEAMENTO DE CARGA EM WEB SERVICES Sabrina …F... · para o uso de e-mail e sites...

UNIVERSIDADE FEDERAL DE SANTA CATARINA

DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA

CURSO DE BACHARELADO EM SISTEMAS DE INFORMAÇÃO

BALANCEAMENTO DE CARGA EM WEB SERVICES

Sabrina da Silva Leandro

Trabalho de conclusão de curso submetido à Universidade Federal de Santa Catarina como parte dos requisitos para obtenção do grau de Bacharel em Sistemas de Informação.

Florianópolis - SC

2005/1

2

Sabrina da Silva Leandro

BALANCEAMENTO DE CARGA EM WEB SERVICES

Trabalho de conclusão de curso submetido à Universidade Federal de Santa Catarina como parte dos requisitos para obtenção do grau de Bacharel em Sistemas de Informação.

Orientador: Prof. Frank Augusto Siqueira, Dr. Universidade Federal de Santa Catarina

[email protected]

Banca examinadora

___________________________________

Prof. João Bosco Mangueira Sobral, Dr. Universidade Federal de Santa Catarina

[email protected]

___________________________________

Prof. Mario Dantas, Dr. Universidade Federal de Santa Catarina

[email protected]

3

AGRADECIMENTOS

Gostaria de agradecer a todos que me auxiliaram, direta ou indiretamente, na

conclusão deste trabalho.

Agradeço aos meus pais pelo apoio e principalmente pelo exemplo, pois além de

excelentes profissionais, que me ajudaram com minhas dúvidas de trabalhos acadêmicos,

são pessoas maravilhosas das quais me orgulho muito.

Agradeço também a força e o ombro do meu amor e melhor amigo João, que me

tranqüilizou e acalmou meus anseios.

Obrigada ao meu orientador, pela ótima idéia oferecida a mim, que me propiciou

muitos aprendizados e novos conhecimentos. Obrigada também por ser meu guia neste

trabalho final.

Finalmente, não poderia deixar de agradecer aos meus colegas da faculdade e do

trabalho. Em especial, Marcus Grando, Gian Carlo Salva ti e Fernando Barreto, pela luz

que me deram quando me vi perdida em uma área na qual não tinha muita experiência.

A todos, um sincero obrigada!

4

RESUMO

LEANDRO, Sabrina da Silva. Balanceamento de Carga em Web Services. 2005. Trabalho de Conclusão de Curso (Bacharelado em Sistemas de Informação). Curso de Sistemas de Informação, Universidade Federal de Santa Catarina, Florianópolis. Empresas e instituições sentem cada vez mais a necessidade de interligar processos de negócio e trocar informações com fornecedores, clientes e parceiros. A arquitetura Web Services surge para facilitar a interligação entre as aplicações que implementam esses processos de negócio. Ela permite a conexão de sistemas heterogêneos, pois apresenta características como fraco acoplamento, independência de plataforma e uso de padrões abertos. Entretanto, essa arquitetura ainda possui padronizações a serem definidas, especialmente em questões como disponibilidade, desempenho e qualidade de serviço. Por possuir problemas de desempenho comprovados, é essencial que estas questões sejam tratadas. Este trabalho tem como objetivo propor um mecanismo para balanceamento de carga entre diferentes servidores que disponibilizam um mesmo serviço Web, visando a melhoraria do seu desempenho. O mecanismo proposto usa uma abordagem de balanceamento de carga baseada em despachante. Esse despachante encaminha as mensagens a uma das réplicas de um serviço, usando um protocolo de endereçamento para serviços Web. O mecanismo proposto foi implementado, assim como três algoritmos de balanceamento de carga (Randômico, Round-robin e Menor Carga), que podem ser usados de acordo com as características do serviço e dos servidores que o implementam. Palavras-chave: serviços Web, balanceamento de carga, desempenho.

5

ABSTRACT

LEANDRO, Sabrina da Silva. Web Services Load Balancing. 2005. Final Dissertation. Information Systems Graduation Course, Universidade Federal de Santa Catarina, Florianópolis. Companies and institutions feel the need to interconnect business processes, in order to exchange information with suppliers, clients and partners. The Web Services Architecture is a way to facilitate the interconnection between the applications that implement these business processes. It enables the communication between heterogeneous systems because it provides loose coupling, platform independence and the use of open standards. However, this architecture still has standards to be defined, specially concerning availability, performance and quality of service. Since it possesses proven performance problems, it is essential to address these issues. In this dissertation, a mechanism to balance load between different servers that provide the same Web service is proposed, so that the performance of the Web service is improved. The proposed mechanism uses a dispatcher as the load balancing entity. This dispatcher forwards messages to the selected replica of a service using a Web services addressing protocol. The proposed mechanism was implemented as well as three load balancing algorithms (Random, Round-robin, Least Load), that can be chosen based on the characteristics of the service and the servers in which it is deployed. Keywords: Web services, load balancing, performance.

6

SUMÁRIO

Lista de Figuras __________________________________________________________8

Lista de Abreviaturas e Siglas _______________________________________________9

1 Introdução____________________________________________________________11

1.1 Descrição do Problema________________________________________________ 12

1.2 Objetivos___________________________________________________________ 12 1.3 Justificativa ________________________________________________________ 13

1.4 Organização do Texto_________________________________________________ 14

2 Revisão Bibliográfica ___________________________________________________16

2.1 Sistemas Distribuídos _________________________________________________ 16 2.1.1 Sistemas de Clusters de Servidores Web__________________________________________ 17

2.2 Balanceamento de Carga ______________________________________________ 19 2.2.1 Abordagem baseada no cliente _________________________________________________ 20 2.2.2 Abordagem baseada no servidor DNS ____________________________________________ 21 2.2.3 Abordagem baseada em despachante_____________________________________________ 23 2.2.4 Abordagem baseada no servidor ________________________________________________ 26

2.3 Web Services________________________________________________________ 27 2.3.1 Arquitetura Orientada a Serviços – SOA __________________________________________ 30 2.3.2 Histórico__________________________________________________________________ 32 2.3.3 Arquitetura Web Services _____________________________________________________ 34 2.3.4 SOAP ____________________________________________________________________ 35 2.3.5 WSDL ___________________________________________________________________ 40 2.3.6 UDDI ____________________________________________________________________ 43

2.4 Web Services Addressing ______________________________________________ 45 2.4.1 Histórico__________________________________________________________________ 48 2.4.2 Detalhes da Especificação_____________________________________________________ 49 2.4.3 WS-Addressing e SOAP ______________________________________________________ 53 2.4.4 WS-Addressing e WSDL _____________________________________________________ 55

2.5 Plataformas de Desenvolvimento para Web Services _________________________ 56

2.6 Desempenho de Web Services___________________________________________ 57

2.7 Considerações Finais__________________________________________________ 61

3 Balanceamento de Carga em Web Services__________________________________62

3.1 Algoritmos de Balanceamento de Carga___________________________________ 66

4 Implementação ________________________________________________________69

4.1 Cliente ____________________________________________________________ 70

4.2 Despachante WS-LoadBalancer_________________________________________ 70

4.3 Servidor ___________________________________________________________ 75

5 Testes e Resultados _____________________________________________________77

5.1 Ambiente de Testes___________________________________________________ 77

5.2 Testes _____________________________________________________________ 77

5.3 Resultados _________________________________________________________ 78

7

6 Conclusões e Trabalhos Futuros __________________________________________80

6.1 Conclusões _________________________________________________________ 80

6.2 Trabalhos Futuros ___________________________________________________ 80

Referências Bibliográficas ________________________________________________82

Apêndices ______________________________________________________________86

Apêndice A – Código Fonte _______________________________________________ 86

Apêndice B – Artigo____________________________________________________ 102

8

LISTA DE FIGURAS

Figura 1 – Arquitetura SOA e protocolos Web Services............................................................................................35 Figura 2 – Exemplo de mensagem SOAP enviada por HTTP...................................................................................40 Figura 3 – Exemplo de arquivo WSDL, a interface abstrata e os detalhes de protocolo....................................42 Figura 4 – Exemplo de estrutura UDDI simplificada................................................................................................45 Figura 5 – Exemplo de endpoint reference com um parâmetro de referência.......................................................53 Figura 6 – Exemplo de endpoint reference em uma mensagem SOAP. ..................................................................54 Figura 7 – Mensagem SOAP utilizando WS-Addressing...........................................................................................55 Figura 8 – Atributo WS-Addressing em um documento WSDL. ...............................................................................56 Figura 9 – Três clientes acessando um serviço implementado em duas réplicas, usando WS-LoadBalancer.69 Figura 10 – Diagrama de classes do despachante WS-LoadBalancer. ..................................................................73 Figura 11 – Exemplo de arquivo de configuração do despachante WS-LoadBalancer.......................................73 Figura 12 – Diagrama de Seqüência de chamada de serviço através do despachante WS-LoadBalancer......75 Figura 13 – Gráfico tempo de resposta médio dos algoritmos de balanceamento de carga no WS-LoadBalancer. ...................................................................................................................................................................79

9

LISTA DE ABREVIATURAS E SIGLAS

§ API – Application Program Interface: conjunto de rotinas, protocolos e ferramentas para construção de aplicações.

§ COM – Component Object Model: arquitetura de software desenvolvida pela Microsoft para criação de aplicações baseada em componentes.

§ CORBA – Common Object Request Broker Architecture: arquitetura do Object Management Group que permite a comunicação entre objetos em diferentes plataformas.

§ DCE – Distributed Computing Environment: ambiente desenvolvido pelo The Open Group para criação de aplicações distribuídas que rodam em diferentes plataformas.

§ DCOM – Distributed Component Object Model: protocolo de objetos remotos, da Microsoft.

§ EPR – Endpoint Reference: referência dinâmica a um ponto de acesso de um serviço que pode receber mensagens SOAP.

§ HTML – HyperText Markup Language: linguagem usada para criar documentos na Web.

§ HTTP – HyperText Transfer Protocol: protocolo que define como mensagens são formatadas e transmitidas e qua is ações servidores Web e navegadores devem tomar em resposta a vários comandos.

§ IP – Internet Protocol: protocolo Internet para troca de pacotes.

§ Java RMI – Java Remote Method Invocation: conjunto de protocolos desenvolvidos pela Sun que permitem a comunicação remota entre objetos Java.

§ JSP – Java Server Pages: extensão da tecnologia servlets da Sun.

§ MEP – Message Exchange Pattern: Padrão de Troca de Mensagens.

§ RPC – Remote Procedure Call: Chamada Remota de Procedimento.

§ SMTP – Simple Mail Transfer Protocol: protocolo para envio de e-mails entre servidores.

§ SNMP – Simple Network Management Protocol: conjunto de protocolos para gerência de redes.

§ SOA – Service-oriented Architecture: Arquitetura Orientada a Serviços.

§ SOAP: protocolo de transporte de mensagens entre serviços Web.

§ TCP – Transmission Control Protocol: protocolo que faz conexão entre hosts para que estes troquem dados.

§ UDDI – Universal Description, Discovery and Integration: Integração, Descobrimento e Descrição Universal. Especificação de descobrimento para serviços Web.

§ URI – Uniform Resource Identifier: Identificador Uniforme de Recursos, termo genérico para todos os tipos de nomes e endereços que se referem a objetos na Web.

10

§ URL – Uniform Resource Locator: Localizador Uniforme de Recursos, endereço global de documentos e outros recursos na Web.

§ W3C – World Wide Web Consortium: organização internacional cujo objetivo é desenvolver padrões abertos para a Web.

§ WS – Web Services: Serviços Web.

§ WS-Addressing – Web Services Addressing: Endereçamento de Serviços Web.

§ WSDL – Web Services Description Language: Linguagem de Descrição de Serviços Web.

§ XML – Extensible Markup Language: linguagem de tags de marcação baseada em texto.

§ XML Infoset : conjunto de dados definidos pelo W3C para uso nas suas especificações.

§ XML Schema – Esquema XML: modelo para descrever a estrutura dos dados XML.

11

1 INTRODUÇÃO

A Internet surge nos EUA, na década de setenta, inicialmente com objetivo de

conectar governos, acadêmicos e pesquisadores [1]. Com o passar do tempo, ela evoluiu

para o uso de e-mail e sites institucionais, que serviam somente como uma forma de

marketing. Atualmente, além da consolidação do comércio eletrônico, está acontecendo

uma nova revolução do uso da Internet, que resolve um dos grandes problemas enfrentados

pelos desenvolvedores: a integração de sistemas heterogêneos. Ou seja, o uso da Internet

está minimizando a complexidade, e conseqüentemente os custos, de se integrar sistemas

diferentes.

As empresas sentem cada vez mais a necessidade de interligar seus processos de

negócio, bem como trocar informações com fornecedores, clientes e parceiros através de

processos de negócio externos. Essa cooperação necessita que a conexão entre sistemas de

diferentes fabricantes, que implementam esses processos, seja fácil, para que as empresas

possam responder de forma rápida e eficiente às exigências de clientes, mudanças de

mercados ou ameaças da concorrência.

A arquitetura Web Services está possibilitando essa conexão entre sistemas

heterogêneos. Por dois motivos, em primeiro lugar porque ela oferece interoperabilidade e

fraco acoplamento, por ser independente de plataformas ou sistemas operaciona is. Em

segundo lugar, essa arquitetura é baseada em padrões abertos e, por isso, todos os

envolvidos projetam seus sistemas utilizando os mesmos padrões. Essas duas

características possibilitam a fácil integração de sistemas. Mas para que o uso comercial

dessa tecnologia se torne corrente, é importante que se tenha uma infra-estrutura confiável

para seu desenvolvimento e implantação.

Nos últimos anos, um grande número de especificações foi criado por empresas e

organizações, mas sem a preocupação de determinar como seria o relacionamento entre

essas especificações, e de como elas, juntas, formariam a Arquitetura Web Services [2].

Por ser uma tecnologia nova, questões de desempenho e disponibilidade ainda não foram

solucionadas de forma satisfatória, de maneira que permita que esta arquitetura seja usada

em todo seu potencial.

Este trabalho tem como objetivo propor um mecanismo para balanceamento de

carga entre réplicas de serviços Web. A distribuição das requisições baseada em algoritmos

12

de balanceamento de carga permite melhorar o desempenho, aumentar a disponibilidade,

diminuir o tempo de resposta e possibilita prover tolerância a faltas. Entende-se que a

melhoria dessas características, trazida pela solução proposta, deverá permitir que esta

nova e interessante arquitetura possa ser mais amplamente difundida e que cada vez mais

novos serviços Web sejam implantados.

1.1 DESCRIÇÃO DO PROBLEMA

O uso da Internet está cada vez mais difundido. A evolução dos sistemas

disponíveis através da Internet é constante; a gama de serviços acessados via Web está

cada vez mais abrangente; surgem novos componentes de hardware, como celulares e

palmtops, para acessar a grande quantidade de informações existentes na Web.

Portanto é imprescindível também que surjam meios mais seguros e confiáveis de

tornar essas informações disponíveis para todos esses novos usuários. As estruturas de

tecnologia de informação devem estar suficientemente maduras para lidar com o aumento

do acesso e o alto tráfego de informações.

Os Web Services se enquadram entre os novos meios criados para o acesso a

informações e a solicitação de serviços implementados remotamente. A arquitetura

orientada a serviços, utilizando serviços Web, está sendo muito discutida tanto no meio

acadêmico quanto nas empresas. Ela é considerada uma solução ideal para integração e

comunicação entre aplicações e processos.

Mas a arquitetura Web Services ainda é uma tecnologia nova, com padronizações a

serem definidas, especialmente no que se refere a questões de disponibilidade,

desempenho, segurança e qualidade de serviço. Enquanto essas questões não forem

tratadas e resolvidas, essa nova tecnologia não poderá ser utilizada em todo seu potencial

[3] [4].

1.2 OBJETIVOS

Este trabalho de conclusão de curso tem como objetivo principal estudar maneiras

de distribuir a carga, ou seja, as requisições recebidas através de uma rede de

computadores, entre Web services replicados em diferentes máquinas. Pretende-se, ao

13

final, propor uma heurística para balanceamento de carga entre réplicas de serviços Web

em um conjunto de servidores de aplicação.

Para tanto, os seguintes objetivos específicos foram determinados:

• Estudar as características da arquitetura Web Services e dos seus suportes de

execução, os servidores de aplicação;

• Estudar as especificações na área de roteamento e endereçamento de serviços Web;

• Estudar técnicas clássicas para balanceamento de carga, com o intuito de verificar

sua aplicabilidade para balanceamento de carga entre Web services;

• Depois de determinar qual técnica de balanceamento de carga é melhor para os

objetivos do trabalho, desenvolver e implementar uma solução de balanceamento

de carga para serviços Web;

• Implementar diferentes algoritmos de balanceamento de carga e realizar testes de

comparação, com o objetivo de verificar qual algoritmo é mais apropriado para o

balanceamento de mensagens destinadas a serviços Web.

1.3 JUSTIFICATIVA

A tecnologia de Serviços Web ainda não está completamente madura, e diversas

pesquisas ainda estão sendo realizadas nessa área. Atualmente, especificações para

diversas funcionalidades consideradas importantes em um ambiente distribuído, como

segurança e mensagens confiáveis, estão sendo desenvolvidas por órgãos como o World

Wide Web Consortium (W3C) [5]. Apesar de suas limitações, diversas empresas e

instituições têm apostado nesta tecnologia como o futuro padrão de mercado para

interconexão de aplicações.

Os Web services são serviços fim a fim disponíveis em um sistema distribuído e

para que possam ser utilizados em larga escala devem possuir características específicas de

desempenho. Para os Serviços Web serem uma realidade, eles devem possuir alta

disponibilidade e confiabilidade para servir aos milhares de usuários potenciais.

Em Tian et al [6], foi comparado o comportamento de servidores Web, durante

sobrecarga, para interações Web tradiciona is (conteúdo dinâmico) e para serviços Web.

Foi concluído que os serviços Web impõem uma sobrecarga adicional no servidor, porque

14

necessitam realizar a aná lise dos dados XML. Além disso, o tamanho dos dados

transferidos aumenta. Os experimentos mostraram que a sobrecarga causada pelos serviços

Web não pode ser negligenciada, pois pode reduzir a vazão do servidor e aumentar

consideravelmente o tempo de resposta durante uma demanda alta.

O balanceamento de carga existe porque, na maioria das vezes, a transmissão de

dados em rede é mais rápida do que o processamento desses dados por uma aplicação.

Atualmente, há um aumento no número de usuários e de acessos a aplicações Web e um

aumento do número de aplicações que se deseja tornar disponíveis online. Considerando

que, além disso, nos serviços Web há uma maior complexidade de processamento, devido

à análise das mensagens, verifica-se a importância que é tratar do desempenho de serviços

Web.

O desempenho de aplicações Web é normalmente medido pela rapidez com que a

aplicação responde a requisições URL. Entretanto, para uma avaliação mais completa

deveria ser incluído também o efeito de requisições simultâneas, a latência das respostas, a

escalabilidade, ou seja, poder lidar com o crescimento da demanda, e os níveis de

degradação operacional devido ao aumento da carga das requisições.

Existem muitos desafios no desenvolvimento de sistemas distribuídos utilizando a

tecnologia Web Services. A arquitetura Web Services precisa evoluir para que atenda

todos os requisitos necessários para sistemas distribuídos. Este trabalho vem contribuir

para esta evolução, inserindo-se em uma discussão importante para uma tecnologia

recente. A autora tem certeza de que para que essa tecnologia progrida e resista ao longo

do tempo, precisam ser apresentadas soluções para o seu problema de desempenho [4] [7]

[8]. Pois, mesmo com as interessantes características positivas dos Serviços Web, o

mercado de tecnologia da informação só investe e implanta tecnologias comprovadamente

eficientes.

1.4 ORGANIZAÇÃO DO TEXTO

O primeiro capítulo introduziu o assunto a ser abordado neste trabalho. Uma

descrição do problema pesquisado foi feita, assim como, a justificativa para a sua

resolução. Os objetivos do trabalho foram traçados.

15

O capítulo dois trata da revisão bibliográfica dos assuntos abordados neste trabalho.

Em primeiro lugar, apresenta-se uma revisão bibliográfica dos principais conceitos de

sistemas distribuídos e balanceamento de carga. Em segundo lugar, são introduzidos os

conceitos e as principais especificações da arquitetura Web Services, especialmente a

especificação WS-Addressing. Por último, mostra-se um resumo dos problemas de

desempenho relacionados a essa arquitetura.

No capítulo três, descreve-se a metodologia utilizada para solucionar o problema

apresentado neste trabalho. A solução proposta para o balanceamento de carga em Serviços

Web é mostrada, explicando-se as decisões tomadas.

No capítulo 4, apresentam-se detalhes da implementação da solução proposta. As

ferramentas utilizadas e as decisões de implementação são descritas.

Foram realizados testes para comparação do tempo de resposta utilizando a solução

apresentada com os algoritmos de balanceamento de carga implementados. Esses testes e

seus resultados são apresentados no capítulo 5.

Finalmente, as conclusões e resultados deste trabalho são apontados no capítulo 6.

Neste capítulo também são apresentadas sugestões para trabalhos futuros.

16

2 REVISÃO BIBLIOGRÁFICA

2.1 SISTEMAS DISTRIBUÍDOS

De acordo com Veríssimo et al [9], um sistema distribuído é um sistema composto

de vários computadores os quais se comunicam através de uma rede, hospedando

processos que usam um conjunto comum de protocolos distribuídos para auxiliar à correta

execução de atividades.

Segundo o W3C [10], um sistema distribuído é um conjunto de agentes de software

que estão em ambientes de processamento diferentes e devem cooperar para realizar

alguma tarefa. Para isso, eles precisam se comunicar usando pilhas de protocolos de

hardware ou software através de uma rede.

A Internet é uma rede de computadores, e não um sistema distribuído em si. Isso

porque uma das características principais nesse tipo de sistema é o compartilhamento de

estado que há entre processos que cooperam para atingir um determinado objetivo.

Entretanto, os dois conceitos se relacionam, pois muitos sistemas distribuídos se utilizam

da Internet e das tecnologias relacionadas a ela como meio de realizar essa cooperação.

Por ser feita através de uma rede, a comunicação em um sistema distribuído é

intrinsecamente menos rápida e menos confiável que aquela usando invocação direta de

código e memória compartilhada. Isso acarreta implicações importantes na arquitetura

desses sistemas, requerendo características como bom desempenho e a consideração de

problemas como latências imprevisíveis, concorrência e a possibilidade de falhas.

Entre os requisitos que um sistema distribuído deve apresentar para prover uma

funcionalidade completa está o desempenho. O desempenho é medido em termos de vazão

e latência. Alta vazão e baixa latência representam um serviço com bom desempenho. A

vazão (throughput) é a taxa na qual o trabalho computacional é feito [11]. Ou seja, ela

representa o número de requisições servidas durante um período de tempo. Essa medida é

afetada pelas velocidades de processamento nos clientes e no servidor e pelas taxas de

transmissão de dados entre eles. Latência, ou tempo de resposta, é o tempo entre o envio de

uma requisição e o recebimento da resposta.

A questão do desempenho em um sistema distribuído é essencial devido às

limitadas capacidades de processamento e comunicação entre computadores e redes.

17

Usuários de aplicações interativas esperam um tempo de resposta pequeno e constante.

Essas exigências são difíceis de atingir quando serviços remotos são utilizados, já que o

tempo em que a resposta é retornada depende não só dos processos no sistema servidor,

mas também da carga da rede empregada para comunicação.

O balanceamento de carga computacional é um mecanismo importante usado para

atingir escalabilidade e melhorar o desempenho em um sistema distribuído, que será

discutido a seguir.

2.1.1 Sistemas de Clusters de Servidores Web

O crescimento contínuo da Web tem causado um aumento nos problemas de

desempenho no acesso ao seu conteúdo, como altos tempos de resposta, congestionamento

na rede e negação e indisponibilidade de serviços. Além disso, atualmente, a maioria dos

conteúdos acessados na Web são dinâmicos. Esse tipo de conteúdo aumenta a demanda nos

servidores, principalmente para operações de entrada e saída e de CPU. Isso faz com que o

servidor, e não mais a rede e a sua largura de banda, se torne o gargalo mais crítico no

acesso a sites Web.

Para solucionar esse problema, adquirir uma máquina mais poderosa para o

servidor Web nem sempre é ideal, tanto pela pouca escalabilidade1 quanto pelo alto custo.

Uma solução mais interessante para dar suporte a esse aumento de demanda seria utilizar-

se de um agregado, ou cluster, de processadores que trabalham conjuntamente, servindo

como um único servidor Web.

Um Sistema de Servidores Web Distribuído pode ser visto como qualquer

arquitetura que consista de vários servidores que utilizam o mesmo mecanismo para

espalhar as requisições dos clientes entre esses servidores [12]. Os nós podem ser

localmente ou geograficamente distribuídos. É assumido que qualquer servidor no sistema

pode responder a qualquer requisição.

A arquitetura em cluster pode ser considerada um Sistema de Servidores Web

Distribuído localmente. Nela, um conjunto de servidores Web distribuídos localmente se

mostra para o exterior como uma entidade única, na qual chegam todas as requisições dos

clientes. Essa arquitetura também pode ser chamada de Sistema Paralelo. Essa solução

possibilita que múltiplas máquinas trabalhem como um único servidor, tornando o sistema 1 Por escalabilidade entende-se a habilidade do sistema de suportar o crescimento no número de usuários.

18

mais poderoso, pois os recursos de todos computadores que formam o cluster são

compartilhados para atender às requisições dos clientes. Entre as vantagens existentes na

utilização de um cluster de servidores Web encontram-se:

• Aumento de desempenho, pois há aumento na capacidade de receber solicitações;

• Melhor confiabilidade1 e disponibilidade2, pois o servidor pode continuar operando

mesmo se uma das máquinas no cluster falhar. A disponibilidade é provida através

de redundância de servidores. Quando um desses servidores falhar, esta falha será

mascarada, pois as requisições poderão ser enviadas a outros servidores ativos,

provendo maior confiabilidade;

• Tolerância a faltas 3, bem como a possibilidade de adicionar e retirar servidores do

cluster sem tornar as aplicações hospedadas no servidor indisponíveis;

• Escalabilidade facilitada, pois é simples aumentar a capacidade de um cluster pela

adição de novos servidores;

• Interface externa é única para todos computadores do cluster; assim, alterações na

configuração do cluster não afetam as aplicações clientes.

É importante que o ambiente de comunicação em um cluster seja bem

implementado para que os nós possam se comunicar uns com os outros e verificar com

maior precisão caso ocorra falha em um deles. O conteúdo servido por um cluster pode ser

replicado em cada máquina, compartilhado usando um sistema de arquivos em rede ou

acessado em um sistema de arquivos distribuído.

Em um sistema Web não se pode prever quando haverá um aumento tal no número

de clientes que tornará difícil o processamento das requisições. Com isso, podem ocorrer

falhas de sistema causadas por sobrecargas de requisições, que tornam os serviços

indisponíveis.

Por essa razão, para utilização de servidores em cluster, fazem-se necessários

mecanismos de distribuição e balanceamento de carga entre os computadores que

1 Confiabilidade representa o grau de capacidade de manter o serviço e a qualidade desse serviço. O número de falhas por mês ou ano representa uma medida de confiabilidade. Outro conceito diz que confiabilidade refere -se à entrega garantida e em ordem de mensagens entre consumidores e provedores de serviços. [6] 2 Disponibilidade é a medida de temp o em que um sistema está ativo e funcionando [8]. 3 Tolerância a faltas é a habilidade de um sistema de continuar a operar de modo válido apesar da ocorrência de uma ou mais faltas no sistema ou em parte dele [8].

19

desempenham o papel de servidor para aplicações Web. Como vários servidores podem

processar os pedidos, deve-se determinar como alocar eficientemente as requisições nos

servidores disponíveis.

Dessa maneira, cada requisição destinada ao host será distribuída, baseada em

algoritmos de balanceamento de carga, para um dos servidores do cluster. Essa distribuição

pode ser feita tanto por um software quanto por um dispositivo de hardware feito

especialmente para este fim. Também é necessário o gerenciamento de estado, pois como é

possível que vários servidores manipulem a mesma sessão de um usuário, deve-se

determinar como manter o estado, ou contexto de sessão, entre os servidores e os clientes.

2.2 BALANCEAMENTO DE CARGA

Existem várias abordagens que distribuem as requisições de clientes entre

diferentes servidores para melhorar o desempenho de uma aplicação ou site Web. Neste

trabalho, será dada atenção às soluções que distribuem requisições em um conjunto de

servidores Web.

Para o uso da distribuição balanceada de requisições em um sistema de servidores

Web, deve haver uma política que distribua a carga recebida de maneira uniforme para

todos esses servidores, não sobrecarregando um deles enquanto outro está disponível.

Balanceamento de carga (load balancing) é um mecanismo usado para atingir

escalabilidade através da redistribuição de carga entre os elementos de processamento em

um conjunto de servidores. Entre os objetivos do uso de balanceamento de carga estão o

aumento da vazão do sistema e a diminuição do tempo de resposta às requisições de

clientes, pela diminuição do tempo de execução da aplicação, o que torna o seu uso crítico

ao se manter um cluster de servidores de alto desempenho. As requisições precisam ser

distribuídas entre os nós de modo a reduzir o tempo de resposta e prover aos usuários a

melhor qualidade de serviço disponível.

A distribuição de carga das requisições dos clientes para o servidor apropriado pode

ser realizada de várias maneiras. Um exemplo simples é o de sites que espalham seus

conteúdos em diferentes servidores, permitindo que o usuário selecione, de uma lista de

sites replicados e independentes, o servidor que melhor lhe convém. Porém essa solução

não é eficiente, já que depende de uma escolha feita pelo usuário final para melhorar o

20

desempenho do site. O interessante é que essa tarefa seja realizada de modo transparente e

automatizado.

No balanceamento de carga realizado em um sistema servidor Web baseado em

cluster existem dois integrantes essenciais: a entidade que realiza a tarefa de

balanceamento de carga e o algoritmo usado para decisão de como serão distribuídas as

requisições entre os servidores que fazem parte do cluster.

Segundo Cardellini et al [12], com relação às entidades que realizam o

balanceamento de carga, podem existir quatro abordagens: baseada no cliente, no servidor

DNS, em um despachante (dispatcher) e no servidor. A seguir, serão descritas abordagens

automatizadas para o balanceamento de carga, segundo esta categorização.

2.2.1 Abordagem baseada no cliente

Esta abordagem pode ser aplicada mesmo em um conjunto de servidores que não

estão coordenados entre si. Isso porque a modificação necessária para realizar a

distribuição de carga é feita no cliente. Por cliente entende-se um programa, geralmente

um navegador, que estabelece conexões com um servidor para responder às requisições do

usuário.

A implementação da abordagem é feita pela alteração do cliente, seja ele um

navegador ou mesmo um servidor proxy, fazendo com que este conheça os diferentes

servidores existentes no sistema de servidores Web. Assim, quando ele recebe a requisição

do usuário, seleciona um dos nós do cluster e envia esta requisição ao servidor escolhido,

que responderá a este cliente. Na próxima requisição do usuário, um servidor diferente

pode ser selecionado.

Essa é uma solução muito simples e transparente para o usuário final, mas exige o

uso de extensões no cliente, com alterações no código do navegador ou pelo uso de applets

Java [13], migrando funcionalidades do servidor para a máquina do usuário ou servidor

proxy. Apesar dessa abordagem solucionar o problema do balanceamento de carga entre

servidores, a necessidade de modificações no cliente a torna quase sempre inviável, visto

que os clientes e servidores Web geralmente não são controlados pela mesma instituição

ou empresa. Consegue-se maior transparência para os clientes com o uso de abordagens de

balanceamento baseadas nas entidades servidoras, como servidores DNS, despachantes ou

mesmo os próprios servidores Web.

21

2.2.2 Abordagem baseada no servidor DNS

Nesta abordagem, a responsabilidade de distribuir requisições é dada ao servidor

Domain Name Service (DNS), serviço de nomes de domínio. Esse servidor tem autoridade

para responder ao mapeamento do endereço URL do cluster em um ou mais endereços IP.

Assim, ele permite que um mesmo domínio possa ser mapeado para os diferentes

endereços IP das máquinas do cluster. O servidor DNS pode implementar vários tipos de

políticas de distribuição de tráfego para o servidor mais apropriado.

Ao receber uma requisição de mapeamento, o servidor DNS primário do cluster

seleciona o nó mais apropriado e especifica um tempo de validade para o cache desse

mapeamento, conhecido como Time-To-Live (TTL). Depois que o mapeamento expira, a

requisição de mapeamento é novamente enviada para o servidor primário do cluster e

então ele pode novamente realizar a distribuição do tráfego. De outra maneira, a requisição

de mapeamento é respondida por uma das entidades intermediárias que possuem

informações em cache sobre aquela URL.

O uso de cache existe para facilitar e agilizar o processo de mapeamento, mas

também é um problema dessa abordagem, já que o servidor DNS tem controle limitado

sobre a distribuição de carga. Primeiro, a solicitação do cliente é enviada para o servidor

DNS local e, se este não puder resolver o nome, ele usa regras bem definidas para enviar a

solicitação para outro servidor DNS, e assim por diante. Em último caso, o servidor DNS

primário, responsável por resolver o nome em questão e onde é realizado o balanceamento

de carga, é quem responde à requisição.

Esse é um problema maior especialmente para sites mais populares. Um servidor

DNS local utilizado por muitos clientes irá sobrecarregar o servidor indicado pelo endereço

IP em cache e fazer com que a informação atual sobre a carga fique obsoleta rapidamente e

seja fracamente relacionada com a possível carga futura. Para minimizar esse problema, o

valor TTL associado com uma entrada DNS pode ser diminuído. Entretanto, com a

diminuição do uso de cache, aumentará a carga no servidor DNS do cluster, que pode se

tornar um possível gargalo de requisições.

Os algoritmos de distribuição de carga nessa abordagem se dividem naqueles que

usam valores de TTL constantes ou adaptáveis. Um exemplo que usa valores constantes é

o algoritmo de Round-robin DNS, ou DNS-RR, implementado pelo National Center for

22

Supercomputing Applications (NCSA) [14]. O servidor DNS do NCSA foi modificado

para implementar um algoritmo Round-robin para o mapeamento de endereços, ou seja,

duas requisições consecutivas terão respostas diferentes.

A desvantagem desse algoritmo é que ele ignora informações sobre a capacidade e

a disponibilidade dos nós. Conhecer as condições do estado atual do cluster de servidores é

obrigatório, pois somente assim pode-se excluir nós não-alcançáveis devido a falhas ou

congestionamentos. Uma solução simples é usar, em combinação com as políticas DNS,

um alarme que avisa quando um servidor está sobrecarregado. Outra solução é basear o

balanceamento nas informações sobre a carga atual dos servidores, escolhendo aquele

menos carregado.

Os algoritmos de distribuição de carga pelo DNS podem usar ainda informações

vindas do cliente, como por exemplo: a carga que chega ao sistema para cada domínio

conectado e a localização geográfica do cliente. A maioria dos algoritmos DNS consegue

melhores resultados quando usa tanto informações de estado do cliente quanto do servidor

[15].

Somente explorar a política para escolher o servidor com valores TTL constantes é

insuficiente. Por isso foram propostas soluções que ajustam os valores do TTL baseado em

diferentes critérios. Uma melhor alternativa é dar diferentes valores de TTL para cada

requisição de endereço (algoritmos TTL adaptativo), para levar em conta situações como a

distribuição desigual da carga dos domínios e as diferentes capacidades dos servidores.

O TTL adaptativo usa um processo de decisão de dois passos. No primeiro, o DNS

seleciona o servidor Web e, no segundo, escolhe o valor apropriado para o TTL. A

distribuição desigual de carga de domínio é controlada pelo uso de valores de TTL

inversamente proporcionais à taxa de requisição do domínio. Por exemplo, as requisições

de endereço vindos de domínios muito populares receberão um valor menor de TTL do que

aquelas vindas de domínios menores.

Algoritmos de TTL adaptativo são mais robustos e efetivos no balanceamento de

carga, mesmo na presença de cargas com variância e servidores de nome não-cooperativos

(que não usam o TTL configurado pelo DNS primário). Uma política que usa TTL

adaptativo e informações de localização do cliente pode conseguir desempenho melhor

ainda.

23

Uma grande desvantagem do uso de cluster de servidores baseado em DNS é que

os endereços IP de todos os nós do cluster estão expostos para a Internet. Quando um

servidor falha ou é posto em manutenção, um cliente pode ainda tentar acessar essa

máquina, porque o servidor DNS não está ciente do estado do servidor ou o endereço IP

dessa máquina está em cache em um dos intermediários entre o cliente e o servidor.

Ainda, por controlar somente uma parte das requisições, o distribuidor DNS precisa

utilizar algoritmos sofisticados para conseguir um bom desempenho. Eles são tip icamente

baseados em informações sobre o estado dos servidores e informações dos clientes.

2.2.3 Abordagem baseada em despachante

Ao contrário da anterior, esta abordagem objetiva ter controle total sobre as

requisições de clientes e mascara o roteamento dessas requisições entre os vários

servidores. Para esse propósito, ela estende a virtualização de endereços, que no DNS era

feita no nível do endereço URL. Agora, ela é feita para o endereço IP, fazendo com que o

cluster Web tenha somente um único endereço IP virtual (IP-SVA, ou IP-Single Virtual

Address). Na verdade, este é o endereço de IP do despachante, ou dispatcher, que age

como um centralizador, com controle total sobre as requisições dos clientes.

Essa abordagem geralmente usa algoritmos mais simples para selecionar o nó

servidor porque o despachante deve gerenciar todas as requisições que chegam no cluster,

e a quantidade de processamento necessária para cada requisição deve ser mantida ao

mínimo. Os tipos de algoritmo de balanceamento comumente usados nessa abordagem são

o Round-robin (RR), que não considera a carga atual de cada um dos servidores, Least

Connection (LC), que distribui a carga baseado no servidor que tem menos conexões

HTTP e Least Loaded (LL), que distribui as requisições baseado na carga de trabalho, isto

é, a soma do tempo de serviço de todas requisições pendentes em um servidor.

Segundo Teo et al [16], que apresenta comparações entre esses três algoritmos, o

LL é o melhor algoritmo, com o RR apresentando os piores resultados. Com o aumento da

taxa de requisições, o desempenho dos três algoritmos converge, com os algoritmos LL e

LC tendo um melhor desempenho para cargas médias e altas.

O despachante pode ser hardware ou software e interceptar os pedidos em

diferentes camadas do modelo OSI. Despachantes da camada quatro, de Transporte, não

têm informações sobre o conteúdo da requisição, pois eles determinam o servidor alvo

24

quando o cliente estabelece uma conexão TCP-IP. Já os despachantes da camada sete, de

Aplicação, possuem informações úteis sobre o conteúdo da requisição, pois têm acesso à

requisição HTTP. Assim, o mecanismo de balanceamento de carga pode ser baseado no

serviço que está sendo requisitado.

As duas principais formas de classificação nessa abordagem, de acordo com o

modo que ela direciona as requisições para um dos nós do cluster são: mecanismos de

reescrita e de redirecionamento HTTP.

Os mecanismos de reescrita podem ser de dois tipos. Na reescrita única de pacotes

pelo despachante, este encaminha pacotes vindos do cliente para o servidor através da

reescrita do endereço IP. Todas as requisições HTTP chegam no despachante porque o IP-

SVA é o único endereço público. O roteamento para um dos servidores é feito com a

reescrita do endereço IP de destino de cada pacote que chega ao despachante, substituindo

o seu IP-SVA com o endereço IP do servidor selecionado. Como uma requisição consiste

de diversos pacotes, é necessário manter uma lista dos endereços IP fontes para cada

conexão TCP estabelecida. Assim, o despachante pode encaminhar sempre ao mesmo nó

os pacotes pertencentes à mesma conexão. Da mesma forma, o nó servidor selecionado,

antes de enviar os pacotes de resposta ao cliente, precisa substituir o seu endereço IP pelo

endereço IP virtual do despachante. Assim, o cliente não tem ciência de que está acessando

um cluster de servidores.

Na reescrita dupla de pacotes pelo despachante, os passos são os mesmos que os

descritos para o primeiro tipo. A diferença é que o despachante, além de reescrever os

pacotes que chegam no sistema, também modifica o endereço dos pacotes de resposta,

substituindo o endereço do nó escolhido pelo seu endereço IP virtual. Essa opção apresenta

piores resultados do que a primeira, pois congestiona ainda mais o despachante.

A segunda classificação das abordagens baseadas em despachante compreende as

soluções que utilizam o redirecionamento dos pacotes de clientes para encaminhá- los ao

servidor escolhido. Um exemplo é a solução da IBM chamada LAN Network Dispatcher

[17]. Ela assume que o despachante e os nós servidores estão na mesma rede local,

compartilhando o mesmo endereço IP virtual. Os pacotes chegam somente à máquina

Network Dispatcher porque os nós desabilitaram seus mecanismos de resolução de

endereço ARP. O despachante pode, então, encaminhar esses pacotes para o servidor

selecionado usando seu endereço físico, sem modificar o cabeçalho TCP. Esta solução é

25

transparente tanto para o cliente quanto para o servidor porque não necessita de reescrita de

pacotes.

Outro exemplo encontrado é o sistema ONE-IP [18], que publica o mesmo

endereço IP secundário, o IP-SVA, dado a todos os nós do cluster de servidores. Nesse

exemplo, ao contrário dos outros, nenhuma máquina possui o IP-SVA como seu endereço

primário. A comunicação entre servidores do cluster é feita utilizando os seus endereços IP

primários e as requisições de clientes chegam somente ao endereço secundário. Ele utiliza

uma função hash para identificar unicamente o servidor que foi selecionado para uma

determinada requisição. O despachante envia os pacotes a todos servidores, que verificam,

através da função hash, se eles são o destino dos pacotes. O uso de hash foi escolhido para

solucionar situações em que a grande quantidade de requisições torna o despachante um

gargalo de acesso ao sistema. Mas esta solução acaba sendo também o ponto fraco dessa

abordagem, pois não permite balanceamento de carga dinâmico e, além disso, não leva em

conta a heterogeneidade dos servidores.

Em outra abordagem, o redirecionamento é feito por um despachante que distribui

as requisições entre os nós do cluster através de um mecanismo existente no protocolo

HTTP. Esse protocolo permite que o redirecionamento seja feito pela especificação, na

resposta, de um código de status indicando no seu cabeçalho o endereço do servidor no

qual o cliente pode conseguir o documento requisitado. Esse redirecionamento é

transparente ao usuário, embora seja possível notar um maior tempo de resposta, pois o

número de conexões TCP necessárias é duplicado.

A maior desvantagem de soluções baseadas em um despachante é a presença de

uma única entidade de decisão, tornando-se um ponto de falha único e um gargalo para o

sistema quando é submetido a crescentes taxas de requisições. Se o despachante falhar,

nenhuma requisição é recebida pelo cluster. Ele também deve ter a capacidade de perceber

quando um dos nós do cluster falha. O ideal é que o despachante tenha mecanismos para a

detecção de falha, para redirecionar a carga de acordo com essas informações.

Nem as soluções baseadas em DNS nem as baseadas em despachantes provêem um

modo conveniente para dinamicamente recrutar recursos inativos durante picos de carga. A

capacidade de balanceamento de carga provida por um despachante ainda é limitada, pois

ele precisa encaminhar os pacotes o mais rápido possível.

26

2.2.4 Abordagem baseada no servidor

As técnicas baseadas no servidor usam mecanismo de distribuição em dois níveis:

uma requisição é inicialmente determinada pelo DNS do cluster para um dos servidores

Web, e então o servidor escolhido pode redistribuí- la para qualquer outro nó no cluster. Ao

contrário das outras abordagens, esta permite que todos os servidores participem no

balanceamento da carga através de mecanismos de redistribuição de requisições. A decisão

de servir ou redirecionar uma requisição pode ser feita baseada em diversos critérios. A

integração da abordagem baseada no DNS com alguma técnica de redirecionamento feito

pelos servidores Web objetiva resolver a maioria dos problemas que afetam as políticas de

distribuição DNS, já mencionados anteriormente. As abordagens baseadas no servidor se

diferenciam pelo modo como a decisão de redirecionamento é feita e implementada.

Um exemplo do redirecionamento HTTP pelo servidor é o sistema Scalable Server

World Wide Web (SWEB) [19]. A arquitetura SWEB usa uma política DNS-RR como o

modo de distribuição no primeiro nível e um esquema de distribuição assíncrona como

modo de distribuição no segundo nível. Cada servidor decide se irá redirecionar baseado

em um critério de seleção, que leva em conta capacidades de processamento dos servidores

e o atraso e a largura de banda da rede.

Uma desvantagem desse método é o aumento no tempo de resposta para o cliente,

pois para cada requisição é necessário criar uma nova requisição no redirecionamento.

Outra desvantagem é que esse método expõe os endereços IP dos servidores do cluster,

diretamente ou através de servidores DNS, podendo ser usados para acessar o site mesmo

quando um servidor está indisponível, devido à falha ou à manutenção.

Os mecanismos de redistribuição propostos implicam também em uma sobrecarga

da comunicação dentro do cluster, pois cada servidor precisa transmitir periodicamente

informações sobre seu estado. Entretanto, esse custo pode ser considerado desprezível no

tráfego total da rede. Na verdade, a maior desvantagem para o usuário é o

redirecionamento HTTP.

Outro exemplo de redirecionamento de pacotes pelo servidor é o Distributed Packet

Rewriting (DPR) [20] que também utiliza um mecanismo DNS-RR para realizar a primeira

distribuição de requisições. O servidor selecionado pode reenviar a requisição para outro

servidor através de um mecanismo de reescrita de pacote que é transparente para o cliente.

27

Dois algoritmos de balanceamento de carga foram propostos pelos autores do mecanismo.

O primeiro usa uma função de roteamento estático, na qual o destino é escolhido por uma

função hash, e o segundo requer comunicação periódica entre os servidores sobre a sua

carga atual, redirecionando para o servidor com menor carga.

2.3 WEB SERVICES

Um serviço é uma abstração de um conjunto de operações, com uma funcionalidade

em comum, oferecido a clientes. O termo Web Service pode ser definido de diversas

maneiras. Nessa revisão destacam-se três conceitos principais.

O primeiro conceito afirma que Web Services é uma arquitetura orientada a

serviços que permite interoperabilidade entre diferentes plataformas através do uso de

padrões abertos, ou seja, padrões que podem ser implementados por qualquer fabricante

[21]. Foi construída utilizando protocolos Web já existentes e é baseada em XML, uma

metalinguagem padrão para representação e transferência de dados do tipo texto através de

tags de marcação.

No segundo conceito diz-se que essa arquitetura disponibiliza um mecanismo único

para descrição, localização e comunicação entre aplicações acessíveis online. Assim, por

um Web Service entende-se um serviço disponível na Web que pode ser descrito,

publicado, localizado e chamado através de protocolos padrões da Internet usando

mensagens no formato XML [22].

Por último, o terceiro conceito, de autoria do W3C [23], um Web Service é um

sistema de software projetado para dar suporte à interação entre máquinas através de uma

rede. Ele possui uma interface descrita em um formato possível de ser processado por

computadores (WSDL). Outros sistemas interagem com um serviço Web, baseados na sua

descrição, usando mensagens SOAP, normalmente transportadas usando HTTP com

serialização XML em conjunto com outros padrões Web. Um Web service é um conceito

abstrato que precisa ser implementado por um agente, que é o software ou hardware que

envia e recebe mensagens.

Resumindo, um Web service é um serviço identificado por um URI (Uniform

Resource Identifier) que pode ser acessado por aplicações através de protocolos Web de

acordo com o contrato que descreve a sua interface.

28

A Web tem tido um gigantesco sucesso na interação entre humanos e

computadores. A simplicidade do protocolo HTTP e da linguagem de marcação HTML

permitiu que fossem implementados em uma variedade de sistemas operacionais e

ambientes de programação. Os Web Services usam muitas das idéias e princípios da Web

para interação entre computadores. Assim como a Web, os Serviços Web utilizam

protocolos simples e baseados em texto, que podem ser utilizados de forma modular,

acrescentando somente as funcionalidades desejadas, e permitem a sua implementação em

diversas plataformas.

O XML, juntamente com a sua linguagem de definição formal, a XML Schema

(esquema XML), ajuda a facilitar e melhorar a integração entre aplicações através da

eliminação de ambigüidade e pelo suporte à validação das mensagens trocadas.

Cada vez que um usuário visita um site na Web, pode-se dizer que ele está fazendo,

indiretamente, uma chamada remota de procedimento, ou Remote Procedure Call (RPC).

O RPC é uma abstração para remotamente executar chamadas a procedimentos em uma

linguagem de programação. O cliente, um navegador, requisita um arquivo de um servidor

com uma requisição em formato HTTP, que então processa e mostra as informações de

resposta em formato HTML.

Inicialmente, o conceito de Web Services era muito vinculado ao de chamada

remota de procedimentos, na qual tanto requisição quanto resposta são codificadas em

formato XML. No princípio, o que deu notoriedade à tecnologia Web Services foi a

possibilidade de conectar sistemas díspares usando tecnologias independentes de

plataforma com a possibilidade de trafegar mesmo através de firewalls. Os

desenvolvedores tinham acesso a um conjunto de tecnologias que se assemelhavam à de

objetos distribuídos, o SOAP era considerado um protocolo de acesso a objetos e o WSDL

era visto como um protocolo de descrição de interface de classes. Não poderia deixar de

ser assim, já que, nessa época, o próprio termo SOAP era um acrônimo para Simple Object

Access Protocol ou Protocolo Simples de Acesso a Objetos. Tudo isso levava a crer que

esta nova arquitetura que surgia era mais um meio de se realizar chamadas remotas a

procedimentos ou objetos.

Essa idéia inicial está sendo aos poucos substituída por uma visão orientada à troca

de mensagens em uma arquitetura orientada a serviços (SOA). Desse modo, pode-se trocar

documentos XML completos entre consumidores e serviços. A partir da especificação

29

SOAP 1.2, o acrônimo original deixou de ser utilizado e o uso de RPC não é mais

obrigatório.

Por isso, é importante lembrar que esta não é uma arquitetura de objetos

distribuídos [24], o mais correto seria vê-la como uma arquitetura orientada a serviços que

processa documentos XML. Sistemas baseados em mensagens escondem a sua

implementação dos seus consumidores e seus serviços possuem uma granularidade maior

do que sistemas RPC ou objetos distribuídos.

Um serviço Web implementa uma funcionalidade específica que pode ser utilizada

por outros serviços ou por aplicações, permitindo a composição de serviços para montar

aplicações Web. É necessário salientar que, embora usuários finais possam acessar

diretamente serviços, seu propósito principal é que seja utilizado por outras aplicações ou

serviços.

Os serviços Web têm sido empregados em vários tipos de aplicação. Como

exemplos, pode-se citar:

• Uso de serviços Web como interface para sistemas legados ou sistemas que não

estão expostos na Internet. Atualmente é crescente a necessidade de tornar

processos de negócio disponíveis para parceiros e clientes. O uso de serviços Web

torna desnecessária a criação de uma nova infra-estrutura de aplicação para

descrever os processos de negócio em um ambiente Internet. Com o uso dessa

arquitetura, é necessária somente a criação das interfaces de comunicação para

disponibilizar aplicações já existentes como serviços Web.

• Ao invés de vender um software, uma empresa pode vender serviços ou assinaturas

desses serviços, tornando-os disponíveis na Internet, como por exemplo, um

serviço de análise de crédito ou de previsão do tempo. Uma pessoa ou empresa que

necessite desse serviço, ao invés de desenvolver novamente uma solução,

simplesmente acessa o Web service para obter essa funcionalidade.

• Por ser uma tecnologia de integração, Web services estão sendo usados não só para

integrar aplicações finais, mas, também, Data Warehouses e fazer a comunicação

entre computadores em grades (Grids).

• Serviços mais simples podem ser combinados para compor um serviço mais

complexo, utilizando serviços como componentes de software, auxiliando no

30

desenvolvimento de aplicações distribuídas. Por exemplo, um serviço de uma

empresa de turismo pode utilizar serviços fornecidos por hotéis, locadoras de

carros, de previsão do tempo, etc.

• Na mesma linha do exemplo anterior, existe a automatização do gerenciamento de

processos de negócio através da orquestração de serviços. Nesse modelo, os

processos de negócio são padronizados em uma camada de serviços. Dessa

maneira, eles podem ser compostos e associados a outros serviços, formando um

fluxo de chamada de serviços. Uma orquestração define as seqüências e condições

nas quais um serviço Web requisita outros serviços Web para realizar alguma

funcionalidade. Ou seja, uma orquestração é o padrão de interação que um serviço

Web deve seguir para alcançar um objetivo [23].

2.3.1 Arquitetura Orientada a Serviços – SOA

Embora seja uma tecnologia nova, a arquitetura Web Services está baseada em

princípios já bem estabelecidos de projeto de sistemas para comunicação entre aplicações.

Esses princípios são conhecidos como Service-oriented Architecture, ou Arquitetura

Orientada a Serviços (SOA).

SOA é uma arquitetura cujo objetivo é alcançar o fraco acoplamento entre agentes

de software que realizam uma interação. Um serviço é uma unidade de trabalho realizada

por um provedor o qual enviará os resultados desse trabalho para um consumidor. Tanto o

provedor quanto o consumidor são papéis desempenhados por agentes de software.

Segundo definição do W3C [23], SOA é um conjunto de componentes que podem

ser invocados e ter suas descrições de interface publicadas e descobertas. Exemplos de

sistemas SOA incluem DCE, DCOM e CORBA. A arquitetura Web Services representa a

união do SOA com a Web, tornando-a, por isso, independente de plataforma e linguagem.

Atualmente vem crescendo a popularidade das arquiteturas SOA. Tanto a

arquitetura Web Services quanto a SOA tiraram muitas de suas idéias de conceitos como:

componentes de software, objetos distribuídos e middleware orientado a mensagens. Da

orientação a objetos, veio o conceito de encapsulamento e polimorfismo. O uso obrigatório

de interfaces foi adotado dos componentes e a noção de contexto e conexão baseada em

brokers veio dos objetos distribuídos. Do middleware orientado a mensagens veio o uso de

filas e, obviamente, a comunicação através de troca de mensagens.

31

Os três papéis básicos que um sistema SOA possui são: provedor, consumidor e

broker (ou intermediador). Um provedor de serviço o torna disponível e publica o contrato

que descreve a sua interface através de um registro no broker. Um consumidor pesquisa no

broker os serviços que deseja. Este fornece ao consumidor informações de localização e de

contrato do serviço, que são usadas para ligar (bind) o consumidor ao serviço.

Para que essa dinâmica seja possível, um sistema SOA deve prover três

componentes de arquitetura [22]:

• Transporte: o componente de transporte representa os formatos e protocolos usados

para se comunicar com um serviço. O formato dos dados especifica os tipos de

dados usados para codificar as mensagens. O protocolo de transferência especifica

as semânticas de aplicação que controlam uma transferência de mensagem. Já o

protocolo de transporte realiza essa transferência.

• Descrição: o componente de descrição representa as linguagens usadas para

descrever um serviço, provendo as informações necessárias para acessá-lo. Uma

linguagem de descrição deve prover também um modo de especificar o contrato do

serviço, incluindo as operações que ele realiza e quais são seus parâmetros. Essa

linguagem pode ter a capacidade de ser lida por compiladores para gerar código de

comunicação, como client proxies ou stubs.

• Descobrimento: o componente de descobrimento representa os mecanismos usados

para registrar, anunciar e encontrar um serviço e sua descrição. Ele pode dar

suporte à ligação estática ou dinâmica entre o consumidor e o serviço.

Java RMI [25], CORBA [26], DCE [27], e DCOM [28] são sistemas distribuídos

que surgiram anteriormente aos serviços Web. Eles definiram, cada um, o seu conjunto de

formatos e protocolos para implementar funções SOA. Essa abordagem, embora garanta a

consistência entre as aplicações que compartilham a mesma plataforma, limita a

interoperabilidade entre aplicações que utilizam plataformas diferentes. Por usar XML,

qualquer linguagem em qualquer plataforma pode interpretar os mecanismos de

mensagens, descrição e descobrimento de serviços Web.

32

2.3.2 Histórico

A partir do momento em que o desenvolvimento de software passou a adotar o

paradigma orientado a objetos (OO), com promessas de reutilização de código e fácil

manutenção, os sistemas distribuídos também começaram a ser vistos pela ótica OO.

Surge então, através do Object Management Group (OMG), o Common Object

Request Broker Architecture, ou CORBA [26], que era uma tentativa de padronizar o uso

de procedimentos distribuídos, focando nas requisições a métodos de objetos remotos. As

dificuldades do CORBA estavam justamente aí, pois por ser OO, precisava manter o

estado dos objetos de forma transparente e gerenciar os seus ciclos de vida, tornando esse

sistema menos escalável. O mesmo problema afligia a solução da Microsoft para objetos

distribuídos: Component Object Model (COM) e o protocolo de objetos remotos DCOM

[28].

Na mesma época, o e-mail e a Web estavam se tornando cada vez mais populares,

tornando-se um exemplo de arquitetura distribuída de grande sucesso. Desenvolvedores

procuravam arquiteturas distribuídas que tinham como características o fraco acoplamento

de tecnologias de mensagens e a onipresença da Internet. A busca por padrões que fossem

assimilados pelas maiores empresas de tecnologia também era vista como importante, pois

isso reduziria os riscos de mudança para essa nova tecnologia distribuída. Neste período,

surgiram a linguagem Java [29] e seu protocolo RMI (Remote Method Invocation) [25],

uma implementação de RPC nativa para essa linguagem.

O surgimento de todas essas tecnologias mostrou que as características esperadas

para sistemas de chamadas remotas de mé todos eram [30] [31]:

• Possibilidade de distribuir operações dentro de uma mesma aplicação;

• O uso de serviços genéricos nas aplicações, para troca de dados dentro e entre

organizações;

• Estar de acordo com a infra-estrutura, já existente e padrão, da Interne t;

• Habilidade para crescimento em escala conforme a complexidade do sistema

aumenta;

• Internacionalização;

• Tolerância a faltas; e

33

• Possibilidade tanto de realizar chamadas simples quanto complexas.

Um dos primeiros produtos a surgir, tendo em vista essas características, foi o e-

Speak, da HP [32], lançado em 1999, que segundo Ogbuji [30] [31] foi a primeira

tecnologia Web Service a ser comercializada. Usando protocolos genéricos como HTTP e

representando dados em XML, ele tratava sistemas em rede como “e-services” com os

quais era possível trocar fluxos de dados. Entretanto, com o sucesso da arquitetura Web

Services, a HP acabou por desistir desse projeto e se unir às outras empresas na

especificação dessa nova arquitetura.

Em 1998, foram dados os primeiros passos do que hoje é o popular protocolo

SOAP, por um conjunto de empresas, incluindo a Microsoft. Sua versão, conforme é

conhecida hoje, foi lançada em 1999.

O Web Interface Definition Language (WIDL), da empresa WebMethods foi um

dos primeiros protocolos para especificação dos serviços Web. Ele foi baseado na Interface

Definition Language que é usada no CORBA e no COM. A Microsoft desenvolveu o

Service Description Language (SDL) e o SOAP Contract Language (SCL) em 2000 para a

descrição de serviços e o Discovery of Web Services (DISCO), que permitia a busca de

serviços pelos seus SCL.

A IBM também criou as suas especificações: Network Accessible Service

Specification Language (NASSL), com os mesmos objetivos do SDL e do SCL e

Advertisement and Discovery of Services (ADS), que era similar ao DISCO, e foram

incorporadas ao conjunto de ferramentas para desenvolvimento de Web Services da IBM,

o alphaWorks.

As especificações NASSL, SDL e SCL uniram-se para formar o Web Services

Description Language (WSDL) [33], desenvolvido originalmente pela IBM, Microsoft e

Ariba. Essas três empresas também reuniram as suas especificações sobre descoberta de

serviços e, em conjunto com outras, lançaram o Universal Description, Discovery and

Integration (UDDI) [34].

Em abril de 2001 foi realizado o W3C Workshop on Web services (WSWS) [35],

com o objetivo de planejar o futuro dos Web Services. Até essa data, a arquitetura Web

Services tinha sido desenvolvida fora do W3C. O objetivo do WSWS era garantir a forma

e os objetivos das atividades relacionadas a Web Services no W3C. O principal tema do

34

Workshop, com a consolidação de protocolos como SOAP [36] e WSDL, foi a Arquitetura

Web Services e como novas funcionalidades, como segurança e transações, se

enquadrariam nela.

Tem-se então, o cenário atual de desenvolvimento da Arquitetura Web Services,

com os protocolos SOAP, WSDL e UDDI sendo considerados a base padrão para o seu

desenvolvimento e diversas empresas e órgãos padronizadores envolvidos na criação e

especificação de novos protocolos que implementam funcionalidades necessárias em uma

arquitetura distribuída.

2.3.3 Arquitetura Web Services

De acordo com Cabrera et al [37], os princípios básicos que dirigem o projeto e

implementação dos protocolos da arquitetura Web Services são:

• Orientação a mensagens, ou seja, usar mensagens para a comunicação entre

serviços, sendo estas consideradas as unidades atômicas do processo de

comunicação entre aplicações;

• Protocolos são vistos como componentes, e com isso, eles podem ser usados na

combinação que melhor convir ao sistema desenvolvido;

• Serviços são autônomos, o que permite que endpoints1 possam ser construídos,

implantados (deployed) e gerenciados de forma independente;

• Transparência do serviço é gerenciável, permitindo controlar quais aspectos de um

endpoint são visíveis externamente;

• Integração entre aplicações é baseada somente na definição e troca de mensagens.

Isso permite a integração de aplicações de plataformas e sistemas operacionais

diferentes.

Como mencionado anteriormente, qualquer arquitetura orientada a serviços deve

prover, no mínimo, três componentes: transporte, descrição e descobrimento. Na

arquitetura de Serviços Web, existem especificações para cada uma dessas áreas, chamadas

1 Um endpoint é uma associação entre uma ligação (binding) e um endereço de rede, especificado por um URI, que pode ser usado para a comunicação com uma instância de um serviço. Ele indica um local para o acesso a um serviço usando um protocolo e formato de dados específicos. Por binding, entende-se a associação entre uma interface, um protocolo e um formato de dados. Ela especifica o protocolo e formato de dados a serem usados ao se transmitir mensagens definidas pela interface associada. [23]

35

SOAP, WSDL e UDDI, respectivamente. A interface de um serviço Web é descrita

utilizando-se o protocolo WSDL. Essa descrição pode ser publicada em um registro UDDI,

no qual consumidores pesquisam os serviços que desejam acessar. Ela também especifica o

local no qual o serviço pode ser acessado e qual deve ser o formato das mensagens

trocadas. Assim, consumidores e serviços utilizam o protocolo SOAP para enviar e receber

mensagens.

Figura 1 – Arquitetura SOA e protocolos Web Services.

2.3.4 SOAP

O protocolo SOAP é a infra-estrutura fundamental de troca de mensagens utilizada

por consumidores e provedores de serviços Web. Ele isola a transferência de mensagens

dos detalhes da camada de transporte, realizando a comunicação entre serviços. Assim,

informações específicas dos protocolos dessa camada não se misturam com a semântica da

aplicação, permitindo interoperabilidade de serviços em diferentes plataformas de

desenvolvimento.

De acordo com o W3C [36], SOAP é “um protocolo leve para troca de informações

em um ambiente descentralizado e distribuído”. Ele define um framework abstrato para

ligação, ou binding, que permite que mensagens possam ser transferidas usando uma

variedade de protocolos. A especificação SOAP define uma ligação para o protocolo

HTTP. Já foram definidos também bindings para os protocolos HTTPS, SMTP, POP3,

IMAP, JMS e outros. Uma única aplicação pode prover múltiplas ligações a protocolos

diferentes, mostrando que a mesma funcionalidade pode ser acessada usando diferentes

Consumidor do Serviço

Provedor do Serviço

Intermediário do Serviço

(Broker)

Busca <UDDI>

Registra <UDDI>

Cliente Serviço

Descrição <WSDL>

Ligação <SOAP>

36

mecanismos de comunicação. Assim, a aplicação consumidora pode escolher o protocolo

que melhor lhe convir.

O SOAP é independente de plataforma, característica essencial em um ambiente

heterogêneo como a Internet. Como utiliza XML transmitido usando os protocolos

tradicionais da Web, pode trafegar mesmo através de firewalls, que liberam as portas de

comunicação utilizadas por estes protocolos.

Os protocolos da arquitetura Web Services foram projetados para que cada um

deles defina uma funcionalidade. Desse modo, aplicações operando em diferentes

hardwares, de várias escalas, podem usar somente aqueles protocolos que necessitam,

maximizando a aplicabilidade da arquitetura. Uma outra vantagem é que novos protocolos

podem ser introduzidos a qualquer momento, para complementar os já existentes e

estender suas funcionalidades.

A composição desses protocolos é baseada na arquitetura modular do SOAP. Ela

permite a composição de protocolos através do uso de um mecanismo de cabeçalho

flexível. A política de atualização da especificação de um protocolo é feita diretamente no

próprio cabeçalho da mensagem. Esse cabeçalho nada mais é do que um conjunto de

elementos que fazem parte do documento XML que representa uma mensagem, chamado

envelope SOAP. O seu uso facilita a inclusão de novas funcionalidades, sem mudar o

formato da mensagem.

Além de um elemento cabeçalho, chamado header, o envelope SOAP (elemento

envelope) possui também um elemento corpo, body. Assim, a estrutura do elemento XML

que representa uma mensagem SOAP possui como raiz o elemento envelope, que, por sua

vez, contém um elemento opcional, header, e outro obrigatório, body, que contém as

informações a serem enviadas ao destinatário da mensagem.

Como mencionado anteriormente, o elemento header possibilita um mecanismo

genérico para adicionar, de modo independente, diferentes funcionalidades ao protocolo

SOAP. Cada elemento filho do header é chamado de header block (ou bloco de

cabeçalho). A especificação do protocolo SOAP não define nenhum bloco de cabeçalho,

mas outras especificações, como de segurança e transações, definem cabeçalhos para

indicar informações relacionadas às suas funcionalidades. O protocolo SOAP define

37

atributos para indicar quem deve lidar com um bloco de cabeçalho e se o processamento de

um bloco de cabeçalho é opcional ou obrigatório.

Um agente de software que envia ou recebe mensagens é chamado de nó SOAP

(SOAP node). O nó que realiza a transmissão inicial de uma mensagem é chamado de

original sender. O nó final, que consome e processa a mensagem, é chamado de ultimate

receiver. Qualquer nó que processa a mensagem entre esses dois é chamado de

intermediário. O conjunto de nós através do qual uma mensagem passa, incluindo o

original sender, zero ou mais nós intermediários e seu ultimate receiver, é chamado de

caminho da mensagem (message path).

Para que partes do caminho da mensagem sejam identificadas, cada nó está

relacionado a um ou mais papéis (roles). Cada papel SOAP é uma categoria que associa

um nome URI a uma funcionalidade abstrata (caching, validação, autorização, etc.). A

especificação SOAP define dois papéis: next e ultimateReceiver. Todo nó SOAP no

caminho da mensagem é associado ao papel next. Já o ultimateReceiver é associado

somente ao nó destino.

O corpo de uma mensagem, ou seja, as suas informações, é sempre destinado ao

ultimateReceiver. Por sua vez, os cabeçalhos podem ser destinados aos nós intermediários

ou ao nó final. Com o propósito de facilitar a inclusão de novas funcionalidades, o SOAP

define três atributos do elemento header block para controlar como os nós intermediários e

o final devem processar um bloco de cabeçalho: role, relay, e mustUnderstand.

O atributo role é usado para identificar a qual nó o bloco de cabeçalho é

endereçado, por exemplo, para o ultimateReceiver. Cabeçalhos que não podem ser

ignorados possuem um atributo, chamado “mustUnderstand”, indicando que a sua inserção

é uma mudança que deve ser aceita por todos, ou seja, somente quem entender este

cabeçalho pode processar e encaminhar a mensagem. Cabeçalhos sem esse atributo ou com

seu valor igual a falso podem ser desconsiderados no processamento da mensagem. O

atributo relay indica se o nó deve encaminhar ou descartar o bloco de cabeçalho.

Cada nó deve usar esses três atributos para implementar o modelo de

processamento SOAP. Abaixo são descritos os passos utilizados por um nó ao processar

uma mensagem:

38

1. Identificar todos os blocos de cabeçalho da mensagem que são para o nó SOAP

atual, através do atributo role. A falta desse atributo significa que o bloco de

cabeçalho só pode ser processado pelo seu nó destino, ou ultimateReceiver;

2. Verificar se todos os blocos de cabeçalho obrigatórios identificados no passo

anterior podem ser processados pelo nó atual, usando o atributo mustUnderstand.

Se um bloco obrigatório não puder ser processado, a mensagem deve ser descartada

e uma mensagem de falha (Fault) deve ser gerada;

3. Processar a mensagem. Elementos opcionais podem ser ignorados;

4. Se o nó não é o destino da mensagem, todos os blocos de cabeçalho identificados

no primeiro passo que não têm o atributo relay igual a verdadeiro são removidos da

mensagem e esta é, então, retransmitida para o próximo nó no caminho da

mensagem;

5. O nó atual pode inserir novos blocos de cabeçalho na mensagem retransmitida.

Alguns desses blocos podem ser cópias dos blocos identificados no primeiro passo.

O estilo de uma mensagem SOAP pode ser de dois tipos: RPC ou document. No

primeiro estilo, o formato de dados representa uma chamada RPC e a mensagem é

encapsulada em um elemento cujo nome indica o método que está sendo chamado. Esse

elemento é composto de uma estrutura de elementos que representam os parâmetros de

entrada ou valor de retorno. Já no segundo estilo, a mensagem XML é colocada

diretamente dentro do corpo do envelope SOAP. Assim, é possível a troca de documentos

XML entre agentes, na qual a própria mensagem é o documento XML enviado ou

recebido. Nesse estilo, espera-se que tenha sido feito um acordo prévio entre remetente e

receptor sobre como interpretar a mensagem XML.

O modo de codificação de uma mensagem SOAP também pode ser de dois tipos:

literal e encoded. O uso do modo encoded significa que regras de codificação, definidas na

especificação SOAP [36], serão utilizadas para codificar a mensagem. Já o uso do modo

literal, significa que as regras de codificação da mensagem estão definidas em um esquema

XML (XML Schema).

Juntos, o estilo da mensagem e o modo de codificação definem qual representação

está presente em uma mensagem SOAP. As três principais combinações dessas

características são [38]:

39

• Codificação SOAP Remote Procedure Call (RPC/encoded): este estilo é o mais

simples de se utilizar. Ele simula o conceito de chamada remota de procedimento,

com o consumidor enviando uma mensagem com o procedimento a ser executado

juntamente com seus parâmetros. A pilha SOAP serializa os parâmetros em XML e

envia os dados para o destino usando um protocolo de transporte, como HTTP ou

SMTP. O corpo da mensagem SOAP deve possuir um elemento com o mesmo

nome do método sendo chamado, e este deve possuir elementos na mesma ordem e

com os mesmos nomes dos parâmetros desse método. O consumidor recebe a

resposta, com os resultados da chamada do método desserializados. Esse estilo de

codificação, embora seja mais simples, possui maiores problemas de escalabilidade

e desempenho, já que a pilha SOAP realiza todo o trabalho de serialização das

mensagens para o desenvolvedor, impedindo que este modifique certos aspectos

para obter um melhor desempenho.

• Codificação SOAP Remote Procedure Call Literal (RPC/literal): usa métodos RPC

para fazer as chamadas, mas a serialização e a desserialização são realizadas pela

aplicação consumidora. Nesse caso é assumido que os parâmetros enviados já são

dados em formato XML. Esse campo XML único é serializado e enviado pelo

consumidor para o host do serviço, recebendo, depois, o resultado retornado.

• Codificação SOAP document-style (document/literal): também conhecido como

codificação message-style, este estilo reflete um uso mais nativo do XML e é mais

flexível que o estilo RPC. No estilo document/literal, a pilha SOAP envia um

documento XML completo para um servidor, sem requerer um valor de resposta. A

mensagem pode conter qualquer tipo de dados XML que seja apropriado para o

serviço remoto. Por isso, o desenvolvedor deve lidar com aspectos como serializar

e desserializar os dados do corpo da mensagem SOAP e analisar sintaticamente os

documentos XML enviados e recebidos. É mais difícil de ser implementado pelo

desenvolvedor, mas, por conseqüência, diminui a sobrecarga do SOAP. Nesse

estilo, o desenvolvedor pode implementar um código que irá analisar seus

documentos de forma mais eficiente que um analisador SOAP padrão. Além disso,

as mensagens ficam menores e menos complexas, já que os dados XML no corpo

da mensagem SOAP não precisam ser envoltos em um elemento que referenciaria o

40

método em uma RPC e não são necessários atributos sobre os tipos dos dados, já

que eles já estão definidos em um XML Schema.

No princípio, a maioria dos serviços da arquitetura Web Services usava estilo RPC

e codificação encoded para troca de mensagens, especialmente, pois esse estilo se

assemelhava a tecnologias tradicionais de computação distribuída. Mas a tendência atual

tem inclinado para o uso de codificação document/literal, quer dizer, realmente serviços

baseados em troca de mensagens. O Web Services Interoperability (WS-I) Basic Profile 1.0

[39] define que a preferência deve ser dada para o uso de document/literal. A versão 1.2 do

SOAP torna opcional o suporte de regras de codificação SOAP (encoded) e convenções

RPC.

Um exemplo de uma mensagem SOAP é apresentado na Figura 2. Esta é uma

mensagem enviada pelo protocolo HTTP. As linhas um a quatro são, na verdade, o

cabeçalho HTTP. Seu documento XML possui dois elementos filhos: o cabeçalho (header)

e o corpo (body). O cabeçalho é opcional, e neste exemplo está em branco. No elemento

corpo, é mostrada a chamada a um método “translate”, de um serviço localizado em

“http://translator.example/translator”. Esse método recebe três parâmetros: o termo a ser

traduzido (text), de qual língua (from) e para qual língua (to), todos do tipo texto (string).

Figura 2 – Exemplo de mensagem SOAP enviada por HTTP.

2.3.5 WSDL

Web Service Description Language (WSDL) [33] é o modo de definição formal dos

métodos e pontos de acesso oferecidos pela interface do Web service. Ele descreve de

1 POST /axis/services/WSATranslator HTTP/1.0 2 Content-Type: text/xml; charset=“utf-8” 3 Content-Length: xxxx 4 SOAPAction: "urn:translate" 5 <SOAP:Envelope xmlns:SOAP=“http://schemas.xmlsoap.org/soap/envelope/” 6 xmlns:xsd=“http://www.w3.org/2001/XMLSchema” 7 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” 8 SOAP:encodingStyle=“http://www.w3.org/2003/05/soap-encoding” 9 xmlns:ns1=“http://translator.example/translator”> 10 <SOAP:Header> 11 <!— Cabeçalho —> 12 </SOAP:Header> 13 <SOAP:Body> 14 <ns1:translate> 15 <ns1:text xsi:type=“xsd:string”>hello</ns1:text> 16 <ns1:from xsi:type=“xsd:string”>en</ns1:from> 17 <ns1:to xsi:type=“xsd:string”>pt</ns1:to> 18 </ns1:translate> 19 </SOAP:Body> 20 </SOAP:Envelope>

41

modo não ambíguo quais funcionalidades um serviço oferece, como deve ser o conteúdo

das mensagens de requisição e resposta, como é possível acessá- lo e onde encontrá- lo.

A descrição WSDL completa de um serviço possui três informações: uma descrição

dos serviços disponíveis, também chamada de interface abstrata; detalhes dependentes de

protocolo que devem ser seguidos para acessar o serviço e o protocolo de comunicação

usado; e a localização do serviço. A separação desses aspectos ajuda a linguagem WSDL a

representar funcionalidades comuns entre serviços implementados de formas diferentes.

Assim, essas três partes principais do WSDL podem ser separadas em diferentes

documentos, para haver maior flexibilidade e reusabilidade.

A notação que um arquivo WSDL usa é a mesma utilizada pelos outros protocolos

da arquitetura Web Services, ou seja, baseada em esquemas XML (XML Schemas). Esse é

um modo neutro e baseado em padrões, o que o torna muito interessante para descrever

interfaces de serviços que podem ser acessadas a partir de uma variedade de plataformas e

linguagens de programação.

Um arquivo WSDL pode especificar os elementos básicos necessários para escrever

um programa que interaja com um serviço Web. Por isso, já existem várias ferramentas

disponíveis que lêem este arquivo e geram o código requerido para produzir mensagens

sintaticamente corretas para acessar um serviço Web.

A primeira parte do documento WSDL descreve o que o serviço faz, ou seja, o seu

tipo de serviço (service type). Um ou mais provedores de serviço podem implementar o

mesmo tipo de serviço. Essa interface abstrata define uma interface lógica que consiste de

um conjunto de operações que um serviço realiza. Para cada operação, são definidos: as

mensagens de entrada e saída, o formato de cada mensagem e o tipo de dados de cada

elemento das mensagens.

A segunda parte define a ligação, ou binding, da interface abstrata a um conjunto

concreto de protocolos. O binding indica o estilo de codificação da mensagem, especifica

se um esquema XML é necessário, qual protocolo XML deve ser usado para construir o

envelope, quais cabeçalhos devem ser incluídos na mensagem e qual protocolo de

transferência deve ser usado. Essa parte inclui ou importa a primeira parte do documento

WSDL.

42

A terceira parte descreve a implementação de um serviço, que é uma coleção de um

ou mais ports relacionados. Cada port implementa uma ligação (binding) específica de

uma interface abstrata, indicando o ponto de acesso a um endpoint de um serviço. Um

provedor de serviço pode oferecer vários pontos de acesso para o mesmo serviço, cada um

implementando uma ligação diferente. Essa parte do documento WSDL inclui ou importa a

segunda parte e pode ser publicada pelo provedor de serviço para torná- lo disponível ao

acesso de clientes.

Figura 3 – Exemplo de arquivo WSDL, a interface abstrata e os detalhes de protocolo.

A Figura 3 apresenta um exemplo de documento WSDL. Esta é a descrição do

serviço que recebeu a mensagem SOAP da Figura 1. A primeira parte do documento

descreve as mensagens enviadas e recebidas pelo serviço. Existem duas mensagens

descritas, “translateRequest”, que possui três elementos (o texto, a língua do texto e a

1 <definitions name="Translator" targetNamespace="http://translator.example/translator" 2 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 3 xmlns:ns="http://translator.example/translator" 4 xmlns:xs="http://www.w3.org/2001/XMLSchema" 5 xmlns="http://schemas.xmlsoap.org/wsdl/"> 6 <message name="translateRequest"> 7 <part name="text" type="xs:string" /> 8 <part name="from" type="xs:string" /> 9 <part name="to" type="xs:string" /> 10 </message> 11 <message name="translateResponse"> Primeira 12 <part name="text" type="xs:string" /> Parte 13 </message> 14 <portType name="TranslatorPortType"> 15 <operation name="translate"> 16 <input message="ns:translateRequest" /> 17 <output message="ns:translateResponse" /> 18 </operation> 19 </portType> 20 <binding name="TranslatorSoapBinding" type="ns:TranslatorPortType"> 21 <soap:binding style="rpc" 22 transport="http://schemas.xmlsoap.org/soap/http"/> 23 <operation name="translate"> 24 <soap:operation Segunda Parte 25 soapAction="urn:translate" style="rpc" /> 26 <input> 27 <soap:body use="encoded" 28 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 29 namespace="http://translator.example/translator"/> 30 </input> 31 <output> 32 <soap:body use="encoded" 33 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 34 namespace="http://translator.example/translator"/> 35 </output> 36 </operation> 37 </binding> 38 <service name="Translator"> Terceira Parte 39 <documentation>Este serviço permite...</documentation> 40 <port name="TranslatorPort" binding="ns:TranslatorSoapBinding"> 41 <soap:address location=" http://translator.example/translator"/> 42 </port> 43 </service> 44 </definitions>

43

língua para a qual ele vai ser traduzido) e “translateResponse” que possui somente o

elemento que representa o texto traduzido. Ainda na primeira parte, são descritos os

serviços oferecidos por este portType, e quais mensagens esses serviços esperam trocar.

Neste exemplo, somente a operação “translate” está disponível. Pode-se ver, nas linhas 11

a 13, que a resposta esperada dessa operação é uma mensagem que contém um elemento

do tipo string, denominado “text”.

Na segunda parte, pode-se ver a descrição das codificações (RPC) esperadas de

cada mensagens da operação “translate”. Ali está definido que o estilo das mensagens do

serviço é RPC e o estilo de codificação é aquele especificado pelo SOAP (encoded).

Finalmente, na terceira parte, é informado o endereço de localização do serviço. Essa parte

pode conter também um texto de documentação.

2.3.6 UDDI

O descobrimento de serviços é feito utilizando a especificação Universal

Description, Discovery and Integration (UDDI) [34]. O UDDI fornece um diretório

centralizado (público ou privado) de Web services disponíveis através do qual os usuários

podem encontrar os serviços desejados. Embora tenha sido originalmente concebido para

ser um diretório global de todos os serviços disponíveis, atualmente diretórios privados são

usados para integrar processos internos, especialmente em empresas.

A especificação UDDI define um Web service de registro para serviços, acessado

através de mensagens SOAP, que gerencia informações sobre tipos de serviços,

implementações de serviços e seus provedores. Ela possui mecanismos para categorizar,

descobrir e realizar a ligação a serviços. Provedores podem usar o UDDI para anunciar os

serviços que oferecem. Já os consumidores usam o UDDI para encontrar serviços que

necessitam e obter os metadados necessários para consumi- los.

A estrutura dos dados UDDI possui quatro construções: businessEntity,

businessService, bindingTemplate e tModel.

A construção businessEntity fornece informações de cada serviço, como

identificadores, nome, descrição e detalhes de contato do provedor do serviço. Essas

informações são conhecidas como white pages. Cada businessEntity inclui um ou mais

elementos businessService, que representam os tipos de serviços oferecidos, categoria

conhecida como yellow pages.

44

Um tipo de serviço, definido pela construção tModel, define um serviço abstrato.

Várias empresas podem oferecer o mesmo tipo de serviço, todas com a mesma interface. O

tModel fornece um ponteiro para o documento WSDL que descreve a interface abstrata do

tipo de serviço, ou seja, a primeira parte desse documento.

Um provedor de serviço registra suas informações e todos os serviços que oferece.

Para cada serviço, ele fornece as informações de binding necessárias para que um

consumidor o acesse. A construção bindingTemplate possui informações técnicas dos

serviços e também é conhecida como a categoria green pages. Ela provê um apontador

para o documento WSDL que descreve a ligação e o ponto de acesso à implementação do

serviço.

Na busca por um serviço, o consumidor pesquisa no registro UDDI dentro dessas

três categorias: white, yellow e green pages. Ele pode acessar a descrição WSDL de um

tipo de serviço através do elemento tModel. Então, o consumidor pode compilar esse

arquivo para gerar uma interface de acesso abstrata, que poderia ser usada para acessar

diferentes implementações desse tipo de serviço. Do elemento bindingTemplate de um

serviço específico, o consumidor pode obter, a partir do arquivo WSDL, o ponto de acesso

e a sua descrição de binding.

Como o UDDI é um Web service, uma aplicação pode fazer a ligação a um serviço

de maneira dinâmica durante a sua execução. Usando a descrição de interface do serviço

durante a compilação, o desenvolvedor pode gerar uma interface cliente abstrata que pode

ser usada com qualquer implementação de um tipo de serviço. Em tempo de execução

(runtime), a aplicação pode descobrir um serviço, recuperar seu WSDL e compilar

dinamicamente a ligação ao serviço concreto escolhido.

Um exemplo de descrição UDDI para um serviço Web é apresentado na Figura 4.

Considere que exista uma especificação padrão para o tipo de serviço “translate” e que ele

é registrado no UDDI usando uma construção tModel. Cada provedor registra suas

informações e implementação do serviço usando as construções businessEntity,

businessService e bindingTemplate. Um dos provedores desse serviço é a empresa

Translator. No exemplo, este é o único serviço que a empresa disponibiliza, pois é o único

elemento dentro de businessServices. E para esse serviço ela possui também somente um

modo de ligação e acesso (linhas 20 a 31).

45

Figura 4 – Exemplo de estrutura UDDI simplificada.

O endereço URL onde está o documento WSDL que descreve a interface do serviço

fica em uma entrada tModel no registro UDDI. O endereço endpoint do Web service está

especificado na linha 24 do exemplo, no elemento accessPoint.

É importante salientar que o uso de UDDI não é obrigatório. Se um consumidor já

conhecer informações sobre o serviço que quer acessar, não precisa pesquisá-lo pelo

UDDI. Nesse caso, ele pode usar um modo mais direto, como Web Services Metadata

Exchange [40]. Essa especificação permite questionar um serviço Web sobre seus

metadados, para assim descobrir sobre o serviço disponível e como fazer para acessá- lo.

Ele pode, ainda, acessar diretamente o endereço do serviço.

2.4 WEB SERVICES ADDRESSING

Apesar do seu foco na neutralidade, atualmente um grande número de serviços Web

implementados dependem do protocolo HTTP para realizar o transporte de mensagens. As

infra-estruturas SOAP ainda não proviam, até recentemente, um mecanismo para

referenciar e enviar mensagens a endpoints sem a ajuda de um protocolo de transporte.

1 <businessEntity businessKey=“ba744ed0-3aaf-11d5-80dc-002035229c64”> 2 <name>Translator</name> 3 <description>The Babel fish is probably the oddest thing in the 4 Universe...</description> 5 <contacts> 6 <contact useType=“Geral”> 7 <personName>Babelfish</personName> 8 <phone>00 55 42 42 42</phone> 9 <email>[email protected]</email> 10 <address> 11 <addressLine>Rua 10, 120</addressLine> 12 <addressLine>Florianópolis, SC</addressLine> 13 </address> 14 </contact> 15 </contacts> 16 <businessServices> 17 <businessService serviceKey="d5921160-3e16-11d5-98bf-002035229c64" 18 businessKey="ba744ed0-3aaf-11d5-80dc-002035229c64"> 19 <name>Translate</name> 20 <bindingTemplates> 21 <bindingTemplate bindingKey="d594a970-3e16-11d5-98bf-002035229c64" 22 serviceKey="d5921160-3e16-11d5-98bf-002035229c64"> 23 <description>SOAP binding to translate a text</description> 24 <accessPoint URLType="http"> 25 http://translator.example/translator</accessPoint> 26 <tModelInstanceDetails> 27 <tModelInstanceInfo 28 tModelKey="uuid:0e727db0-3e14-11d5-98bf-002035229c64" /> 29 </tModelInstanceDetails> 30 </bindingTemplate> 31 </bindingTemplates> 32 </businessService> 33 </businessServices> 34 </businessEntity>

46

Por isso, foi necessário criar extensões ao HTTP. O URI alvo de uma mensagem de

requisição HTTP é usado para representar o endereço de um endpoint. Quando a

mensagem chega ao destino para ser processada, a infra-estrutura SOAP utiliza uma

extensão do cabeçalho HTTP, chamada SOAPAction, para determinar o que deverá

acontecer em resposta a esta mensagem. Isso pode ser visto no exemplo de mensagem

SOAP apresentado anteriormente (Figura 2). O procedimento mais comum é usar essa

informação para despachar a mensagem para um método que executa o serviço requisitado.

Se houver resposta, ela será enviada para o endereço de retorno especificado pela camada

de transporte.

Essa abordagem pode causar inúmeros problemas, pois a informação sobre fonte e

destino não faz parte da mensagem. Assim, ela pode ser perdida se uma conexão de

transporte é terminada ou se a mensagem é re-encaminhada por um intermediário, como

um firewall. Por exemplo, se uma conexão HTTP falha ou expira antes da resposta ter sido

completada, não se pode reenviar a mensagem já que as informações de endereçamento

foram perdidas com a conexão.

Com o surgimento de aplicações mais sofisticadas, notou-se a importância do uso

de diferentes protocolos de transporte e que, para isso, era necessário especificar

informações de transporte de modo neutro nas próprias mensagens SOAP. Além disso,

quando se quer que uma mensagem seja especificada diretamente a um elemento ou

recurso dentro de um serviço, o simples uso da URL para indicar um endereço de destino

não é suficiente.

Para solucionar esses problemas foi criada a especificação WS-Addressing (WS-A)

[41], que criou mecanismos para referência e endereçamento de serviços Web. Ela fornece

uma abordagem interoperável e independente de transporte para identificar uma

mensagem, bem como uma abordagem mais detalhada para identificar um endpoint de um

serviço. A WS-Addressing é crítica para outras extensões à arquitetura Web Services, pois

a maioria delas depende de funções de endereçamento.

A WS-Addressing provê melhorias como: especificar mais detalhadamente as

informações de endereçamento; tornar as mensagens independentes de transporte,

permitindo que elas sejam enviadas através de redes que incluem processamento nos nós,

em intermediários como gerenciadores de endpoint, firewalls e gateways; permitir que um

47

remetente indique um outro endereço, que não o dele, para onde uma resposta deve ser

enviada, de maneira independente de transporte; e outras.

As principais contribuições dessa especificação são: definição do modo como

cabeçalhos de mensagem direcionam as mensagens para um serviço ou um agente; formato

XML para troca de referências de endpoint (endpoint references); mecanismos para

direcionar respostas ou falhas para um local específico; e relacionamento entre mensagens.

A WS-Addressing criou construções chamadas endpoint references (EPR), que são

referências a endpoints de serviços com maior nível de detalhe, se comparado a um

simples URI. Essa construção permite que outras informações, como identificador de

mensagem, informações de sessão, ou mesmo informações específicas da aplicação, sejam

adicionadas ao endereço URI, para, assim, melhor encaminhar a mensagem.

Esse protocolo permite realizar o co-relacionamento entre requisições e respostas,

aumentando a confiabilidade da comunicação e também a escalabilidade do servidor, já

que o destino final da mensagem pode ser negociado. Permite também a implementação de

diferentes padrões de troca de mensagens (MEPs) como publicação e assinatura e

notificação de eventos. De acordo com o W3C [10], um MEP é um template que descreve

um padrão genérico para a troca de mensagens entre agentes (implementações de serviços).

A definição de um MEP descreve o ciclo de vida e as relações temporais e causais entre

mensagens que uma troca de mensagens deve ter para estar em conformidade com o

padrão. No padrão requisição-resposta, está implícito que o endereço de retorno é o

endereço de quem enviou a mensagem. Mas em padrões como assinatura e notificação de

eventos, é necessário especificar o endereço para resposta, já que nesses casos a resposta

não será feita na mesma conexão de transporte na qual foi enviada a requisição.

Outra vantagem de se ter informações de endereçamento juntamente com a

mensagem é que isso facilita o uso de filas de espera. Ao invés de se utilizar uma fila para

cada endpoint de serviço, usa-se uma única fila para todas as mensagens. Elas podem ser

encaminhadas com base nos seus cabeçalhos WS-Addressing. Além disso, as mensagens

podem ser salvas para posterior envio, com o armazenamento de todas as mensagens, em

um banco de dados, por exemplo, sem perdas de informações essenciais de endereçamento.

48

2.4.1 Histórico

Em agosto de 2004 foi submetida ao W3C a especificação WS-Addressing, como

uma submissão de membro (member submission) [41]. Produzida primeiramente como

uma especificação privada pelas empresas BEA, IBM e Microsoft, a WS-Addressing foi

publicada em março de 2003 e revisada em maio deste mesmo ano e novamente em março

de 2004. Atualmente, as empresas SAP AG e Sun Microsystems se juntaram a este projeto.

Essa especificação referencia à WS-Policy e é referenciada por um número crescente de

especificações Web Services, como:

• Web Services Eventing (WS-Eventing);

• Web Services Reliable Messaging Protocol (WS-ReliableMessaging);

• Web Services Business Process Execution Language (BPEL4WS);

• Especificações do Web Services Resource Framework, em especial WS-

RenewableReferences.

Em outubro de 2004 foi criado, pelo W3C, o grupo de trabalho Web Services

Addressing [42]. Esse grupo faz parte do Web Services Activity e seu propósito é produzir

uma W3C Recommendation para essa especificação, através do refinamento do documento

enviado em agosto deste mesmo ano. Essa ação demonstra a importância desse

componente na arquitetura Web Services. O grupo de trabalho deve padronizar os

mecanismos de referência e endereçamento de Web services, incluindo:

• Os meios pelos quais cabeçalhos de mensagens são usados para direcionar

mensagens para um serviço Web ou um agente;

• Propriedades abstratas de mensagens, como:

o Um identificador de mensagem;

o Um URI para o endereço de destino ;

o Um URI para designar a ação a ser executada no destino;

o Correlação com outra(s) mensagem(ns);

o A natureza desses relacionamentos.

• Um XML Infoset que comunicará a informação necessária para gerar os cabeçalhos

apropriados para direcionar mensagens para um serviço ou agente, incluindo:

49

o Um URI designando o endereço destino;

o Cabeçalhos de mensagem específicos sobre serviço;

o Cabeçalhos de mensagem específicos sobre interação;

o Definições WSDL relevantes para este serviço;

o Metadados adicionais, conforme necessário.

• Propriedades abstratas para identificar destinos subseqüentes na troca de

mensagens, incluindo:

o O destino de resposta;

o O destino em caso de falhas;

Atualmente, o grupo de trabalho já publicou diversos rascunhos da especificação

para chegar à recomendação final, que está prevista para ser terminada em janeiro de 2006.

2.4.2 Detalhes da Especificação

Na especificação WS-Addressing são definidas duas construções que transportam

informações tipicamente fornecidas por protocolos de transporte. Elas normalizam essas

informações em um formato que pode ser processado independentemente do protocolo de

transporte ou aplicação. Essas duas construções são "endpoint references" e "message

information headers".

Uma endpoint reference é um mecanismo leve e extensível para referenciar e

descrever dinamicamente endpoints e instâncias de serviços. Ela pode ser considerada um

URI com extensões, quer dizer, um URI adicionado de informações necessárias para

identificar um endpoint de um serviço Web. Uma endpoint reference possui um elemento

address, que é o próprio URI, e mais outros elementos metadados para as informações

adicionais. Por exemplo, existe um elemento Policy que pode ser usado para incluir

informações de política da mensagem.

Um endpoint é uma entidade, processador ou recurso, para onde mensagens podem

ser direcionadas, ou seja, é o ponto de acesso a um serviço. Uma endpoint reference

descreve um lugar na rede que pode receber mensagens SOAP. Na prática, o modelo de

endereçamento proposto pelo WS-Addressing é baseado inteiramente na presença de

50

alguns tipos específicos de cabeçalhos SOAP. As endpoint references são somente um

modo simples de referenciar a esse conjunto de cabeçalhos como uma entidade única.

Uma endpoint reference pode ser composta de seis elementos: um endereço base

representado por um URI (address), um elemento portType do endpoint, como definido no

documento WSDL (selected port type), uma referência ao elemento que descreve o serviço

no documento WSDL (service-port), informações que se referem a políticas do serviço

(policy) e um conjunto opcional de propriedades (endpoint properties) e parâmetros

(endpoint parameters) para o endpoint.

A especificação WS-Policy é usada pela WS-Addressing. Uma endpoint reference

pode incluir zero ou mais propriedades abstratas de elementos policy, que são políticas que

descrevem o comportamento, requisitos e capacidade de um endpoint. Essas políticas

podem ser incluídas na mensagem para facilitar o processamento pela aplicação ou porque

elas foram geradas dinamicamente.

As propriedades e parâmetros de referência são elementos XML que, normalmente,

serão processados somente no nó final (ultimate receiver). Eles ajudam a assegurar que as

informações necessárias para o encaminhamento, a indexação ou outras atividades de

processamento que um servidor pode fazer, estão incluídas na mensagem. Intermediários,

como firewalls ou gateways, podem usar algumas propriedades ou parâmetros para

roteamento e/ou processamento da mensagem.

O uso de propriedades e parâmetros de referência é normalmente transparente ao

consumidor. A própria infra-estrutura de implementação dos protocolos Web Services dá

suporte à inserção e processamento dos elementos WS-Addressing, incluindo propriedades

e parâmetros de referência, nos cabeçalhos das mensagens SOAP.

De acordo com a especificação WS-Addressing enviada ao W3C, a diferença entre

propriedades e parâmetros de referência se dá no modo como eles se relacionam com os

metadados do serviço. Uma propriedade de referência e um endereço base identificam um

certo serviço disponível, ou seja, eles determinam a identidade do serviço. Por exemplo, se

duas endpoint references possuem o mesmo endereço address e propriedades de referência

diferentes, então elas representam dois nomes lógicos (duas identidades) para o mesmo

endpoint. Já os parâmetros de referência são usados para endereçar recursos específicos,

que são gerenciados por esse serviço. Eles dão a habilidade de enviar “parâmetros” à EPR,

51

sem mudar a identidade do serviço. Entretanto, é importante salientar que essas definições

estão sendo amplamente debatidas no Grupo de Trabalho da especificação no W3C.

Existem muitos usos para as propriedades de referência. Em Cabrera et al [37], dois

exemplos simples são mostrados: classes de serviços e identificadores de entidade. No

primeiro exemplo, as propriedades são usadas para diferenciar entre um serviço para

clientes padrão e outro para clientes “ouro”, que tem melhor qualidade de serviço (QoS),

formando logicamente dois endpoints diferentes. Propriedades como essa são configuradas

somente uma vez em uma sessão e reusadas durante a interação. No segundo exemplo, as

propriedades são usadas como um mecanismo para identificar um cliente de maneira

privada para o sistema de origem. Uma combinação desses dois exemplos pode permitir

despachar eficientemente uma mensagem para o conjunto apropriado de servidores. Esses

exemplos também mostram como dados que se referem a instâncias de serviços e usuários

podem ser representados pelas propriedades de referência.

Em um exemplo de uso de parâmetros de referência, a interação entre consumidor e

serviço começa com o consumidor enviando uma mensagem para o serviço – por exemplo,

uma mensagem para autenticação. O serviço realiza o processamento da mensagem e cria

uma sessão, enviando a resposta ao cliente juntamente com um reference parameter que

informa o seu identificador de sessão. Assim, esse cliente não precisa saber que, a cada

mensagem enviada ao serviço, ele envia também a sua identificação de sessão. Só é

necessário que a aplicação cliente coloque todos os reference parameters e properties que

chegam a ela no cabeçalho das mensagens enviadas ao serviço. Assim, este pode ter

disponíveis informações sobre a sessão do cliente que o acessa.

Essa mesma abordagem pode ser usada, com propriedades de referência, para

despachar mensagens vindas de um cliente. Por exemplo, o cliente envia sua primeira

mensagem utilizando a endpoint reference referente ao despachante do serviço. Quando a

conversa é estabelecida, o despachante determina um dos servidores que implementam

réplicas do serviço para responder ao cliente. Ao receber a resposta do servidor, o

despachante a envia ao cliente, mas antes coloca no seu cabeçalho uma reference property

que provê uma identificação única para a máquina escolhida para responder às mensagens

do cliente. Assim, o despachante enviará as próximas mensagens recebidas desse cliente ao

servidor apropriado, sem realizar a seleção do servidor novamente.

52

A segunda construção criada pela especificação WS-Addressing é o cabeçalho de

informações da mensagem (message information header). Esse cabeçalho adiciona

propriedades abstratas à mensagem, que permitem o endereçamento a endpoints

envolvidos em uma interação.

O encaminhamento das mensagens é baseado em duas propriedades obrigatórias:

destination e action, que identificam a localização do destino de processamento e intenção

da mensagem.

Os cabeçalhos de informações de mensagem atualmente definidos são:

• To: é a URL alvo do serviço Web. Normalmente, ela é igual a URL usada na

requisição HTTP, mas isso não é obrigatório. Representa a propriedade destination.

• From: é a endpoint reference do remetente da mensagem. Para identificar o

endpoint a quem se deve enviar uma resposta, deve-se usar o cabeçalho ReplyTo. O

From é normalmente usado para mensagens ack em uma troca confiável (reliable)

de mensagens.

• ReplyTo: é a endpoint reference a quem se deve enviar a resposta.

• FaultTo: se houver uma falha, esta deve ser enviada à endpoint reference indicada

neste cabeçalho.

• MessageID: é um URI que identifica unicamente uma mensagem.

• Action: é a ação que deve ser executada quando o serviço recebe a mensagem.

Possui a mesma finalidade do cabeçalho HTTP SOAPAction.

• RelatesTo: importante para troca de mensagens assíncronas, é normalmente usado

em mensagens de resposta para indicar a qual mensagem esta está relacionada. Seu

valor é um MessageID. Por exemplo:

<wsa:RelatesTo RelationshipType="wsa:Response">uuid:098765</wsa:RelatesTo>

A WS-Addressing é definida de acordo com W3C XML Information Set e tem

conformidade com o modelo de processamento SOAP 1.2. O uso de SOAP 1.2 não é

obrigatório. Ela foi projetada para poder trabalhar com serviços descritos com WSDL 1.1.

A seguir serão descritos os relacionamentos entre a especificação WS-Addressing e as

especificações SOAP e WSDL.

53

2.4.3 WS-Addressing e SOAP

Para realizar seus objetivos, a especificação WS-Addressing define três conjuntos

de blocos de cabeçalho SOAP. O bloco de cabeçalho action é usado para indicar o

processamento esperado de uma mensagem. Esse bloco contém um único URI que é

normalmente usado pelo nó destino para encaminhar a mensagem para processamento. Os

blocos messageID e relatesTo são usados para identificar e co-relacionar mensagens. Os

blocos to, from, replyTo e faultTo são usados para identificar os agentes que devem

processar a mensagem e suas possíveis respostas.

Os cabeçalhos replyTo, faultTo e from são representados pela estrutura endpoint

reference, que, como já foi dito, contém as informações necessárias para endereçar

corretamente uma mensagem SOAP a um endpoint de serviço. Essa estrutura possui três

informações importantes: um endereço base, reference properties (propriedades de

referência) e reference parameters (parâmetros de referência). O endereço base é um URI

usado para identificar um endpoint e aparece no bloco de cabeçalho to de cada mensagem

SOAP destinada aquele endpoint. Reference properties e reference parameters são

coleções de elementos XML usadas para complementar o endereço base, provendo

informações adicionais de roteamento ou processamento.

Na Figuras 5 é apresentado um exemplo de uma endpoint reference para um

endpoint disponível no endereço base apresentado no elemento address e com um

parâmetro de referência chamado “idSessao”.

Figura 5 – Exemplo de endpoint reference com um parâmetro de referência .

Na Figura 6, é mostrado como a endpoint reference apresentada na figura anterior

seria representada em um cabeçalho de uma mensagem SOAP. Nota-se que os parâmetros

de referência são representados diretamente como cabeçalhos SOAP. A mesma abordagem

seria tomada se também houvesse propriedades de referência na EPR.

1 <wsa:EndpointReference xmlns:wsa="..." xmlns:ns="..."> 2 <wsa:Address>http://translator.example/translator</wsa:Address> 3 <wsa:ReferenceParameters> 4 <ns:idSessao>1234ABC</ns:idSessao> 5 </wsa:ReferenceParameters> 6 </wsa:EndpointReference>

54

Figura 6 – Exemplo de endpoint reference em uma mensagem SOAP.

Quando envia uma mensagem, é esperado do receptor usar uma das construções

from, replyTo ou faultTo como o destino (destination) para a resposta ou envio de falha:

• From: identifica o remetente. Na falta do replyTo ou faultTo, esse é o destino

padrão para resposta ou envio de falha;

• ReplyTo: se presente, o provedor do serviço deve usar este destino para enviar a

resposta;

• FaultTo: se presente, é usado para enviar uma falha quando esta é gerada.

Na Figura 7 pode-se ver um exemplo de mensagem SOAP usando os cabeçalhos de

informação de mensagem da especificação WS-Addressing. Essa mensagem tem a mesma

semântica da mensagem mostrada na Figura 2. Mas nesse exemplo não é necessário usar o

cabeçalho HTTP para informar o destino e a ação da mensagem. Essas informações estão

especificadas nos elementos das linhas 15 a 17. Também se pode ver o endereço do

consumidor do serviço (from), o endereço para onde a resposta deve ser enviada (replyTo)

e o endereço para onde a mensagem de falha deve ser enviada, caso ocorra (faultoTo). O

corpo da mensagem permanece o mesmo do exemplo anterior. Isso mostra a facilidade que

o cabeçalho SOAP traz para a adição de novas funcionalidades ao modelo de mensagens

SOAP.

1 <SOAP:Envelope xmlns:SOAP="http://www.w3.org/2003/05/soap-envelope" 2 lns:wsa="..." xmlns:ns1="..."> 3 <SOAP:Header> 4 ... 5 <wsa:To>http://translator.example/translator</wsa:To> 6 <ns1:idSessao>1234ABC</ns1:idSessao> 7 ... 8 </SOAP:Header> 9 <SOAP:Body> 10 ... 11 </SOAP:Body> 12 </SOAP:Envelope>

55

Figura 7 – Mensagem SOAP utilizando WS-Addressing.

2.4.4 WS-Addressing e WSDL

As endpoint references estendem logicamente, mas não substituem, o modelo de

descrição WSDL (como os elementos portTypes, bindings, etc.). Elas são um complemento

ao elemento service do WSDL 1.1, e por isso os dois devem ser usados em conjunto.

Porém, endpoint references podem ser usadas no lugar do elemento service quando, por

exemplo, instâncias específicas de um serviço com estado precisam ser identificadas,

quando detalhes de configuração específicos a uma instância precisam ser transmitidos, ou

quando uma descrição leve e autocontida de um endpoint de serviço precisa ser

comunicada. Isso pode ser necessário quando detalhes da configuração do endpoint já são

compartilhados pelas partes que se comunicam, mas informações específicas sobre a

política utilizada precisam ser adicionadas ou atualizadas, tipicamente como resultado de

um processo de configuração dinâmico.

As endpoint references podem fazer um link para elementos service da

especificação WSDL/1.1, e assim, oferecer suporte a um cenário no qual as informações

WSDL não são conhecidas pela entidade processadora da mensagem, como na troca

dinâmica de mensagens ou devido à capacidade limitada da entidade processadora.

A associação entre uma mensagem descrita no WSDL e o elemento action do WS-

Addressing pode ser feita de duas maneiras: explícita ou implicitamente. No modo

1 <SOAP:Envelope xmlns:SOAP="http://www.w3.org/2003/05/soap-envelope" 2 xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 3 xmlns:ns1="http://translator.example/translator"> 4 <SOAP:Header> 5 <wsa:MessageID>uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff</wsa:MessageID> 6 <wsa:From> 7 <wsa:Address>http://client.example/cliente1</wsa:Address> 8 </wsa:From> 9 <wsa:ReplyTo> 10 <wsa:Address>http://client.example/cliente1</wsa:Address> 11 </wsa:ReplyTo> 12 <wsa:FaultTo> 13 <wsa:Address>http://client.example/cliente1</wsa:Address> 14 </wsa:FaultTo> 15 <wsa:To 16 SOAP:mustUnderstand="1">http://translator.example/translator</wsa:To> 17 <wsa:Action>urn:translate</wsa:Action> 18 </SOAP:Header> 19 <SOAP:Body> 20 <ns1:translate> 21 <ns1:text xsi:type=“xsd:string”>hello</ns1:text> 22 <ns1:to xsi:type=“xsd:string”>pt</ns1:to> 23 <ns1:from xsi:type=“xsd:string”>en</ns1:from> 24 </ns1:translate> 25 </SOAP:Body> 26 </SOAP:Envelope>

56

explícito, o atributo action pode ser adicionado aos elementos input, output ou fault do

WSDL.

Figura 8 – Atributo WS-Addressing em um documento WSDL.

No modo implícito, quando o atributo action não é utilizado, usa-se a seguinte regra

para criar o valor padrão do action: [target namespace]/[port type name]/[input|output name].

No exemplo da Figura 8, o valor de action para a mensagem input seria:

http://translator.example/translator/TranslatorPortType/translate. Se o atributo name do

elemento input ou output não estivesse presente, seria usado o atributo name do elemento

operation concatenado ao texto “Request” e “Response”, para mensagens de requisição e

resposta, respectivamente. Essa regra não é aplicada para as mensagens de falha, nesse

caso é usada sempre a ação padrão: http://www.w3.org/2004/12/addressing/fault.

2.5 PLATAFORMAS DE DESENVOLVIMENTO PARA WEB SERVICES

Diferente de outros sistemas SOA, a arquitetura Web Services define somente

protocolos de comunicação, e não o modo como as aplicações devem interagir com eles,

que deve ser especificado pela linguagem ou plataforma utilizada.

Os Web services podem ser escritos em praticamente qualquer linguagem (Java,

PHP, Python, VB.Net, C, C++, C#, etc) e ser executados em qualquer servidor que aceite a

linguagem na qual foi implementado. Uma linguagem que pode analisar gramaticalmente e

processar XML pode, no mínimo, construir, empacotar e trocar mensagens diretamente em

XML. Como essa maneira não é nada producente, várias empresas produziram um

conjunto de mecanismos de invocação padrão.

As plataformas Web Services provêem um meio de construir, implementar e

implantar serviços Web. Com o seu uso, o desenvolvedor pode focar na criação de código

para solucionar seu problema, sem se preocupar com a construção de mensagens SOAP ou

1 <definitions targetNamespace="http://translator.example/translator"...> 2 <portType name="TranslatorPortType"> 3 <operation name="translate"> 4 <input action="http://translator.example/translator/translate" 5 message="ns:translateRequest" name="translate" /> 6 <output action="http://translator.example/translator/translateResponse" 7 message="ns:translateResponse" name="translateResponse" /> 8 </operation> 9 ... 10 </portType> ...

57

com a análise sintática dessas mensagens. Uma plataforma Web Service geralmente é

composta de ferramentas de desenvolvimento, um servidor de aplicação e um conjunto de

serviços de gerenciamento.

Ferramentas de desenvolvimento são usadas para criar Web services, para gerar

descrições WSDL e proxies de clientes que podem ser usados para enviar mensagens ao

serviço. Elas podem também prover ferramentas para facilitar o registro ou descobrimento

de serviços em um registro UDDI.

Um servidor de aplicação processa mensagens SOAP e provê um container de

execução (runtime container) de serviços Web. O servidor normalmente é executado

dentro de um servidor Web ou de aplicação, e fica à espera de requisições SOAP. Para

cada requisição, o servidor processa a mensagem, traduz o XML em dados da linguagem

nativa da plataforma e chama o serviço. Quando o serviço termina sua execução, o servidor

traduz os valores de retorno em um formato XML, empacota o resultado em um envelope

SOAP e o envia de volta à aplicação que o requisitou.

Ferramentas de gerenciamento fornecem mecanismos para implantar, remover,

iniciar, terminar, configurar e administrar os serviços Web. Outros serviços que podem

existir são: registro UDDI privado, um repositório WSDL e uma ferramenta para

monitoramento de execução.

Na escolha de uma plataforma Web Services, entre os principais fatores [43] que se

deve considerar estão: a(s) linguagem(s) e a(s) plataforma(s) que se pode utilizar, o

servidor Web ou de aplicação usado para execução, o suporte para os protocolos de

transporte, a interoperabilidade, a portabilidade, o desempenho, a escalabilidade, a

segurança, a gerência de serviços, e claro, os custos.

Entre as plataformas e kits de desenvolvimento de Serviços Web, encontram-se os

seguintes exemplos: Axis, projeto Apache livre e de código aberto; .Net, da Microsoft;

WebSphere Application Server, da IBM; o servidor de aplicação WebLogic da BEA; entre

outros.

2.6 DESEMPENHO DE WEB SERVICES

O desempenho e a disponibilidade dos serviços Web devem ser vistos cada vez

mais com maior importância. A empresa de pesquisas ZapThink afirma que até 2006 é

58

esperado que mais de 25% do tráfego nas redes seja de dados XML [44]. Por isso, é

necessária a busca de soluções para melhorar o desempenho de serviços Web.

Especialmente tendo em vista que, como foram criados para serem consumidos por outras

aplicações e serviços, a composição e a interdependência entre esses serviços serão

grandes. Uma falha ou mau desempenho de um dos serviços prejudica toda a aplicação

composta.

Apesar de ser um dos fatores de sucesso da arquitetura Web Services, o uso de

XML tem uma desvantagem: por ser baseado em texto, seu processamento é lento. Por

isso, é necessário um cuidado especial com o desempenho de sistemas que utilizam Web

services. Esse fator está entre os que mais influenciam no desempenho de serviços Web,

principalmente a sua análise sintática e transformação das mensagens SOAP [45].

Sistemas CORBA, DCOM e RMI usam codificação binária para os parâmetros e

valores de retorno das mensagens trocadas. Além disso, é assumido que tanto o

consumidor quanto o provedor têm total conhecimento do contexto da mensagem e, por

isso, não precisa receber nenhum tipo de metadados, como nomes ou tipos dos parâmetros.

Essa abordagem resulta em bom desempenho.

Como SOAP usa codificação XML, a depuração de mensagens é mais fácil, já que

elas podem ser lidas e claramente entendidas. Porém, o processamento de mensagens que

usam esquema baseado em XML é mais demorado, aumentando a sobrecarga no servidor.

O analisador SOAP perde em desempenho, pois deve dar suporte a um número de funções

como verificação e conversão de tipo de dados, verificação se o documento XML está

correto (well-formed), etc. O mapeamento dos dados e objetos de uma linguagem em

elementos XML também é um fator que requer tempo (processo conhecido como

marshalling e unmarshalling). Além disso, as tags de marcação, que funcionam como

metadados, aumentam o tamanho da mensagem.

Não existe ainda uma solução padrão para melhorar o desempenho de aplicações

que utilizam serviços Web. Entretanto alguns autores já apontam soluções paliativas.

No artigo de Govindaraju et al [46] foram propostas várias técnicas para o

desenvolvimento de toolkits SOAP otimizados. Esse artigo também faz uma comparação

entre alguns toolkits existentes.

59

O tipo de codificação escolhido para a mensagem SOAP influi no tempo de troca

de mensagens entre agentes. Em Cohen [38] encontram-se testes que comprovam que a

codificação document/literal apresenta melhor desempenho. Isso porque, as regras da

codificação SOAP (encoded) tornam obrigatória a inclusão de informações sobre os tipos

de dados dos elementos em todas as mensagens SOAP recebidas e enviadas, aumentando a

complexidade das mensagens, e conseqüentemente a sua análise. Já as informações sobre

tipos de dados das mensagens document/literal geralmente estão em arquivos externos,

como na descrição WSDL ou em um esquema XML.

Em Kohlhoff et al [47] sugere-se o uso de alterações nos protocolos TCP e HTTP

para melhorar o desempenho na troca de mensagens SOAP. Nesse artigo, pesquisou-se o

desempenho de sistemas de mercado de capitais desenvolvidos com a tecnologia de

Serviços Web. Para isso, comparou-se seu desempenho com o de um protocolo já

conhecido e largamente utilizado para esse fim.

O estudo descobriu que, em aplicações comerciais, o SOAP apresenta um pior

desempenho se comparado a formatos binários. As mensagens SOAP podem ser de duas a

quatro vezes maiores que mensagens binárias equivalentes. A latência em redes locais

aumenta, com um tempo de codificação de 8-10 vezes maior e decodificação de cinco

vezes maior.

Esses resultados são similares aos encontrados em outros estudos, que tinham o

foco no desempenho de aplicações cientificas [48]. O interessante desse artigo é que o

desempenho do SOAP foi comparado também ao de outro protocolo baseado em texto, o

FIX. Os resultados mostram que mesmo comparado a um protocolo baseado em texto, o

SOAP apresenta resultados bem piores de desempenho. Disso, conclui-se que o

desempenho ruim do SOAP não pode ser totalmente justificado pelas desvantagens de

formatos baseados em texto. Também se sugere que melhorias na eficiência dos

codificadores SOAP podem permitir seu uso em aplicações que exijam alto desempenho.

O artigo também afirma que a simples redução do tamanho das mensagens SOAP,

pelo uso de tags mais curtas, não melhorou proporcionalmente a velocidade de codificação

e decodificação. Além disso, o uso de compactação tem efeito desprezível na eficiência da

codificação. Fazer a compressão dos dados reduz o tamanho das mensagens, mas acaba

requerendo mais tempo de processamento. Isso sugere que o maior custo da codificação e

60

decodificação XML está na sua complexidade estrutural e sintática, e não nos dados

contidos na mensagem ou nos nomes das tags.

Esses estudos também afirmam que a conversão de formato texto para binário é o

maior degradante na comunicação SOAP. Entretanto, isso é de se esperar, considerando a

natureza das aplicações testadas, que trocam muitos dados numéricos.

Já existe um interesse comercial na criação de roteadores e gateways para Web

services. O Web Service Gateway [49] da empresa IBM é um exemplo desse tipo de

produto. Esse componente middleware faz parte do WebSphere Application Server

Network Deployment e funciona como um intermediário, ou proxy, mapeando serviços

internos para o ambiente externo da Internet e serviços externos para o ambiente de

intranet.

Atualmente, já existem hardwares aceleradores do processo de análise e

transformação dos dados XML. Um exemplo é o XA35 XML Accelerator [50] da empresa

DataPower, que usa uma tecnologia própria para diminuir o tempo de processamento de

dados XML. O produto combina tecnologia de hardware, tecnologia própria e firmware

inteligente, oferecendo análise de XML, operações XPath e validação de esquemas XML.

A empresa possui um chip que permite a realização desse tipo de operação diretamente no

hardware.

Por ser uma tecnologia proprietária, o uso do hardware da empresa DataPower

apresenta alto custo (a partir de U$ 55.000,00 [50]). Além disso, essa solução não é

baseada em padrões abertos e nem é específica à arquitetura Web Services. As outras

abordagens apresentadas são soluções paliativas. A modificação dos protocolos HTTP ou

TCP é tecnicamente mais complexa e na maioria das vezes não é viável para os provedores

de serviço. Modificar o tipo de codificação ou a complexidade da estrutura dos

documentos XML enviados pode melhorar o desempenho dos serviços Web. Mas o ideal é

que o serviço escolha essas características baseado na sua funcionalidade e não em

possíveis problemas de desempenho.

61

2.7 CONSIDERAÇÕES FINAIS

Nesse contexto de baixo desempenho das aplicações que usam serviços Web, tem-

se o balanceamento de carga como um mecanismo e uma solução para aumentar o

desempenho dessas aplicações.

A especificação de um protocolo de endereçamento para Web Services permite a

realização de distribuição de carga voltada especialmente para esse tipo de arquitetura,

podendo adaptar-se melhor as suas características. O fato de esse protocolo estar em

processo de se tornar um padrão W3C garante a sua implementação na maioria das

plataformas de desenvolvimento Web Services.

62

3 BALANCEAMENTO DE CARGA EM WEB SERVICES

Entre os requisitos de qualidade necessários para serviços Web estão:

disponibilidade (se o serviço está executando), acessibilidade (ele está executando agora?),

integridade e confiabilidade (ele irá falhar quando executado? Com que freqüência?),

vazão (quantas requisições simultâneas podem ser executadas), latência (tempo de

reposta), conformidade a padrões e segurança (privacidade e autenticação).

Neste trabalho pretende-se melhorar o desempenho através do aumento da vazão e

ao mesmo tempo da diminuição da latência de serviços Web através do uso de um

mecanismo de distribuição de carga. A abordagem proposta por este trabalho para

melhorar o desempenho de serviços Web é o uso do balanceamento de carga entre

diferentes servidores que disponibilizam um mesmo serviço. As requisições balanceadas

são as mensagens enviadas pelos consumidores do serviço.

Para isso, foi escolhida a abordagem de balanceamento de carga baseada em

despachante em um conjunto de servidores Web. A máquina despachante é um endpoint de

serviços que encaminha as mensagens que chegam para um dos diversos servidores

disponíveis, baseado em uma política de distribuição. Os servidores podem estar agrupados

em um cluster, facilitando a comunicação com o despachante. Mas, com o intuito de

oferecer uma proposta mais flexível, essa característica não é obrigatória.

A abordagem de balanceamento de carga baseada em cliente não foi escolhida por

depender exclusivamente de mudanças nos consumidores dos serviços. No capítulo

anterior foram apontadas as características negativas dessa abordagem. Entre elas, destaca-

se a dificuldade de modificação do cliente. Consumidores de Web services são aplicações

que não utilizam um modo de acesso comum aos serviços, ao contrário dos usuários que

acessam a Web através de um navegador. Por conseqüência, os consumidores de serviços

são mais difíceis e complexos de serem modificados.

A abordagem baseada em DNS faz sentido somente no balanceamento de

requisições na camada de rede do protocolo IP. Ela pode ser adotada no balanceamento de

serviços Web, mas não seria uma solução voltada especialmente para esse tipo de

arquitetura.

63

Já a baseada em servidores requer alteração dos servidores com o objetivo de

efetuar processamento adicional nestes para balancear carga. Como foi visto, um mesmo

serviço pode ser implementado em sistemas operacionais, plataformas e linguagens de

programação diferentes. A abordagem baseada em servidores exigiria mudanças que

diminuiriam uma das melhores características da arquitetura Web Services: a flexibilidade.

Na abordagem escolhida, ao invés de acessar o serviço diretamente, o consumidor o

acessa através de um despachante. Essa escolha possibilita fraco acoplamento e

flexibilidade, por interceptar a ligação direta entre o provedor e o consumidor. O

consumidor continua enviando as requisições para o serviço do mesmo modo que enviaria

diretamente ao servidor no qual o serviço está implantando. Por sua vez, o serviço continua

respondendo às requisições que chegam a ele como se fossem requisições feitas

diretamente por um consumidor válido.

Esse tipo de abordagem ainda permite, além do balanceamento de carga, a

realização do roteamento baseado em conteúdo ou regras, a realização de filtragem de

conteúdo e a possibilidade de oferecer tolerância a possíveis falhas nos provedores do

serviço.

Segundo o W3C [10], um intermediário de serviços (service intermediary) é um

Web service cujo principal papel é transformar mensagens de modo que adicione valor, por

exemplo, filtrando as mensagens que manipula. Esse serviço preserva a semântica das

mensagens que recebe e envia. Normalmente ele não processa essas mensagens, mas

apenas as encaminha para outros serviços. De acordo com esse conceito, o despachante

apresentado neste trabalho é um intermediário de serviços.

Para diminuir a carga de processamento no despachante, foi decidido que ele

realizará a reescrita única de mensagens. Ou seja, o despachante apenas encaminha as

mensagens para o servidor escolhido. Se o consumidor indicar um endereço para envio da

mensagem de resposta, o servidor é responsável por enviar essa mensagem, em nome do

despachante, para o consumidor.

Uma grande desvantagem no uso de despachante, é que ele é um ponto de falha

único na abordagem apresentada. Se o despachante falhar, nenhuma requisição será

respondida. A solução para esse problema é manter uma ou mais réplicas do despachante,

com as mesmas configurações deste, que serão utilizadas em caso de falha.

64

Outro problema que deve ser endereçado é o tratamento do uso dos vários

protocolos de transporte que podem ser utilizados. Por exemplo, uma mensagem pode

chegar pelo protocolo HTTP endereçada a um serviço que provê ligação somente ao

protocolo SMTP. Essa troca de protocolos pode acontecer e seria interessante que fosse

prevista pelo despachante.

Escolheu-se a especificação WS-Addressing para realizar o endereçamento e

encaminhamento das mensagens dos consumidores ao despachante, deste aos servidores e

destes aos consumidores. A principal razão é o fato de ela ser uma especificação Web

Services, desenvolvida especialmente para esse tipo de arquitetura. Além disso, com a

criação do Grupo de Trabalho no W3C, é esperado que em janeiro de 2006 ela se torne um

padrão de fato para Serviços Web. Como o WS-Addressing permite a independência de

transporte, pode-se receber mensagens de um protocolo de transporte e encaminhá- las para

um serviço que tenha uma ligação com outro protocolo, provendo uma solução para o

problema apresentado anteriormente.

O encaminhamento das mensagens pelo despachante será feito pela edição dos

cabeçalhos WS-Addressing das mensagens SOAP. Uma mensagem para um serviço será

endereçada com o endpoint do despachante (elemento to). Este irá selecionar o servidor

apropriado e re-encaminhar a mensagem, reescrevendo o elemento to do cabeçalho SOAP

com o endereço do servidor escolhido. É importante notar que os elementos from, replyTo

e faultTo da mensagem de resposta ou falha, se esta houver, devem conter o endpoint do

despachante. O próprio servidor encarregado de processar a mensagem providencia essa

alteração, implementando a abordagem com reescrita única de mensagens pelo

despachante. O servidor encaminhará a mensagem para o endpoint indicado no cabeçalho

replyTo, que comumente é o endereço do consumidor do serviço. Entretanto, se esse

endereço não for determinado pelo consumidor, a resposta será enviada para o endereço

indicado no protocolo de transporte.

O tipo de padrão de troca de mensagens (Message Exchange Pattern, ou MEP)

escolhido para o exemplo de implementação e testes neste trabalho é o MEP requisição-

resposta. Nesse padrão, um consumidor envia uma mensagem ao serviço e, após, recebe

deste uma mensagem de resposta. Em caso de erro, a resposta enviada é uma mensagem de

falha. Esse padrão é comumente implementado em operações síncronas. Para operações

65

mais longas e complexas, um padrão mais apropriado é a troca de mensagens assíncronas

com o co-relacionamento entre as mensagens.

O padrão requisição-resposta foi escolhido pois nele há uma maior interação entre

consumidor e serviço, o que pode caracterizar uma sessão entre essas duas aplicações.

Assim, haveria trocas de mensagens consecutivas entre as aplicações por um período de

tempo, ao contrário de mensagens de notificação de eventos, nas quais a interação entre

aplicações é menor ou mais esporádica. O MEP requisição-resposta é usado, por exemplo,

em aplicações de comércio eletrônico.

Para que o gerenciamento de sessão seja feito pelos servidores, é necessária uma

característica chamada afinidade de servidor, ou server affinity. Esse termo é usado para

designar a capacidade de um sistema de balanceamento de carga de manter as informações

de sessão de um usuário em suas várias requisições.

A solução apresentada neste trabalho pode permitir essa característica se, em uma

mesma sessão, o consumidor for redirecionado sempre para o mesmo servidor. O uso de

um parâmetro de referência que identifique o servidor escolhido para o cliente implementa

essa proposta. Quando uma requisição chega ao despachante, este seleciona um servidor

para respondê-la, baseado no algoritmo escolhido. Então, o despachante cria a mensagem a

ser direcionada a este servidor, colocando no seu cabeçalho um reference parameter

indicando o servidor escolhido. A resposta do cliente chegará com esta informação no

cabeçalho. Como descrito na especificação WS-Addressing, os cabeçalhos reference

parameter são transparentes ao cliente, ou seja, este somente deve replicar esses

cabeçalhos na sua próxima requisição. Assim, o despachante saberá que um servidor já foi

escolhido para aquele cliente, direcionando para o servidor indicado no cabeçalho da

requisição.

Essa solução, além de garant ir a afinidade de servidor, seleciona um servidor por

sessão, diminuindo a carga no despachante, que por si só já é um gargalo crucial do

sistema. Entretanto, foi escolhido como proposta final deste trabalho fazer a seleção do

servidor a cada mensagem que chega do consumidor. Considerou-se mais importante

refletir melhor a carga atual do sistema. Para manter a afinidade de servidor nessa solução,

poderia ser utilizado um banco de dados distribuído acessado por todos servidores para

manter as informações de estado.

66

Se um intermediário SOAP será utilizado, é importante tomar cuidado para não

realizar a manipulação dos corpos das mensagens por este intermediário de forma

desnecessária, já que isso traria maiores problemas de desempenho. Neste contexto,

apresenta-se mais uma vez a importância da utilização dos cabeçalhos WS-Addressing.

Normalmente, além de informações de endereçamento, o serviço intermediário necessita

de informações de sessão ou de contexto para encaminhar, contabilizar e fazer log das

mensagens que chegam a ele. Com o uso da especificação WS-Addressing, essas

informações estariam nos cabeçalhos da mensagem SOAP, permitindo que o corpo da

mensagem contenha somente informações importantes para a realização do serviço pelo

ultimateReceiver.

3.1 ALGORITMOS DE BALANCEAMENTO DE CARGA

Um algoritmo de balanceamento de carga deve ser escolhido de modo que não

deteriore ainda mais o desempenho do serviço. O uso de despachante introduz mais uma

entidade entre o consumidor e o provedor. Por isso, se ele não for bem planejado e

implementado, pode trazer mais problemas do que soluções, inclusive a completa

indisponibilidade do serviço.

A técnica de balanceamento de carga escolhida deve ser ao mesmo tempo simples e

eficiente. Para isso, pode-se escolher entre uma variedade de algoritmos que se adequam

melhor a diferentes situações. Todos esses algoritmos têm como objetivo distribuir as

requisições de forma a maximizar a utilização de todos os servidores disponíveis. Neste

trabalho, os seguintes algoritmos foram implementados:

• Randômico: a cada requisição, um servidor é escolhido aleatoriamente. Existe uma

pequena probabilidade de, em um pequeno número de requisições, a carga não ser

distribuída igualmente entre os servidores. Entretanto, em média, a carga é

distribuída igualmente.

Vantagens: é um algoritmo simples. É recomendado em clusters nos quais todos

servidores têm a mesma capacidade (homogêneos).

Desvantagem: existe um pequeno custo de processamento na geração do número

randômico para cada requisição. Não considera informações sobre o estado atual

67

dos servidores – por exemplo, a carga e o número de conexões ativas em um

determinado momento ou mesmo se ocorreu falha no servidor.

• Round-robin: neste algoritmo, o primeiro servidor escolhido é o que foi definido

em primeiro lugar nas configurações do despachante. Os próximos servidores serão

escolhidos em ordem circular. Quando um servidor é escolhido para responder a

uma requisição, ele é enviado ao fim da lista, e o próximo servidor a ser escolhido é

o próximo da lista.

Vantagens: possui uma lógica simples e previsível. As requisições são distribuídas

igualmente entre os servidores. Como trata todos os servidores da mesma maneira,

é ideal para cluster de servidores homogêneos.

Desvantagens: pode ocorrer que um servidor mais lento, ou mesmo com um

processo mais demorado, tranque as requisições quando a sua vez de ser escolhido

chegar novamente. Ou seja, esse algoritmo não é ideal para cluster de servidores

heterogêneos. Além disso, esse algoritmo também não considera informações sobre

o estados dos servidores.

• Round-robin com pesos: igual ao algoritmo anterior, sendo que agora são

consideradas as diferenças entre os servidores, através de pesos atribuídos na

configuração. Cada servidor possui um peso, que declara qual porção das

requisições vai ser direcionada a ele. Servidores com peso maior recebem um maior

número de requisições. Por exemplo, se existem três servidores com os pesos: 5, 7

e 3, o servidor 1 receberá 5/(5+7+3) das requisições.

É importante que os pesos dos servidores sejam determinados com precisão, para

melhor aproveitamento do algoritmo. É interessante a realização de testes de carga

para verificar o comportamento dos servidores ao receber um grande número de

requisições, e, a partir daí, determinar qual carga cada servidor consegue consumir

de maneira correta.

Vantagens: este algoritmo torna possível utilizar Round-robin em clusters

heterogêneos.

Desvantagens: ainda não considera informações sobre o estado dos servidores.

68

Menor carga : o servidor com a menor carga tem maior probabilidade de ser

selecionado para receber as requisições. O despachante possui um processo,

executado em paralelo, para cada servidor, que pergunta, em intervalos de tempo,

qual a carga disponível no servidor. Ao selecionar um servidor, essas informações

são consideradas, dando maior probabilidade de um servidor com menor carga ser

escolhido. Não significando que sempre o servidor com menor carga será

selecionado, para evitar que esse servidor seja sobrecarregado. Para isso, um

número randômico é gerado, levando-se em conta o total de carga disponível dos

servidores. A probabilidade de um servidor ser sorteado é o seu valor de carga

disponível. Para o servidor i ser selecionado, o número sorteado tem que estar entre

o somatório das cargas disponíveis de C(i-1) a C(i-1) e Ci.

Vantagens: este algoritmo leva em conta informações dos servidores. O

despachante pode considerar que um servidor está indisponível se este não

responder à sua solicitação das informações de carga.

Desvantagens: é um algoritmo mais complexo. Exige comunicação entre os

servidores e o despachante para troca de informações sobre seus estados.

69

4 IMPLEMENTAÇÃO

A implementação deste trabalho consiste em duas partes: o serviço provido e

implantado nos servidores e o despachante (WS-LoadBalancer). Além destes,

implementou-se um cliente que irá acessar o serviço com o intuito de testar o

funcionamento do mecanismo de balanceamento de carga. A funcionalidade escolhida para

o serviço de teste é bem simples: um serviço de tradução, que recebe um texto para ser

traduzido, informando também de qual e para qual língua a tradução deve ser feita. A

simplicidade do serviço facilita na comparação de desempenho do despachante usando os

diferentes algoritmos.

Figura 9 – Três clientes acessando um serviço implementado em duas réplicas, usando WS-LoadBalancer.

A IDE para desenvolvimento escolhida foi o Eclipse, por ser uma ferramenta com

muitos recursos e por ser um software livre. A linguagem escolhida, Java, foi fortemente

influenciada pelas implementações existentes da especificação WS-Addressing e também

por possuir ampla disponibilidade de ferramentas e APIs. Neste projeto utilizou-se a versão

5.0 do seu ambiente de execução (JRE 1.5.0_02).

A seguir, serão descritas as implementações do cliente, despachante e servidores.

70

4.1 CLIENTE

Foi desenvolvida uma pequena aplicação cliente para testes, com o objetivo de ser a

aplicação consumidora do serviço. Ela consiste em uma página JSP que recebe do usuário

os parâmetros do serviço e mostra o resultado na tela. A plataforma Axis [51] foi escolhida

como plataforma de desenvolvimento de Web services para o cliente. O Axis é uma

implementação do protocolo SOAP desenvolvida pelo projeto Apache. Essa

implementação nada mais é do que uma aplicação que roda em um servidor Tomcat, um

servidor de aplicação também desenvolvido pela Fundação Apache. As versões 1.1 do

Axis e 5.0 do Tomcat foram utilizadas.

A plataforma Axis foi escolhida por ser livre e de código aberto, o que facilita

alterações necessárias ao modelo de manipulação das mensagens SOAP. A sua escolha

também se deu pois com ela seria possível utilizar o projeto Web Service FX

(Functionality Extensions) [52]. Esse projeto, também da Fundação Apache, provê

ferramentas para adicionar funcionalidades descritas nas especificações Web Services.

Uma das especificações implementadas é a WS-Addressing.

Entre os objetivos do projeto Web Service FX estão os de criar e manter

implementações para especificações de Serviços Web em várias linguagens de

programação, incluindo Java e C++, que deverão ser usadas em conjunto com um ou mais

dos outros projetos Web Services @ Apache, como o Apache Axis. A implementação Web

Services Addressing é um manipulador SOAP (SOAP Handler) que interage com

mensagens SOAP, colocando e extraindo informações de endereçamento dos seus

cabeçalhos XML. O projeto WS-FX pretende projetar componentes para serem utilizados

independentemente de outro produto ou framework, sempre seguindo os padrões para Web

Services. O projeto WS-FX Addressing ainda está em desenvolvimento e testes, não

possuindo por isso, um número de versão.

4.2 DESPACHANTE WS-LOADBALANCER

Para a implementação do despachante encarregado do balanceamento de carga,

usou-se como base o módulo WS-Dispatcher [53] [54]. Esse módulo faz parte do projeto

Web/XML Services Utility Library (XSUL) do laboratório Extreme! Lab, Universidade de

71

Indiana, Estados Unidos. O XSUL visa criar ferramentas e utilitários em diversos módulos

para Web Services. A versão utilizada foi a 1.1.

Os objetivos do despachante WS-Dispatcher são: possibilitar que requisições

possam ser enviadas para serviços internos que não são diretamente acessíveis e permitir

que clientes que não são serviços Web possam tornar-se Web service peers, ou seja, que

eles possam receber mensagens de modo assíncrono, como se fossem serviços Web. O

WS-Dispatcher permite que serviços internos sejam expostos de maneira segura pela

Internet, pois são acessados através de um despachante.

Na implementação do despachante do presente trabalho, foi criado um novo

módulo para o projeto XSUL, que estende o módulo WS-Dispatcher para que este possa

realizar balanceamento de carga.

O servidor HTTP utilizado no despachante foi o servidor implementado pelo

projeto XSUL. A implementação WS-Addressing utilizada pelo despachante também foi a

do projeto XSUL. Mas como esta e a implementação WS-FX são baseadas na mesma

especificação, elas são intercambiáveis. O único problema tido com a implementação

XSUL foi a falta de suporte para propriedades e parâmetros de referência. Assim, foi

impossibilitada a implementação de afinidade de servidor pelo uso de um cabeçalho

reference parameter indicando o servidor selecionado na sessão.

Existem dois modos de interação com o despachante WS-Dispatcher. No primeiro

modo, chamado RPC-Dispatcher, quando uma requisição chega ao despachante, este

pesquisa pelo endereço físico do serviço. Logo após, o despachante abre uma nova

conexão com o serviço, encaminhando a requisição. A sua resposta é enviada de volta ao

despachante, que a envia ao consumidor na mesma conexão HTTP. Então, no caso do

RPC-Dispatcher, consumidores esperam pela resposta do serviço e o WS-Dispatcher deve

manter uma conexão com o consumidor e uma segunda com o serviço. Mas essa

abordagem não é ideal para serviços que desejam enviar a resposta para outro endpoint ou

que necessitam muito tempo para processar uma requisição, pois nesse caso, a conexão

TCP pode terminar antes da resposta estar pronta para o envio.

Para solucionar problemas como estes, pode-se usar o segundo modo de interação,

chamado MSG-Dispatcher, que provê o encaminhamento assíncrono de mensagens WS-

Addressing entre consumidores e serviços. Quando o despachante recebe uma requisição

72

de um consumidor e esta é aceita, imediatamente uma resposta indicando o seu

recebimento é enviada ao consumidor e esta conexão é fechada. O despachante envia a

mensagem ao serviço, em uma nova conexão, com o cabeçalho replyTo para ele mesmo e

o cabeçalho to para o serviço. Então, se houver resposta, o despachante a receberá e

reescreverá esses cabeçalhos modificados com seus valores originais, enviando para o

endpoint indicado no cabeçalho replyTo.

No presente trabalho a implementação do RPC-Dispatcher foi modificada para que

o protocolo WS-Addressing fosse utilizado também nas requisições síncronas. Assim, o

despachante encaminharia somente as requisições aos servidores. E o próprio servidor,

usando o cabeçalho replyTo da mensagem, enviaria a resposta diretamente ao consumidor.

Se esse cabeçalho não for definido, a resposta é enviada para o endereço indicado no

protocolo de transporte.

Um arquivo de configuração da tabela de roteamento do despachante foi criado

pelo projeto XSUL para mapear os endereços virtuais aos endereços físicos. Essa escolha

permite que essas informações sejam modificadas sem a necessidade de edição e nova

compilação do código.

Para transformar o WS-Dispatcher em uma entidade que realiza balanceamento de

carga, foram feitas outras modificações no despachante para que ele pudesse realizar essa

tarefa. No projeto inicial do WS-Dispatcher, a classe que representa a tabela de roteamento

continha somente uma lista de pares “endereço virtua l”/“endereço físico”. Neste trabalho,

para o WS-LoadBalancer, foi criada uma nova implementação da tabela de roteamento,

que agora contém uma lista de objetos da classe LoadBalancingRoutingItem. Cada objeto

dessa classe possui um endereço virtual (nome do serviço), uma lista de servidores que

implementam o serviço e um objeto que implementa o algoritmo de balanceamento de

carga que é utilizado para esse serviço. Na Figura 10 é apresentado o diagrama das novas

classes implementadas neste trabalho no despachante.

73

Figura 10 – Diagrama de classes do despachante WS-LoadBalancer.

Com este objetivo foi modificado também o arquivo de configuração do

despachante, para que permita determinar mais de um servidor para um endereço virtual.

Ou seja, para cada serviço disponível em um endereço virtual, define-se os servidores que

implementam este serviço. Além disso, nas configurações também é possível definir qual o

algoritmo de balanceamento de carga será utilizado, permitindo que diferentes algoritmos

de balanceamento de carga possam ser usados em diferentes serviços. Um exemplo de

arquivo de configuração para um serviço chamado “translator” usando algoritmo de

balanceamento de carga randômico é apresentado na Figura 11.

Figura 11 – Exemplo de arquivo de configuração do despachante WS-LoadBalancer.

O serviço é acessado pelo cliente através do endereço do despachante e o nome do

serviço. Por exemplo, se um despachante está no endereço

1# Uso: [service]=[className]%[host:port/path],[host:port/path],[host:port/path]... 2translator=RandomPolicy%http://translator.example/WSATranslator,anotherserver:5580/WSATranslator,localhost/axis/services/WSATranslator

74

“http://www.dispatcher.example/”, o consumidor acessaria o serviço “translator” usando a

URL: “http://www.dispatcher.example/translator” para acessar o endpoint.

A implementação dos algoritmos de balanceamento de carga randômico e Round-

robin foi simples e utilizou somente APIs padrões da linguagem Java. O algoritmo

randômico, a cada requisição, seleciona um número randômico entre zero e o número de

servidores. O número sorteado indica o índice do servidor selecionado na lista de

servidores.

O algoritmo Round-robin com pesos permite que seja indicado um peso, no arquivo

de configurações, para cada servidor. A indicação deve vir após o endereço do servidor,

separada por um espaço. O peso nada mais é do que o número de vezes que um servidor

será selecionado em cada iteração na lista de servidores. Se nenhum peso é atribuído, o

servidor será selecionado uma vez a cada rodada na lista de servidores. O algoritmo

Round-robin sem pesos acontece quando pesos iguais são atribuídos a todos os servidores.

Por ser um algoritmo mais complexo, o Menor Carga exigiu o uso de APIs

externas. Isso porque é necessário descobrir a carga atual dos servidores. Com esse

propósito, escolheu-se o uso do protocolo Simple Network Management Protocol (SNMP)

que permite acessar uma variedade de informações sobre uma máquina que execute um

agente SNMP. Esse protocolo foi escolhido por ser um padrão na sua área e por possuir

implementações em diversos tipos de máquinas.

Ao iniciar o despachante, é criada uma thread para cada servidor do serviço, que

vai obter as suas informações de carga. Essa thread é responsável por questionar um

servidor sobre o valor da sua carga disponível. Esse valor será usado pelo despachante ao

selecionar um servidor para uma requisição. A API Java SNMP Package [55], uma

implementação livre e de código aberto do protocolo SNMP, foi utilizada por essas threads

para acessar o agente SNMP instalado em cada servidor. No SNMP, as informações

encontram-se nas chamadas Management Information Bases (MIBs), uma coleção de

objetos acessíveis através da chamada de métodos da interface SNMP. Nesse algoritmo,

para sistemas Unix, foi utilizada a MIB ucdavis, que possui uma entrada contendo

informações sobre a carga disponível na CPU de uma máquina (ssCpuRawIdle). Já para

sistemas Windows, foi utilizada a MIB WTCS, que possui uma entrada com informações

sobre a carga utilizada (cpuPercentProcessorTime) em uma máquina. A thread recebe o

valor ssCpuRawIdle ou cpuPercentProcessorTime (nesse caso, esse valor deve ser

75

subtraído de 100) e atua liza uma lista que contém a carga disponível para todos os

servidores. Essa lista é usada para calcular a probabilidade de cada servidor ser sorteado,

com a fórmula citada anteriormente.

Na Figura 12, um diagrama de seqüência de uma chamada a um serviço usando

WS-LoadBalancer é apresentada.

Figura 12 – Diagrama de Seqüência de chamada de serviço através do despachante WS-LoadBalancer.

4.3 SERVIDOR

O serviço de tradução WSATranslator foi implementado em cada servidor com a

mesma infra-estrutura do cliente: na plataforma Axis em servidores de aplicação Tomcat.

Entretanto, o Axis utilizado pelos servidores foi ligeiramente modificado. Para

implementar a reescrita única de mensagens, é necessário que o próprio servidor indique

nos cabeçalhos das mensagens de resposta ou falha que estas provêem do despachante e

não do seu próprio endereço. Com este intuito, foi implementado um novo manipulador

(handler) para as mensagens SOAP.

O Axis é essencialmente um processador de mensagens. Existe um componente

Axis que recebe dados da camada de transporte e transforma em um objeto Message, que

representa uma mensagem SOAP. A partir daí, um conjunto de manipuladores, ou

handlers, é chamado, em uma determinada seqüência, para processar a mensagem. O novo

handler implementado é uma extensão do handler de processamento de mensagens WS-

Addressing. Além de realizar o processamento necessário para mensagens WS-Addressing,

76

ele possui um atributo com o valor do endereço do despachante. A cada mensagem enviada

por um servidor, seja ela de resposta ou falta, os seus cabeçalhos from, replyTo e faultTo

recebem o valor do atributo com o endereço do despachante.

O servidor, após processar a mensagem, envia a resposta ao consumidor, se

indicado um endpoint para resposta (replyTo) na mensagem de requisição. Se não, a

resposta é enviada para o despachante, pela conexão HTTP, que enviará ao endereço do

consumidor indicado na camada de transporte.

77

5 TESTES E RESULTADOS

Além dos testes de funcionalidade utilizando o cliente JSP, também foram

realizados testes de carga no despachante. Esses testes foram feitos com a aplicação JMeter

[56], que é uma ferramenta de testes que permite criar um número estipulado de

requisições a páginas HTML, a documentos XML, a serviços através de mensagens SOAP

e outros.

A aplicação JMeter permite determinar o número de consumidores, quantas

requisições serão feitas por eles e com qual intervalo de tempo. Os resultados podem ser

visualizados através de diferentes listeners, no formato de tabelas e gráficos.

Os testes foram aplicados com o intuito de comparar o desempenho dos algoritmos

implementados, verificando o tempo de resposta do serviço quando o despachante utiliza

esses algoritmos.

5.1 AMBIENTE DE TESTES

Os testes foram realizados utilizando as seguintes máquinas, conectadas em uma

rede local:

• Cliente: PC AMD Athlon XP 2200. 256Mb Memória RAM. Sistema Operacional

Windows 2003 Server.

• Despachante: Notebook Mobile Intel Celeron 1,8 GHz. 256Mb Memória RAM.

Sistema Operacional Windows XP Service Pack 2.

• Servidor 1: PC AMD Athlon XP 2200. 224Mb Memória RAM. Sistema

Operacional Windows XP Service Pack 2.

• Servidor 2: PC AMD Athlon XP 1800. 512Mb Memória RAM Sistema

Operacional Windows XP Service Pack 2.

5.2 TESTES

Para melhor comparar os algoritmos em diferentes situações de carga, foram

realizados testes para cada implementação de algoritmo em duas situações diferentes. Na

primeira situação (cargas iguais), os dois servidores não estavam sobrecarregados. Já na

78

segunda (cargas diferentes), o servidor 2 estava com muitos processos em execução e, por

isso, ficou sobrecarregado, enquanto o servidor 1 possuía carga normal.

Não foram utilizados pesos nos testes do algoritmo Round-robin, pois as duas

máquinas servidoras possuíam uma capacidade de processamento semelhante.

O algoritmo de Menor Carga utilizou a variável cpuPercentProcessorTime (OID

1.3.6.1.4.1.9600.1.1.5.1.5.1.48) para o sistema operacional Windows. Essa variável retorna

a porcentagem de tempo de uso do processador, sendo necessário subtrair 100 desse valor

para descobrir o tempo de processador disponível. A variável ssCpuRawIdle não pôde ser

utilizada pois não está disponível para agentes SNMP no Windows.

Para cada situação de teste, foram realizados três testes em seqüência. Em cada um

desses testes, foi simulado o envio de 100 requisições por 50 usuários, através da aplicação

JMeter, totalizando 5000 requisições por teste e 15.000 requisições por situação de teste e

algoritmo. A média do tempo de resposta foi calculada pela média dos três testes em

seqüência para cada algoritmo e cada situação de teste.

5.3 RESULTADOS

A aplicação JMeter possui um elemento chamado listener, que é responsável por

armazenar e exibir todos resultados das requisições efetuadas durante a execução de um

plano de testes. Os resultados poderão ser gravados em um arquivo ou exibidos através de

algum modelo visual de dados.

Entre as informações disponíveis estão a média de tempo de resposta de todas as

amostras (requisições) em milissegundos e o desvio padrão em milissegundos. A seguir, é

apresentado o gráfico com o resultado do tempo de resposta médio para cada algoritmo nos

testes nas duas situações.

79

Tempo de resposta médio

149,67151175,34

207,67

168,34 147

0

50

100

150

200

250

Randô

mico

Round

-robin

Menor

carga

Mili

sseg

un

do

s

Cargas diferentes

Cargas iguais

Figura 13 – Gráfico tempo de resposta médio dos algoritmos de balanceamento de carga no WS-LoadBalancer.

O gráfico da Figura 13 mostra que os algoritmos Round-robin e Randômico

possuem comportamento parecido nas duas situações testadas: tanto em situações nas quais

a carga dos dois servidores está baixa e igual quanto em situações nas quais um servidor

está bem mais carregado que o outro. Ainda assim, o algoritmo de Round-robin possui o

menor tempo de resposta dos dois.

Nesse gráfico também se pode ver que o algoritmo de Menor Carga possui o mais

alto tempo de resposta quando os dois servidores possuem cargas iguais e baixas. Isso

acontece porque a escolha do servidor nesse algoritmo é mais complexa que nos outros

dois. Entretanto, essa complexidade é superada pela implementação do algoritmo que

escolhe o servidor menos carregado quando um deles possui um maior processamento.

Assim, é demonstrado que, em cargas altas, o algoritmo de Menor Carga apresenta um

melhor resultado, mostrando a importância de saber o estado atual dos servidores ao se

selecionar um servidor para responder uma requisição.

80

6 CONCLUSÕES E TRABALHOS FUTUROS

6.1 CONCLUSÕES

Os Web Services apresentam diversas qualidades, entre elas a flexibilidade, a

interoperabilidade e o fraco acoplamento. Entretanto, a sua implementação ainda possui

problemas de desempenho que este trabalho buscou endereçar. Com este trabalho,

julgamos que foi possível obter êxito no emprego de replicação e de algoritmos de

balanceamento de carga com o intuito de limitar os problemas de desempenho

apresentados pelos Web Services.

A arquitetura Web Services foi pesquisada e estudada, assim como, soluções já

existentes de balanceamento de carga em outras arquiteturas. Dessa maneira, pôde-se

propor uma heurística para o balanceamento de carga específica para a arquitetura Web

Services. A solução apresentada ainda oferece diferentes algoritmos de balanceamento de

carga, que podem ser escolhidos conforme as características do serviço e dos servidores

que o implementam. Nos trabalhos e estudos pesquisados, não foi encontrada uma solução

de balanceamento de carga que abordasse especificamente serviços Web.

É importante lembrar que a decisão de utilizar a tecnologia Web Services nunca vai

ser justificada com base somente no seu desempenho, mas sim, em características de

interoperabilidade, flexibilidade, reutilização de código, redução de custos operacionais e

de desenvolvimento e melhor relacionamento com parceiros de negócio e clientes.

Contudo, a disponibilidade e o desempenho dos serviços são imprescindíveis quando se

deseja oferecer qualidade de serviços para os seus consumidores.

6.2 TRABALHOS FUTUROS

Este trabalho ainda pode ser melhorado para aprimorar cada vez mais a qualidade

de serviço oferecida pelos serviços Web.

Na abordagem de balanceamento de carga baseada em despachante, é

imprescindível que a máquina no papel de despachante tenha a menor sobrecarga possível.

Por isso, uma sugestão para melhorar o desempenho do algoritmo de Menor Carga seria

modificar este algoritmo para que o próprio servidor enviasse a sua carga para o

despachante. Assim, torna-se desnecessário o uso de threads no despachante para

81

questionar os servidores, diminuindo o número de processos que são executados nessa

máquina.

O despachante ainda poderia ser modificado para receber requisições em um

protocolo de transporte e encaminhar para um servidor que utiliza outro protocolo.

Atualmente, o servidor despachante é somente um servidor HTTP. Entretanto, com o uso

da especificação WS-Addressing, para implementar essa nova solução seria necessário

somente identificar o protocolo de transporte para cada servidor e criar a conexão

adequada quando um servidor for escolhido. As informações de endereçamento e

processamento encontram-se todas nas próprias mensagens.

O despachante WS-LoadBalancer também poderia ser aperfeiçoado com o intuito

de prover tolerância a faltas. Para isto, seria necessário monitorar a atividade dos

servidores e distribuir a carga entre os servidores não-faltosos.

Seria também interessante desenvolver um trabalho mais completo de avaliação dos

algoritmos de balanceamento de carga sob diferentes condições, para embasar o

desenvolvedor que utiliza o mecanismo proposto na escolha do algoritmo mais adequado

para uma determinada aplicação.

Uma arquitetura nova é sempre muito interessante e desperta a atenção daqueles

que desejam desenvolver sistemas melhores e mais flexíveis. Com ênfase em padrões

abertos e flexibilidade, os Serviços Web oferecem uma ótima solução para integração de

sistemas. Mas ela apresenta também novos desafios que devem ser endereçados para que o

esforço de adotar essa nova arquitetura valha a pena.

82

REFERÊNCIAS BIBLIOGRÁFICAS

1. LEINER, Barry et al. A Brief History of the Internet. The Internet Society. Versão 3.32. Última revisão: 10 dez. 2003. Disponível em: <http://www.isoc.org/internet/his tory/brief.shtml>. Acesso em: 29 jan. 2005.

2. VINOSKI, Steve. WS-Nonexistent Standards. IEEE Internet Computing. Nov./Dez. 2004.

3. TARTANOGLU, Ferda et al. Dependability in the Web Services Architecture. Proc. of WADS. 2002.

4. KREGER, Heather. Web Services Conceptual Architecture. IBM Software Group. Maio 2001.

5. WORLD Wide Web Consortium (W3C). Disponível em: <http://www.w3.org/>. Acesso em: 20 nov. 2004.

6. TIAN, M. et al. Performance Impact of Web Services on Internet Servers . International Conference on Parallel and Distributed Computing and Systems. Estados Unidos da América, nov. 2003.

7. MANI, Anbazhagan; NAGARAJAN, Arun. Understanding quality of service for Web services. Jan 2002. Disponível em: <http://www-106.ibm.com/developerworks/webservices/library/ws-quality.html>. Acesso em: 24 abr 2005.

8. DAVIS, Dan; PARASHAR, Manish. Latency Performance of SOAP Implementations. Proc. 2nd IEEE/ACM International Symposium on Cluster Computing and the Grid. Maio 2002.

9. VERÍSSIMO, P.; RODRIGUES, L. Distributed Systems for System Architects. Kluwer Academic Publishers, 2001.

10. W3C. Web Services Architecture. W3C Working Group Note. Fev. 2004, Disponível em: <http://www.w3.org/TR/2004/NOTE-ws-arch-20040211/ >. Acesso em: 10 jul. 2004.

11. COULOURIS, George; DOLLIMORE, Jean; KINDBERG, Tim. Distributed Systems: Concepts and Design. Terceira Edição. Addison-Wesley, 2001.

12. CARDELLINI, V.; COLAJANNI, M.; YU, P. Dynamic Load Balancing on Web-Server Systems. IEEE Internet Computing. Maio/jun. 1999.

13. VINGRALEK, Radek et al. Web++: A System For Fast and ReliableWeb Service. Proceedings of 1999 USENIX Annual Technical Conference, Monterey, California, jun. 1999.

14. KWAN, T.; MCGRATH, R.; REED, D. NCSA’s World Wide Web server: Design and Performance. Computer, Vol. 28, no. 11, nov. 1995.

15. CISCO DistributedDirector. Disponível em: <http://www.cisco.com/warp/public/cc/pd/cxsr/dd/index.shtml>. Acesso em: 20 nov. 2004.

16. TEO, Y.; AYANI, R. Comparison of Load Balancing Strategies on Cluster-based Web Servers. Transactions of the Society for Modeling and Simulation, 2001.

17. HUNTA, Guerney et al. Network Dispatcher: a connection router for scalable Internet services. Comp. Networks and ISDN Sys., set. 1999.

18. DAMANI, P. et al. ONE-IP: Techniques for hosting a service on a cluster of machines. Computer Networks and ISDN Systems, Vol. 29, 1997.

19. ANDERSON, D. et al. SWEB: Toward a Scalable World Wide Web-Server on Multicomputers. 10th IEEE International Symposium on Parallel Processing, 1996.

83

20. BESTAVROS, A. et al. Distributed Packet Rewriting and its Application to Scalable Web Server Architectures. 6th IEEE Int’l Conf. Network Protocols , Estados Unidos da América, 1998.

21. MAHMOUD, Qusay H. Service-Oriented Architecture (SOA) and Web Services: The Road to Enterprise Application Integration (EAI). Abril 2005. Disponível em: <http://java.sun.com/developer/technicalArticles/WebServices/soa/ >. Acesso em: 14 maio 2005.

22. SYSTNET. Introduction to Web Services Architecture. 2002. Disponível em: <http://www.systinet.com/download/74c83b5cf8607b124e247426574e0943/wp_Systinet_SOA.pdf>. Acesso em: 20 nov. 2004.

23. HAAS, H.; BROWN, A. W3C Glossary. W3C Working Group Note. Fev. 2004. Disponível em: <http://www.w3.org/TR/ws-gloss/>. Acesso em: 20 nov. 2004.

24. VOGELS, Werner. Web Services Are Not Distributed Objects. IEEE Internet Computing. Nov.-dez. 2003. Disponível em: <http://weblogs.cs.cornell.edu/AllThingsDistributed/archives/000343.html>. Acesso em: 20 nov. 2004.

25. SUN Microsystems. Java Remote Method Invocation (Java RMI). Disponível em: <http://java.sun.com/products/jdk/rmi/>. Acesso em: 20 nov. 2004.

26. COMMON Object Request Broker Architecture (CORBA) Core Specification. Disponível em: <http://www.omg.org/technology/documents/formal/corba_iiop.htm>. Acesso em: 20 nov. 2004.

27. DCE 1.1: Remote Procedure Call. Disponível em: <http://www.opengroup.org/onlinepubs/9629399/>. Acesso em: 20 nov. 2004.

28. MICROSOFT Corporation. Distributed Object Component Model (DCOM) Architecture. Disponível em: <http://www.microsoft.com/ntserver/techresources/appserv/COM/dcom_architecture.asp>. Acesso em: 20 nov. 2004.

29. SUN Microsystems. Java Technology. Disponível em <http://java.sun.com/>. Acesso em: 20 nov. 2004.

30. OGBUJI, Uche. The Past, Present and Future of Web Services, part 1. Set. 2002. Disponível em: <http://www.webservices.org/index.php/article/articleprint/663/-1/61/ >. Acesso em: 20 nov. 2004.

31. OGBUJI, Uche. The Past, Present and Future of Web Services, part 2. Out. 2002. Disponível em: <http://www.webservices.org/index.php/article/articleprint/679/ -1/61/>. Acesso em: 20 nov. 2004.

32. HP Web Services Platform. Disponível em: <http://www.hp.com/go/espeak>. Acesso em: 20 nov. 2004.

33. CHRISTENSEN , Erik et al. Web Services Description Language (WSDL) 1.1. Março 2001. Disponível em: <http://www.w3.org/TR/wsdl>. Acesso em: 20 nov. 2004.

34. UNIVERSAL Description, Discovery and Integration (UDDI). Disponível em: <http://www.uddi.org/>. Acesso em: 20 nov. 2004.

35. WSWS World Wide Web Consortium. Workshop on Web Services. Estados Unidos da América, 11-12 abr. 2001. Disponível em: <http://www.w3.org/2001/01/WSWS>. Acesso em: 20 nov. 2004.

36. SOAP Specifications. Disponível em: <http://www.w3.org/TR/soap/>. Acesso em: 20 nov. 2004.

37. CABRERA, Luis Felipe; KURT, Christopher; BOX, Don. An Introduction to the Web Services Architecture and Its Specifications. Versão 2.0, out. 2004. Disponível em: <http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dnwebsrv/html/introwsa.asp>. Acesso em: 20 nov. 2004.

84

38. COHEN, F. Discover SOAP encoding's impact on Web service performance. Março 2003. Disponível em: <http://www-106.ibm.com/developerworks/webservices/library/ws-soapenc/>. Acesso em: 20 nov. 2004.

39. WEB Services Interoperability Organization. Disponível em: <http://www.ws-i.org/>. Acesso em: 20 nov. 2004.

40. BALLINGER, Keith et al. Web Services Metadata Exchange. Set. 2004. Disponível em: <ftp://www6.software.ibm.com/software/developer/library/WS-MetadataExchange.pdf>. Acesso em: 29 abr. 2004.

41. WEB Services Addressing (WS-Addressing). W3C Member Submission. Ago. 2004. Disponível em: <http://www.w3.org/Submission/ws-addressing/>. Acesso em: 29 abr. 2004.

42. CHARTER of the Web Services Addressing Working Group. Disponível em: <http://www.w3.org/2004/09/wsa-charter.html>. Acesso em: 20 nov. 2004.

43. VAWTER, Chad; ROMAN, Ed. J2EE vs. Microsoft.NET - A comparison of building XML-based web services. The Middleware Company, junho, 2001.

44. FONTANA, John. Move afoot to speed XML traffic. Network World. Jun. 2003. Disponível em: <http://www.nwfusion.com/news/2003/0623xml.html>. Acesso em: 20 nov. 2004.

45. BUSTAMANTE, Fabian et al. Efficient wire formats for high performance computing. Supercomputing 2000, Estados Unidos da América, nov. 2000.

46. GOVINDARAJU, M. et al. Toward Characterizing the Performance of SOAP Toolkits. 5th IEEE/ACM International Workshop on Grid Computing. Nov, 2004.

47. KOHLHOFF, C.; STEELE, R. Evaluating SOAP for High Performance Business Applications: Real-Time Trading Systems. WWW2003, Hungria, 2003.

48. CHIU, K.; GOVINDARAJU, M.; BRAMLEY, R. Investigating the limits of SOAP performance for scientific computing. 11th IEEE International Symposium on High Performance Distributed Computing, 2002.

49. Fremantle, Paul et al. Web Services Gateway. Dez. 2001. Disponível em: <http://www.alphaworks.ibm.com/tech/wsgw>. Acesso em: 29 abr 2005.

50. HARBAUGH, Logan. Power Up XML Data Processing With the DataPower XA35 XML Accelerator. Dez. 2002. Disponível em: <http://www.serverwatch.com/hreviews/article.php/1550181>. Acesso em: 27 nov. 2004.

51. APACHE Axis. Disponível em: <http://ws.apache.org>. Acesso em: 5 maio 2005.

52. Web Service FX (Functionality Extensions). Disponível em: <http://ws.apache.org/ws -fx/>. Acesso em: 20 nov. 2004.

53. DI COSTANZO, Alexandre; SLOMINSKI, Aleksander. WS-Dispatcher. Disponível em: <http://www.extreme.indiana.edu/xgws/dispatcher/>. Acesso em: 5 maio 2005.

54. SLOMINSKI, Aleksander et al. Asynchronous Peer-to-Peer Web Services and Firewalls. 7th International Workshop on Java for Parallel and Distributed Programming (IPDPS 2005). Abril 2005.

55. SEVY, Jonathan. Java SNMP Package. Drexel University. Disponível em: <http://gicl.cs.drexel.edu/people/sevy/snmp/snmp_package.html>. Acesso em: 14 maio 2005.

56. APACHE JMeter. Disponível em: <http://jakarta.apache.org/>. Acesso em: 5 maio 2005.

85

57. CURBERA, F. et al. Unraveling the Web Services Web - An Introduction to SOAP, WSDL, and UDDI. IEEE Internet Computing, março/abr. 2002.

58. BRYHNI, H.; KLOVNING, E.; KURE, O. A Comparison of Load Balacing Techniques for Scalable Web Servers. IEEE Network, jul./agosto 2000.

59. DIAS, D. et al. A Scalable and Highly Available Web Server. IEEE COMPCON, 1996.

60. FRYE, C. SOA’s up. Application Development Trends, agosto 2004. Disponível em: <http://www.adtmag.com/article.asp?id=9781>. Acesso em: 20 nov. 2004.

86

APÊNDICES

APÊNDICE A – CÓDIGO FONTE

Licença GNU GENERAL PUBLIC LICENSE. Version 2, June 1991 Interface LBPolicy package xsul.loadbalancer.lbpolicies; import java.util.ArrayList; import xsul.dispatcher.routingtable.WS; /** * Interface for load balacing algorithms implementations */ public interface LBPolicy { public abstract void init(ArrayList list); public abstract WS selectServer(); } Classe AvailableLoadPolicy package xsul.loadbalancer.lbpolicies; import java.util.*; import java.math.BigInteger; import xsul.loadbalancer.FileLogger; import xsul.dispatcher.routingtable.WS; /** * Load balancing policy in which the least loaded * servers have a greater probability of being chosen. * This algorithm uses ssCpuRawIdle (OID .1.3.6.1.4.1.2021.11.53) * from the ucdavis MIB. */ public class AvailableLoadPolicy implements LBPolicy { private FileLogger log; private ArrayList list; private HashMapThreadSafe idleList; private int index; public AvailableLoadPolicy() { log = new FileLogger("availableloadpolicy.log"); log.start(); } public void init(ArrayList paramList) { this.list = paramList; this.idleList = new HashMapThreadSafe(this.list.size()); ArrayList threadList = new ArrayList(this.list.size()); for (index=0; index < this.list.size(); index++) { threadList.add(index, new ServerThread (this.index, this.list, this.idleList)); ((Thread) threadList.get(index)).start(); } } public WS selectServer() { BigInteger idle; long idleness; long cont = 0; int key = 0; int total = 0; // Total sum of idleList for (int x=0; x < this.idleList.size(); x++) { idle = (BigInteger) this.idleList.get(new Integer(x)); total = total + idle.intValue(); } Random random = new Random(); int rand = random.nextInt(total); for (int x=0; x < this.idleList.size(); x++) { idleness = ((BigInteger) this.idleList.get(new Integer(x))).longValue(); cont = cont + idleness; if (rand < cont) { key = x; break;

87

} } WS item = (WS) this.list.get(key); log.writeln("Selected server["+key+"] = "+ item.toString()); log.writeln("Random number: "+ rand +" | List: " + idleList + " | Total: " + total); log.flush(); return item; } } /** * Thread to collect available load information from a SNMP Agent */ class ServerThread extends Thread { private ArrayList list; private HashMapThreadSafe idleList; private int index;

public ServerThread(int index, ArrayList list, HashMapThreadSafe paramIdleList) { super(); this.index = index; this.list = list; this.idleList = paramIdleList;

} public void run() {

while (true) { String host = ((WS)list.get(index)).getHost(); // ssCpuRawIdle SnmpInquirer inq = new SnmpInquirer(host, "1.3.6.1.4.1.2021.11.53.0"); inq.inquire(); BigInteger value = (BigInteger)inq.getReturnedValue(); if (value != null) { // CpuIdle List idleList.put(new Integer(index), value); } try { sleep(2000); // miliseconds } catch (InterruptedException e) { e.printStackTrace(); } } } }

88

Classe LeastLoadPolicy package xsul.loadbalancer.lbpolicies; import java.util.*; import java.math.BigInteger; import xsul.loadbalancer.FileLogger; import xsul.dispatcher.routingtable.WS; /** * Load balancing policy in which the least loaded * servers have a greater probability of being chosen. * This algorithm uses cpuPercentProcessorTime for Windows (OID 1.3.6.1.4.1.9600.1.1.5.1.5.1.48) * It can also use hrProcessorLoad for Unix (not tested) */ public class LeastLoadPolicy implements LBPolicy { private FileLogger log; private ArrayList list; private HashMapThreadSafe idleList; private int index; public LeastLoadPolicy() { log = new FileLogger("leastload.log"); log.start(); } public void init(ArrayList paramList) { this.list = paramList; this.idleList = new HashMapThreadSafe(this.list.size()); ArrayList threadList = new ArrayList(this.list.size()); for (index=0; index < this.list.size(); index++) { threadList.add(index, new LeastLoadServerThread (this.index, this.list, this.idleList)); ((Thread) threadList.get(index)).start(); } } public WS selectServer() { Long idle; long idleness; long cont = 0; int key = 0; int total = 0; // Total sum of idleList for (int x=0; x < this.idleList.size(); x++) { idle = ( Long ) this.idleList.get(new Integer(x)); total = total + idle.intValue(); } Random random = new Random(); int rand = random.nextInt(total); for (int x=0; x < this.idleList.size(); x++) { idleness = ((Long) this.idleList.get(new Integer(x))).longValue(); cont = cont + idleness; if (rand < cont) { key = x; break; } } WS item = (WS) this.list.get(key); log.writeln("Selected server["+key+"] = "+ item.toString()); log.writeln("Random number: "+ rand +" | List: " + idleList + " | Total: " + total); log.flush(); return item; } } /** * Thread to collect load information from a SNMP Agent * and calculate available load */ class LeastLoadServerThread extends Thread { private ArrayList list; private HashMapThreadSafe idleList; private int index;

public LeastLoadServerThread(int index, ArrayList list, HashMapThreadSafe paramIdleList) {

super(); this.index = index; this.list = list;

89

this.idleList = paramIdleList; }

public void run() { while (true) { String host = ((WS)list.get(index)).getHost(); // Other possible OID: hrProcessorLoad: OID: 1.3.6.1.2.1.25.3.3.1.2.768 // Other possible OID (Windows): cpuPercentProcessorTime = 1.3.6.1.4.1.9600.1.1.5.1.5.1.48 SnmpInquirer inq = new SnmpInquirer(host, "1.3.6.1.4.1.9600.1.1.5.1.5.1.48"); inq.inquire(); BigInteger value = (BigInteger)inq.getReturnedValue(); if (value != null) { idleList.put(new Integer(index), new Long(100 - value.longValue())); } try { sleep(2000); // miliseconds } catch (InterruptedException e) { e.printStackTrace(); } } } } Classe RandomPolicy package xsul.loadbalancer.lbpolicies; import java.util.*; import xsul.loadbalancer.FileLogger; import xsul.dispatcher.routingtable.WS; /** * Load balancing policy in which servers are selected randomly. */ public class RandomPolicy implements LBPolicy { private FileLogger log;

private ArrayList serverList; public RandomPolicy() { log = new FileLogger("random.log"); log.start(); } public void init(ArrayList list) { this.serverList = list; } public WS selectServer() { Random random = new Random(); int key = random.nextInt(this.serverList.size()); WS item = (WS) this.serverList.get(key); log.writeln("Selected server["+key+"] = "+ item.toString()); log.flush(); return item; } }

90

Classe RoundRobinPolicy package xsul.loadbalancer.lbpolicies; import java.util.ArrayList; import xsul.loadbalancer.FileLogger; import xsul.loadbalancer.routingtable.LoadBalancingWS; import xsul.dispatcher.routingtable.WS; /** * Selects server on a round-robin fashion. * Selecting <code>weight</code> times more each server. */ public class RoundRobinPolicy implements LBPolicy { private FileLogger log; private int lastSelected; private int[] countList; private int count; private ArrayList list; public RoundRobinPolicy() { log = new FileLogger("roundrobin.log");

log.start(); } public void init(ArrayList list) { this.lastSelected = -1; this.list = list; this.count = 0; this.countList = new int[this.list.size()]; for (int i = 0; i< this.countList.length; i++) { this.countList[i] = 0; } } public WS selectServer() { if ((lastSelected + 1) == this.list.size()) { lastSelected = 0; } else { lastSelected++; } WS item = (WS) this.list.get(lastSelected); if (countList[lastSelected] < ((LoadBalancingWS)item).getWeight()) { countList[lastSelected]++; count = 0; log.writeln("Selected server["+lastSelected+"] = "+ item.toString());

log.writeln("Weight: "+((LoadBalancingWS)item).getWeight()+" | Count:"+ countList[lastSelected]);

log.flush(); return item; } else { count++; if (count == this.list.size()) { for (int i = 0; i < this.countList.length; i++) { this.countList[i] = 0; } } return selectServer(); } } }

91

Classe SnmpInquirer package xsul.loadbalancer.lbpolicies; import snmp.*; import java.util.*; import java.net.*; /** * Collects informantion from a SNMP agent */ public class SnmpInquirer { protected String host; protected int version = 0; // SNMPv1 protected String community; protected String itemID; // OID protected ArrayList loadHashtable = new ArrayList(); protected Object returnedValue; public SnmpInquirer (String host, String community, int version){ this.host = host; this.community = community; this.version = version; } public SnmpInquirer (String host, String id){ this.host = host; this.community = "public"; this.version = 0; this.itemID = id; } public SnmpInquirer() { this.host = "127.0.0.1"; this.community = "public"; this.version = 0; this.setItemID("1.3.6.1.2.1.1.1.0"); } public Object getReturnedValue() { return this.returnedValue; } public void setItemID(String id){ this.itemID = id; } public void inquire() { try { InetAddress hostAddress = InetAddress.getByName(this.host); String community = this.community; int version = this.version; SNMPv1CommunicationInterface comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); SNMPVarBindList returned = comInterface.getMIBEntry(itemID); SNMPSequence pair = (SNMPSequence)(returned.getSNMPObjectAt(0)); SNMPObject snmpValue = pair.getSNMPObjectAt(1); // index ZERO: OID, this.returnedValue = (Object) snmpValue.getValue(); } catch(Exception e) { System.out.println("Exception during SNMP operation: " + e + "\n"); } } public static void main(String[] args){ SnmpInquirer inq = new SnmpInquirer(); inq.inquire(); } }

92

Classe HashMapThreadSafe package xsul.loadbalancer.lbpolicies; import java.util.HashMap; /** * Thread safe class for hash map */ class HashMapThreadSafe { HashMap lista = new HashMap(); public HashMapThreadSafe(int size) { new HashMap(size); }; public synchronized int size() { return lista.size(); }; public synchronized void put(Object arg0, Object arg1) { lista.put(arg0, arg1); }; public synchronized String toString() { return lista.toString(); }; public synchronized Object get(Object arg0) { return lista.get(arg0); }; } Classe LoadBalancingRoutingItem package xsul.loadbalancer.routingtable; import java.util.ArrayList; import xsul.loadbalancer.lbpolicies.LBPolicy; /** * An item of the LoadBalancingRoutingTable. * It has a virtual address (service name), a load balancing policy class and * the list of servers that implement the service. */ class LoadBalancingRoutingItem { public String service = null; public LBPolicy loadBPolicy = null; public ArrayList serverList = null;

public LoadBalancingRoutingItem(String service, String className, ArrayList list) throws Exception { this.service = service; this.serverList = list; String classPath = "xsul.loadbalancer.lbpolicies."+className; try { this.loadBPolicy = (LBPolicy) Class.forName(classPath).newInstance(); this.loadBPolicy.init(this.serverList); } catch (Exception e) { throw new Exception ("Couldn't load Load Balancing Policy class: " + classPath, e); } } } Classe LoadBalancingRoutingTable package xsul.loadbalancer.routingtable; import java.io.*; import java.net.*; import java.util.*; import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; import xsul.dispatcher.*; /** * An implementation of the RoutingTable interface. * Each item of the table is a LoadBalancingRoutingItem. * It has a virtual address (service name), a load balancing policy class and * the list of servers that implement the service. */ public class LoadBalancingRoutingTable implements RoutingTable { private ConcurrentReaderHashMap routingTable = null; public LoadBalancingRoutingTable(File data) { try { this.routingTable = new ConcurrentReaderHashMap(); this.fillTableWithFile(data); } catch (Exception e){ e.printStackTrace(); } } public LoadBalancingRoutingTable() { try {

93

this.routingTable = new ConcurrentReaderHashMap(); String tablefile = System.getProperty("table"); if (tablefile == null) { tablefile = LoadBalancingRoutingTable.class.getResource( "/xsul/loadbalancer/routingtable/loadbalancingtable.properties").getPath(); } File routingFile = new File(tablefile); this.fillTableWithFile(routingFile); } catch (Exception e){ e.printStackTrace(); } } private void fillTableWithFile(File data) throws Exception { Properties dataProps = new Properties(); FileInputStream in = null; try { in = new FileInputStream(data); dataProps.load(in); in.close(); } catch (FileNotFoundException e) { logger.finest("Couldn't find the default configuration file", e); } catch (IOException e) { logger.finest("Couldn't read the default configuration file", e); } String className = ""; Enumeration enumKey = dataProps.keys(); String log = ""; enumKey = dataProps.keys(); while (enumKey.hasMoreElements()) { String key = (String) enumKey.nextElement(); String[] classList = ((String) dataProps.get(key)).split("%"); if (classList.length < 2 || classList[0] == "") throw new Exception ("Please inform the load balacing class name and servers.\nConfig file sintax: \n[service]:[className]%[server1],[server2]"); className = classList[0]; String[] pathList = classList[1].split(","); int cont = 0; int weight; ArrayList elements = new ArrayList(); while (cont < pathList.length) { weight = 0; String pathWS = pathList[cont]; if (!pathWS.startsWith("http")) { pathWS = "http://" + pathWS; } WS element = new LoadBalancingWS(); try { if (pathWS.indexOf(" ") > 0) { String[] weightArr = pathWS.split(" "); pathWS = weightArr[0]; weight = Integer.parseInt(weightArr[1]); } URI wsUrl = new URI (pathWS); element.setHost(wsUrl.getHost()); int port = wsUrl.getPort(); if (port > 0) element.setPort(port); element.setPath(wsUrl.getPath()); element.setWsaElementTo(wsUrl); if (weight > 0) ((LoadBalancingWS) element).setWeight(weight); } catch (URISyntaxException e) { logger.warning("Couldn't create an URI", e); } elements.add(element); cont++; }

LoadBalancingRoutingItem item = new LoadBalancingRoutingItem(key, className, elements);

this.routingTable.put(key, item); }

} public Object get(String key) { try {

LoadBalancingRoutingItem item = (LoadBalancingRoutingItem) this.routingTable.get(key);

if (item == null) throw new NullPointerException();

94

WS selected = (WS) item.loadBPolicy.selectServer(); return selected; } catch (NullPointerException e) { return null; } }

public boolean contains(Object value) { return this.routingTable.contains(value);

} public void clear() { this.routingTable.clear(); } public boolean containsKey(String key) { return this.routingTable.containsKey(key); } public boolean containsKey(URI key) { return this.routingTable.containsKey(key); } public boolean containsValue(Object value) { return this.routingTable.containsValue(value); } public Enumeration elements() { return this.routingTable.elements(); } public Object get(URI Key) { try {

LoadBalancingRoutingItem item = (LoadBalancingRoutingItem) this.routingTable.get(Key);

if (item == null) throw new NullPointerException(); return (WS) item.loadBPolicy.selectServer(); } catch (NullPointerException e) { return null; } } public boolean isEmpty() { return this.routingTable.isEmpty(); } public Object put(String key, Object value) { return (LoadBalancingRoutingItem) this.routingTable.put(key, value); } public Object put(URI key, Object value) { return (LoadBalancingRoutingItem) this.routingTable.put(key, value); } public void putAll(LoadBalancingRoutingTable t) { this.routingTable.putAll(t.getTable()); }

public void putAll(RoutingTable t) { this.routingTable.putAll(t.getTable());

} public Map getTable() {

return this.routingTable; }

public Object remove(String key) { return (LoadBalancingRoutingItem) this.routingTable.remove(key); } public Object remove(URI key) { return (LoadBalancingRoutingItem) this.routingTable.remove(key); } public int size() { return this.routingTable.size(); } } Arquivo de Configuração # service=class%host:port/path,host:port/path,host:port/path... translator=RandomPolicy%localhost:7580/axis/services/WSATranslator 3,localhost:4580/axis/services/WSATranslator,localhost:5580/axis/services/WSATranslator

95

Classe LoadBalancingWS package xsul.loadbalancer.routingtable; import java.net.URI; import xsul.loadbalancer.msg.LBDispatcherMSG; import xsul.loadbalancer.msg.wsconnection.LBMSGWSConnection; import xsul.dispatcher.routingtable.WS; import xsul.ws_addressing.WsaEndpointReference; /** * This class represents a server that implements the service. * Contains all information for connecting and forwarding requests to a WS in a server. */ public class LoadBalancingWS extends WS {

private String host; private int port; private String path; private int weight; private LBMSGWSConnection connection = null; private URI wsaTo; private WsaEndpointReference wsaReplyTo; private WsaEndpointReference wsaFaultTo;

public LoadBalancingWS() {

this.host = "localhost"; this.port = 80; this.path = "/"; this.weight = 1;

} public LoadBalancingWS(String host, int port, String path, int weight) {

this.host = host; this.port = port; this.path = path; this.weight = weight;

} public int getWeight() {

return weight; } public void setWeight(int weight) {

this.weight = weight; } public LBMSGWSConnection getLBMsgConnection() {

if (this.connection == null) { this.connection = new LBMSGWSConnection(this);

} if (this.connection.isKeepAlive()) {

return this.connection; } else {

try { LBMSGWSConnection conn = ((LoadBalancingWS)this).connection; LBDispatcherMSG.poolWSConnections.execute(conn);

return conn; } catch (InterruptedException e) {

logger.warning("Couldn't start a thread", e); return null;

} }

} }

96

Class ClientConnection package xsul.loadbalancer.rpc.clientconnection; import xsul.loadbalancer.*; import xsul.dispatcher.*; import xsul.http_server.*; /** * Looking in the Routing Table for find the real Web Service which match the * virtual path from the client's request. * @author Alexandre di Costanzo * @author Sabrina: this class had to use load balancing implementations of * ServletClientConnection and RPCWSConnection */ class ClientConnection {

public ClientConnection() { } public void service(HttpServerRequest req, HttpServerResponse resp) throws

HttpServerException { String path = req.getPath(); if (path == null) {

SendError.send(resp, "404", "Web Services not found on this server"); } else {

if (path.startsWith("/")) { path = path.substring(1);

} String method = req.getMethod(); String arguments = null; if (method.equals("GET")) {

int argStart = path.indexOf('?'); if (argStart != -1) {

arguments = path.substring(argStart, path.length()); path = path.replaceAll("\\?.*", "");

} } if (path.endsWith("/")) {

path = path.substring(0, path.length()-1); } WS wsHttp = (WS) ServletClientConnection.routingTable.get(path); if (wsHttp == null) {

SendError.send(resp, "404", "Web Services not found on this server"); } else {

RPCWSConnection connection = new RPCWSConnection(wsHttp); connection.forwards(new Object[] { req, resp, arguments });

} }

} } Classe ServletClientConnection package xsul.loadbalancer.rpc.clientconnection; import xsul.dispatcher.routingtable.RoutingTable; import xsul.http_server.*; /** * This servlet serves request from client. The service is to forward the request to * the good Web Service. * @author Alexandre di Costanzo * @author Sabrina: this class could not be reused because ClientConnection does not have * access to routingTable:WS wsHttp = (WS) ServletClientConnection.routingTable.get(path); */ public class ServletClientConnection extends HttpMiniServlet {

protected static RoutingTable routingTable;

public ServletClientConnection(RoutingTable routingTable) { super(); ServletClientConnection.routingTable = routingTable;

} public void service(HttpServerRequest req, HttpServerResponse resp) throws

HttpServerException { ClientConnection client = new ClientConnection(); client.service(req, resp);

} }

97

Classe RPCWSConnection package xsul.loadbalancer.rpc.wsconnection; import java.io.*; import xsul.dispatcher.*; import xsul.loadbalancer.rpc.DispatcherRPC; import xsul.http_client.*; import xsul.http_server.*; import xsul.ws_addressing.WsaMessageInformationHeaders; import xsul.XmlConstants; import org.xmlpull.v1.builder.*; /** * @author Alexandre di Costanzo * @author Sabrina: set the WS-Addressing header TO to the selected server * and set the SOAPAction HTTP header. */ public class RPCWSConnection extends WSConnection {

private final static XmlInfosetBuilder builder = XmlConstants.BUILDER; private HttpClientRequest fwdRequest; private HttpClientConnectionManager cx = null; private WS wsHttp;

public RPCWSConnection(WS wsHttp) {

this.wsHttp = wsHttp; if (cx == null) cx = HttpClientReuseLastConnectionManager.newInstance();

} public void forwards(Object[] request) {

this.fwdRequest = cx.connect(this.wsHttp.getHost(), this.wsHttp.getPort(), Integer.parseInt(DispatcherRPC.CONFIGURATION.getProperty("webservices.timeout")));

HttpServerRequest req = (HttpServerRequest) request[0]; HttpServerResponse resp = (HttpServerResponse) request[1]; String arguments = (String) request[2]; XmlElement el = builder.parseFragmentFromInputStream(req.getInputStream()); XmlElement outMessage = null; try { outMessage = (XmlElement) el.clone(); } catch (CloneNotSupportedException e) { SendError.sendWSAFault("Couldn't clone the message", null, soapUtil, fault); return; }

WsaMessageInformationHeaders outHeaders = new WsaMessageInformationHeaders(outMessage);

outHeaders.setTo(wsHttp.getWsaElementTo()); String wsPath = this.wsHttp.getPath(); if (arguments != null) {

wsPath += arguments; } this.fwdRequest.setRequestLine(req.getMethod(), wsPath, "HTTP/1.0"); this.fwdRequest.setRequestLine("POST", wsPath, "HTTP/1.0");

this.fwdRequest.setHeader("SOAPAction", req.getHeader("SOAPAction")); this.fwdRequest.setContentType(req.getContentType()); builder.serializeToOutputStream(outMessage, this.fwdRequest.getBodyOutputStream());

HttpClientResponse wsResp = this.fwdRequest.sendHeaders(); try {

InputStream inReq = req.getInputStream(); OutputStream outToWs = fwdRequest.getBodyOutputStream(); this.copy(inReq, outToWs);

} catch (IOException e) { SendError.send(resp, "500", "Couldn't communicate with the Web service");

return; } wsResp.readStatusLine(); wsResp.readHeaders(); resp.setContentType(wsResp.getContentType()); resp.setReasonPhrase(wsResp.getReasonPhrase()); resp.setStatusCode(wsResp.getStatusCode()); OutputStream outResp = resp.getOutputStream(); InputStream inResp = wsResp.getBodyInputStream(); try {

this.copy(inResp, outResp); } catch (IOException e) { }

} }

98

Classe DispatcherRPC package xsul.loadbalancer.rpc; import java.io.* import java.util.Properties; import xsul.dispatcher.routingtable.RoutingTable; import xsul.loadbalancer.*; import xsul.http_server.*; /** * The main class to start the RPC Dispatcher. * @author Alexandre di Costanzo * @author Sabrina: this class instantiates DispatcherRPC with load balancer properties * and load balancing routing table */ public class DispatcherRPC {

private final static String DEFAULT_CONF_FILE_PATH = DispatcherRPC.class.getResource("/xsul/loadbalancer/rpc/default.properties").getPath();

public static Properties CONFIGURATION; private HttpMiniServer httpServer; private static HttpMiniServlet poolServlet; private static RoutingTable routingTable;

private DispatcherRPC() {

int port = Integer.parseInt(CONFIGURATION.getProperty("server.port")); this.httpServer = new HttpMiniServer(port); routingTable = new LoadBalancingRoutingTable(); poolServlet = new ServletClientConnection(routingTable); this.httpServer.useServlet(poolServlet);

} public static void main(String[] args) {

DispatcherRPC.loadConfiguration(); DispatcherRPC gateway = new DispatcherRPC(); gateway.start();

} private void start() {

this.httpServer.startServer(); } private static void loadConfiguration() {

Properties props = new Properties(); FileInputStream in = null; try {

String configfile = System.getProperty("config"); if (configfile == null) {

configfile = DEFAULT_CONF_FILE_PATH; } in = new FileInputStream(configfile); props.load(in); in.close();

} catch (FileNotFoundException e) { logger.finest("Couldn't found the configuration file", e);

} catch (IOException e) { logger.finest("Couldn't read the configuration file", e);

} CONFIGURATION = new Properties(props);

} }

99

Classe FileLogger package xsul.loadbalancer; import java.io.*; public class FileLogger {

private String logFileName = null; private PrintWriter pw = null; public void writeln (String s) {

pw.println(s); } public void start() {

try { if (logFileName.indexOf(".") != -1) {

logFileName = logFileName.substring(0, logFileName.indexOf(".")) + "_" + startTime.getTime() + logFileName.substring(logFileName.indexOf("."), logFileName.length());

} else {

logFileName += "_"+startTime.toString()+".log"; } pw = new PrintWriter(new FileWriter(logFileName));

} catch (IOException ioe) { ioe.printStackTrace();

} } public void flush() {

pw.flush(); }

public FileLogger (String logFileName) { this.logFileName = logFileName;

} } Classe BalancedAddressHandler package org.apache.ws.addressing.handler; import org.apache.*; import javax.xml.rpc.*; import javax.xml.soap.SOAPMessage; /** * This class is a WS-Addressing SOAP Handler. * This class rewrites the from, reply to and faulto WS-Addressing * headers with the value: DISPATCHER_URI. * It rewrites reply and fault messages. */ public class BalancedAddressHandler extends AxisServerSideAddressingHandler { private final static String DISPATCHER_URI = "http://localhost:9080/translator"; private final static String SERVER_ID = "0"; public BalancedAddressHandler() { super(); } public boolean handleResponse( MessageContext msgContext ) { SOAPMessageContext soapMsgContext = (SOAPMessageContext) msgContext; try { SOAPMessage msg = soapMsgContext.getMessage(); if (msg == null) { return CONTINUE_HANDLER_CHAIN_PROCESSING; }

AddressingHeaders reqHeaders = (AddressingHeaders) msgContext.getProperty( Constants.ENV_ADDRESSING_REQUEST_HEADERS );

if (reqHeaders == null) { return CONTINUE_HANDLER_CHAIN_PROCESSING; } AddressingHeaders resHeaders = AddressingUtils.getResponseHeaders( msgContext );

setRefProps(resHeaders); resHeaders.setSetMustUnderstand( isMustUnderstandEnabled(msgContext)); processFromHeader( reqHeaders, resHeaders ); processActionHeader( reqHeaders, resHeaders ); processToHeader( reqHeaders, resHeaders ); processRelatesToHeader( reqHeaders, resHeaders ); processMessageIdHeader( resHeaders ); setFromHeader(resHeaders); setReplyToHeader(resHeaders); setFaultToHeader(resHeaders);

100

resHeaders.toEnvelope( msg.getSOAPPart().getEnvelope(), getActor() ); processReplyToHeader( reqHeaders, soapMsgContext ); } catch ( Exception e ) { throw new JAXRPCException( "unexpected error in handleResponse()", e ); } return CONTINUE_HANDLER_CHAIN_PROCESSING; } public boolean handleFault( MessageContext msgContext ) { SOAPMessageContext soapMsgContext = (SOAPMessageContext) msgContext; try {

AddressingHeaders reqHeaders = (AddressingHeaders) msgContext.getProperty( Constants.ENV_ADDRESSING_REQUEST_HEADERS );

if ( reqHeaders == null ) { return CONTINUE_HANDLER_CHAIN_PROCESSING; } AddressingHeaders resHeaders = AddressingUtils.getResponseHeaders( msgContext );

reqHeaders, resHeaders ); setRefProps(resHeaders);

resHeaders.setAction( new Action( new URI( AddressingUtils.getFaultActionURI() ) ) );

addRelatesToHeader( reqHeaders, resHeaders ); addMessageIdHeader( resHeaders ); setFromHeader(resHeaders); setReplyToHeader(resHeaders); setFaultToHeader(resHeaders); addAddressingHeadersToSOAPEnvelope( soapMsgContext, resHeaders ); processFaultToHeader( reqHeaders, soapMsgContext ); } catch ( Exception e ) { throw new JAXRPCException( "unexpected error in handleFault()", e ); } return CONTINUE_HANDLER_CHAIN_PROCESSING; } private void processActionHeader( AddressingHeaders requestAddrHeaders, AddressingHeaders responseAddrHeaders ) throws URI.MalformedURIException { Action action = responseAddrHeaders.getAction(); if ( action == null ) { action = requestAddrHeaders.getAction(); if ( action != null ) { responseAddrHeaders.setAction( new Action( new URI( action.toString() + "Response" ) ) ); } } } private void processToHeader( AddressingHeaders requestAddrHeaders, AddressingHeaders responseAddrHeaders ) throws URI.MalformedURIException { if ( responseAddrHeaders.getFrom() == null && requestAddrHeaders.getFrom() != null ) { responseAddrHeaders.setTo( requestAddrHeaders.getFrom().getAddress() ); } else { responseAddrHeaders.setTo( new To( AddressingUtils.getAnonymousRoleURI() ) ); } } private void addRelatesToHeader( AddressingHeaders reqHeaders, AddressingHeaders resHeaders ) throws URI.MalformedURIException { MessageID msgID = reqHeaders.getMessageID(); if ( msgID != null ) {

resHeaders.addRelatesTo( msgID.toString(), AddressingUtils.getResponseRelationshipType() );

} } private void processFaultToHeader( AddressingHeaders reqHeaders, SOAPMessageContext soapMsgContext ) throws Exception { EndpointReference faultTo = reqHeaders.getFaultTo();

if ( faultTo != null ) { AttributedURI address = faultTo.getAddress(); if ( address != null && address.toString() != null ) {

forwardMessage( soapMsgContext, faultTo ); }

} } private void addAddressingHeadersToSOAPEnvelope( SOAPMessageContext soapMsgContext, AddressingHeaders resHeaders ) throws Exception {

SOAPMessage msg = soapMsgContext.getMessage(); if ( msg == null ) {

throw new JAXRPCException( "Unable to obtain response message from SOAP message context." );

101

} resHeaders.toEnvelope( msg.getSOAPPart().getEnvelope() ); }

private void addMessageIdHeader( AddressingHeaders resHeaders ) throws URI.MalformedURIException { MessageID msgID = new MessageID( new URI( "uuid:" + generateUUId() ) ); resHeaders.setMessageID( msgID ); } private void processFromHeader( AddressingHeaders requestAddrHeaders, AddressingHeaders responseAddrHeaders ) { EndpointReference fromEPR = responseAddrHeaders.getFrom(); if ( fromEPR == null ){ To toURI = requestAddrHeaders.getTo(); if ( toURI != null ) { fromEPR = new EndpointReference( toURI ); fromEPR.setProperties( requestAddrHeaders.getReferenceProperties() ); responseAddrHeaders.setFrom( fromEPR ); } } } private void processReplyToHeader( AddressingHeaders requestAddrHeaders, SOAPMessageContext soapMsgContext ) throws Exception { EndpointReference replyTo = requestAddrHeaders.getReplyTo(); if ( replyTo != null ) { AttributedURI address = replyTo.getAddress(); if ( address != null ) { String uri = address.toString(); if ( uri != null && !uri.equals( AddressingUtils.getAnonymousRoleURI() ) ) { forwardMessage( soapMsgContext, replyTo ); } } } }

private void processRelatesToHeader( AddressingHeaders requestAddrHeaders, AddressingHeaders responseAddrHeaders ) throws URI.MalformedURIException { MessageID msgID = requestAddrHeaders.getMessageID(); if ( msgID != null ) {

responseAddrHeaders.addRelatesTo( msgID.toString(), AddressingUtils.getResponseRelationshipType() );

} } private void processMessageIdHeader( AddressingHeaders responseAddrHeaders ) throws URI.MalformedURIException { responseAddrHeaders.setMessageID( createMessageID() ); } private void setReplyToHeader(AddressingHeaders responseAddrHeaders) throws Exception { responseAddrHeaders.setReplyTo(new EndpointReference(new URI(DISPATCHER_URI))); } private void setFromHeader(AddressingHeaders responseAddrHeaders) throws Exception { responseAddrHeaders.setFrom(new EndpointReference(new URI(DISPATCHER_URI))); } private void setFaultToHeader(AddressingHeaders responseAddrHeaders) throws Exception { responseAddrHeaders.setFaultTo(new EndpointReference(new URI(DISPATCHER_URI))); } private void setRefProps(AddressingHeaders responseAddrHeaders) throws Exception { MessageElement el = new MessageElement(); ReferencePropertiesType ref = new ReferencePropertiesType(); el.setName("server"); el.setValue(SERVER_ID); ref.add(el); responseAddrHeaders.setReferenceProperties(ref); } }

102

APÊNDICE B – ARTIGO

Balanceamento de Carga em Web Services

Sabrina Leandro1

1Departamento de Informática e Estatística Universidade Federal de Santa Catarina (UFSC) – Florianópolis, SC – Brasil.

[email protected]

Abstract. Companies need to interconnect business processes with clients and partners. The Web Services are a way to facilitate the interconnection between the applications that implement these business processes, because they provide loose coupling and platform independence. However, this technology possesses proven performance problems, specially because it uses XML. In this dissertation, a mechanism to balance load between different servers that provide the same service is proposed, so that the performance of the Web service is improved. The proposed mechanism uses a dispatcher as the load balancing entity. It forwards messages to the selected replica of a service, using a Web services addressing protocol. The proposed mechanism was implemented as well as load balancing algorithms, that can be chosen based on the characteristics of the service and the servers in which it is deployed.

Resumo. Empresas precisam interligar processos de negócio com parceiros e clientes. Os Web Services surgem para facilitar a interligação entre as aplicações que implementam esses processos de negócio, pois apresentam características como fraco acoplamento e independência de plataforma. Entretanto, essa tecnologia possui problemas de desempenho comprovados, especialmente pelo uso de XML. Este trabalho propõe um mecanismo para balanceamento de carga entre diferentes servidores disponibilizando um mesmo serviço, visando a melhoraria do seu desempenho. O mecanismo proposto usa uma abordagem de balanceamento de carga baseada em despachante. Este encaminha as mensagens a uma das réplicas de um serviço, usando um protocolo de endereçamento para serviços Web. O mecanismo proposto foi implementado, assim como algoritmos de balanceamento de carga, que podem ser usados de acordo com as características do serviço e dos servidores que o implementam.

1. Introdução

Atualmente, empresas e instituições sentem cada vez mais a necessidade de interligar processos de negócio e trocar informações com fornecedores, clientes e parceiros. Essa cooperação necessita que a conexão entre sistemas, que implementam esses processos de

103

negócio, seja fácil e flexível, para que as empresas possam responder de forma rápida e eficiente às exigências de clientes, mudanças de mercados ou ameaças da concorrência.

A arquitetura Web Services facilita a conexão e comunicação entre sistemas heterogêneos porque oferece interoperabilidade e fraco acoplamento. Por ser baseada em padrões abertos, ela é independente de plataformas ou sistemas operacionais. Essas características possibilitam a fácil integração de sistemas, tornando-a uma solução ideal para integração e comunicação entre aplicações. Mas para que seu uso comercial se torne corrente, é importante que se tenha uma infra-estrutura confiável para seu desenvolvimento e implantação.

O desempenho dos serviços Web é um problema comprovado [Tian 2003]. O principal padrão usado nas especificações Web services é o XML, uma linguagem de marcação baseada em texto, que permite a independência de plataforma e flexibilidade. Apesar de ser um dos fatores de sucesso da arquitetura Web Services, o uso de XML tem uma desvantagem: por ser baseado em texto, seu processamento é lento e impõe uma sobrecarga adicional no servidor. Esse fator está entre os que mais influenciam no desempenho de serviços Web, principalmente a sua análise sintática e transformação das mensagens SOAP [Bustamante 2000]. Além disso, as tags de marcação, que funcionam como metadados, aumentam o tamanho da mensagem. Por isso, é necessário um cuidado especial com o desempenho de sistemas que utilizam Web services.

Não existe ainda uma solução padrão para melhorar o desempenho de aplicações que utilizam serviços Web. Alguns autores já apontam soluções paliativas [Govindaraju et al 2004] [Kohlhoff e Steele 2003] [Cohen 2003] [Harbaugh 2002]. Entretanto, o ideal é que um serviço Web escolha suas características baseado na sua funcionalidade e não em possíveis problemas de desempenho. Nesse contexto, tem-se o balanceamento de carga como um mecanismo e uma solução para aumentar o desempenho dessas aplicações.

Este trabalho tem como objetivo estudar maneiras de distribuir a carga, ou seja, as requisições recebidas através de uma rede de computadores, entre Web services replicados em diferentes máquinas. O estudo teve o propósito de determinar e propor um mecanismo de balanceamento de carga em Serviços Web, que foi implementado e testado.

2. Organização do Texto

Este artigo está organizado da seguinte maneira. As seções 3, 4 e 5 tratam da revisão bibliográfica, com ênfase em Serviços Web e sua especificação de endereçamento. Na seção 6, o mecanismo de balanceamento de carga proposto é detalhado, bem como a sua implementação. Na seção 7, são mostrados resultados de testes comparativos dos algoritmos de balanceamento de carga implementados. Por último, na seção 8 são feitas conclusões e apontadas sugestões para trabalhos futuros.

3. Balanceamento de Carga

Um sistema distribuído é um conjunto de agentes de software que estão em ambientes de processamento diferentes e devem cooperar para realizar alguma tarefa. Por exemplo, uma aplicação consumidora acessando um serviço Web. Por ser feita através de uma rede, a

104

comunicação em um sistema distribuído é mais lenta e menos confiável se comparada à invocação direta de código e memória compartilhada. Isso acarreta implicações importantes na arquitetura desses sistemas. Entre os requisitos que um sistema distribuído deve apresentar para prover uma funcionalidade completa está o desempenho. O desempenho é medido em termos de vazão e latência. A vazão (throughput) representa o número de requisições servidas durante um período de tempo e a latência, ou tempo de resposta, é o tempo entre o envio de uma requisição e o recebimento da resposta.

Balanceamento de carga (load balancing) é um mecanismo usado para atingir escalabilidade e melhorar o desempenho de sistemas distribuídos através da redistribuição de carga entre os elementos de processamento em um conjunto de servidores que implementam um mesmo serviço. A distribuição das requisições baseada em algoritmos de balanceamento de carga permite melhorar o desempenho, aumentar a disponibilidade e diminuir o tempo de resposta. Como vários servidores podem processar os pedidos, deve haver uma política que distribua a carga recebida de maneira uniforme e eficiente para todos esses servidores, não sobrecarregando um deles enquanto outro está disponível.

4. Web Services

Um serviço é uma abstração de um conjunto de operações, com uma funcionalidade em comum, oferecido a consumidores. Um Web service é um serviço disponível na Web que pode ser descrito, publicado, localizado e chamado através de protocolos padrões da Internet usando mensagens no formato XML [Systnet 2002].

A tecnologia Web Services é uma implementação da Arquitetura Orientada a Serviços (Service-oriented Architecture, ou SOA). Essa arquitetura tem o objetivo de alcançar o fraco acoplamento entre agentes de software que realizam uma interação. Utilizar serviços Web na sua implementação permite interoperabilidade entre diferentes plataformas através do uso de padrões abertos, ou seja, padrões que podem ser implementados por qualquer fabricante.

Os três papéis básicos desempenhados por sistemas em uma arquitetura SOA são: provedor, consumidor e broker (ou intermediador). Um provedor de serviço o torna disponível e publica o contrato que descreve sua interface através de um registro no broker. Um consumidor pesquisa no broker os serviços que deseja. Este fornece ao consumidor informações de localização e de contrato do serviço, que são usadas para ligar (bind) o consumidor ao serviço. Para que essa dinâmica seja possível, um sistema SOA deve prover três componentes de arquitetura [Systnet 2002]:

• Transporte: representa os formatos e protocolos usados para comunicação com um serviço

• Descrição: representa as linguagens usadas para descrever um serviço, provendo as informações necessárias para acessá-lo, as operações que ele realiza e quais são seus parâmetros.

• Descobrimento: representa os mecanismos usados para registrar, anunciar e encontrar um serviço e sua descrição.

105

Nos Serviços Web, existem especificações para cada um desses componentes, chamadas SOAP [SOAP], WSDL [Christensen et al 2001] e UDDI [UDDI], respectivamente. A interface de um serviço Web é descrita utilizando-se o protocolo WSDL. Essa descrição pode ser publicada em um registro UDDI, no qual consumidores pesquisam os serviços que desejam acessar. Ela também especifica o local no qual o serviço pode ser acessado e qual deve ser o formato das mensagens trocadas. Assim, consumidores e serviços utilizam o protocolo SOAP para enviar e receber mensagens.

Figura 1 – Arquitetura SOA e protocolos Web Services.

5. Web Services Addressing

Apesar do seu foco na neutralidade, atualmente o SOAP ainda não provia um mecanismo para referenciar e enviar mensagens sem a ajuda de um protocolo de transporte. A informação sobre fonte e destino não faz parte da mensagem SOAP, assim, ela pode ser perdida se uma conexão de transporte é terminada ou se a mensagem é re-encaminhada por um intermediário. Com o surgimento de aplicações mais sofisticadas, notou-se a importância do uso de diferentes protocolos de transporte e que, para isso, era necessário especificar informações de transporte de modo neutro nas próprias mensagens SOAP. Além disso, quando se quer que uma mensagem seja especificada diretamente a um elemento ou recurso dentro de um serviço, o simples uso da URL para indicar um endereço de destino não é suficiente.

Para solucionar esses problemas foi criada a especificação WS-Addressing (WS-A) [WS-Addressing 2004], que define mecanismos para referência e endereçamento de serviços Web. Ela fornece uma abordagem interoperável e independente de transporte para identificar uma mensagem, bem como uma abordagem mais detalhada para identificar um endpoint de um serviço. Por endpoint entende-se uma entidade para onde mensagens podem ser direcionadas, ou seja, um ponto de acesso a um serviço.

Na especificação WS-Addressing são definidas duas construções que transportam informações tipicamente fornecidas por protocolos de transporte: "endpoint references" e "message information headers".

Consumidor do Serviço

Provedor do Serviço

Intermediário do Serviço

(Broker)

Busca <UDDI>

Registra <UDDI>

Cliente Serviço

Descrição

Ligação <SOAP>

106

Uma endpoint reference é um mecanismo leve e extensível para referenciar e descrever dinamicamente endpoints, ou seja, ela descreve um lugar na rede que pode receber mensagens SOAP. Essa referência possui maior nível de detalhe, se comparada a um simples URI, permitindo que outras informações, como identificador de mensagem, informações de sessão, ou mesmo informações específicas da aplicação, sejam adicionadas ao endereço URI, para, assim, melhor encaminhar a mensagem.

Os cabeçalhos de informações da mensagem, ou message information headers, adicionam propriedades abstratas à mensagem, que permitem o endereçamento a endpoints envolvidos em uma interação, podendo especificar para quem a mensagem está sendo enviada (To), qual ação a ser tomada (action), para quem deve ser enviada a resposta (replyTo), entre outros.

Tabela 1: Construções Message Information Headers – WS-Addressing.

Message Information Headers Descrição do Cabeçalho

To URL alvo do serviço Web.

From A endpoint reference do remetente da mensagem.

ReplyTo

A endpoint reference a quem se deve enviar a resposta.

FaultTo A endpoint reference a quem se deve enviar a mensagem de falha, se esta houver.

MessageID

Um URI que identifica unicamente uma mensagem.

Action A ação que deve ser executada quando o serviço recebe a mensagem.

RelatesTo Determina o relacionamento entre mensagens.

A especificação de um protocolo de endereçamento para Web Services permite a realização de distribuição de carga voltada especialmente para esse tipo de arquitetura, podendo adaptar-se melhor as suas características. O fato do protocolo WS-Addressing estar em processo de se tornar um padrão World Wide Web Consortium (W3C) [Charter] garante a sua implementação na grande maioria das plataformas de desenvolvimento Web Services.

6. Balanceamento de Carga em Web Services

Neste trabalho pretende-se melhorar o desempenho de serviços Web através do uso de um mecanismo de distribuição de carga. A abordagem proposta para melhorar o desempenho de serviços Web é o uso do balanceamento de carga entre diferentes servidores que disponibilizam um mesmo serviço. As requisições balanceadas são as mensagens enviadas pelos consumidores do serviço.

Para isso, foi escolhida a abordagem de balanceamento de carga baseada em despachante em um conjunto de servidores Web. A máquina despachante é um endpoint de serviços que encaminha as mensagens que chegam para um dos diversos servidores

107

disponíveis, baseado em uma política de distribuição. Os servidores podem estar agrupados em um cluster, facilitando a comunicação com o despachante. Mas, com o intuito de oferecer uma proposta mais flexível, essa característica não é obrigatória.

O uso de despachante possibilita fraco acoplamento e flexibilidade, por interceptar a ligação direta entre o provedor e o consumidor. Esse tipo de abordagem permite, além do balanceamento de carga, a possibilidade de realizar roteamento baseado em conteúdo ou regras, de filtrar o conteúdo e a possibilidade de oferecer tolerância a possíveis falhas nos provedores do serviço. Uma grande desvantagem no uso de despachante, é que ele é um ponto de falha único, se o despachante falhar, nenhuma requisição será respondida. A solução para esse problema é manter uma ou mais réplicas do despachante, com as mesmas configurações deste, que serão utilizadas em caso de falha.

Escolheu-se a especificação WS-Addressing para realizar o endereçamento e encaminhamento das mensagens dos consumidores ao despachante, deste aos servidores e destes aos consumidores. A principal razão é o fato de ela ser uma especificação Web Services, desenvolvida especialmente para esse tipo de arquitetura. Além disso, com a criação de um Grupo de Trabalho no W3C que produzirá uma W3C Recommendation para a especificação, é esperado que em janeiro de 2006 ela se torne um padrão de fato para Serviços Web.

O encaminhamento das mensagens pelo despachante será feito pela edição dos cabeçalhos WS-Addressing das mensagens SOAP. Uma mensagem para um serviço será endereçada com o endpoint do despachante (elemento to). Este irá selecionar o servidor apropriado e re-encaminhar a mensagem, reescrevendo o elemento to do cabeçalho SOAP com o endereço do servidor escolhido. Para diminuir a carga de processamento no despachante, foi decidido que este apenas encaminha as mensagens para o servidor escolhido, ficando o próprio servidor incumbido de enviar a resposta. Para isso, ele altera os elementos from, replyTo e faultTo da mensagem de resposta ou falha, se esta houver, para que contenham o endpoint do despachante, assim, as mensagens podem ser respondidas diretamente pelo servidor. O servidor encaminhará a mensagem para o endpoint indicado no cabeçalho replyTo da mensagem de requisição, que comumente é o endereço do consumidor do serviço. Entretanto, se esse endereço não for determinado pelo consumidor, a resposta será enviada para o endereço indicado no protocolo de transporte.

Para que o gerenciamento de sessão de consumidores seja feito pelos servidores, é necessária uma característica chamada afinidade de servidor, ou server affinity. Esse termo é usado para designar a capacidade de um sistema de balanceamento de carga em manter as informações de sessão de um usuário em suas várias requisições.

A solução apresentada neste trabalho pode permitir essa característica se, em uma mesma sessão, o consumidor for redirecionado sempre para o mesmo servidor. O uso de um parâmetro de referência (reference parameter) que identifique o servidor escolhido para o cliente implementa essa proposta. Um parâmetro de referência é uma das informações que podem estar presentes em uma endpoint reference. Nessa possível solução, quando uma requisição chegaria ao despachante, este selecionaria um servidor para respondê-la, baseado no algoritmo escolhido. Então, o despachante criaria a mensagem a ser direcionada a este

108

servidor, colocando no seu cabeçalho um reference parameter indicando o servidor escolhido. A resposta do consumidor chegaria com esta informação no cabeçalho. Como descrito na especificação WS-Addressing, os cabeçalhos reference parameter são transparentes ao consumidor, ou seja, este somente deve replicar esses cabeçalhos na sua próxima requisição. Assim, o despachante saberia que um servidor já teria sido escolhido para aquele consumidor, direcionando para o servidor indicado no cabeçalho da requisição.

Essa solução, além de garantir a afinidade de servidor, seleciona um servidor por sessão, diminuindo a carga no despachante. Entretanto, foi escolhido como proposta final deste trabalho fazer a seleção do servidor a cada mensagem que chega do consumidor. Considerou-se mais importante refletir melhor a carga atual do sistema. Para manter a afinidade de servidor nessa solução, poderia ser utilizado um banco de dados distribuído acessado por todos servidores para manter as informações de estado.

Um algoritmo que implementa uma política de balanceamento de carga deve ser escolhido de modo a não deteriorar ainda mais o desempenho do serviço. O uso de despachante introduz mais uma entidade entre o consumidor e o provedor, por isso, se ele não for bem planejado e implementado, pode trazer mais problemas do que soluções. Neste trabalho, foram implementados quatro algoritmos que implementam políticas de distribuição de requisições no despachante:

• Randômico: a cada requisição, um servidor é escolhido aleatoriamente. Existe uma pequena probabilidade de, em um pequeno número de requisições, a carga não ser distribuída igualmente entre os servidores. Entretanto, em média, a carga é distribuída igualmente. É um algoritmo simples e recomendado em sistemas de servidores homogêneos, ou seja, nos quais todos têm a mesma capacidade. Uma desvantagem encontra-se no pequeno custo de processamento na geração do número randômico para cada requisição e na não consideração de informações sobre o estado atual dos servidores – por exemplo, a carga e o número de conexões ativas em um determinado momento ou mesmo se ocorreu falha no servidor.

• Round-robin: neste algoritmo, o primeiro servidor escolhido é o que foi definido em primeiro lugar nas configurações do despachante. Os próximos servidores serão escolhidos em ordem circular. Possui uma lógica simples e previsível e as requisições são distribuídas igualmente entre os servidores. Como trata todos os servidores da mesma maneira, é ideal para conjunto de servidores homogêneos. Entretanto, esse algoritmo também não considera informações sobre o estados dos servidores.

• Round-robin com pesos: igual ao algoritmo anterior, sendo que agora são consideradas as diferenças entre os servidores, através de pesos atribuídos na configuração. Cada servidor possui um peso, que declara qual porção das requisições vai ser direcionada a ele. Servidores com peso maior recebem um maior número de requisições. É importante que os pesos dos servidores sejam determinados com precisão, para melhor aproveitamento do algoritmo. Por exemplo, realização de testes de carga para verificar o comportamento dos servidores ao receber um grande número de requisições, e, a partir daí, determinar qual carga cada servidor consegue consumir de maneira correta. Esse algoritmo torna possível utilizar Round-robin em

109

conjunto de servidores heterogêneos, mas ainda não considera informações sobre o estado dos servidores.

• Menor carga: o servidor com a menor carga tem maior probabilidade de ser selecionado para receber as requisições. O despachante possui um processo, executado em paralelo, para cada servidor, que pergunta, em intervalos de tempo, qual a carga disponível no servidor. Ao selecionar um servidor, essas informações são consideradas, dando maior probabilidade de um servidor com menor carga ser escolhido. Não significando que sempre o servidor com menor carga será selecionado, para evitar que esse servidor seja sobrecarregado. Para isso, um número randômico é gerado, levando-se em conta o total de carga disponível dos servidores. A probabilidade de um servidor ser sorteado é o seu valor de carga disponível. Para o servidor i ser selecionado, o número sorteado tem que estar entre o somatório das cargas disponíveis de C(i-1) a C(i-1) e Ci. Por esse algoritmo considerar informações dos servidores, o despachante pode verificar se um servidor está indisponível se este não responder à sua solicitação das informações de carga. Como desvantagem, é um algoritmo mais complexo, exigindo comunicação entre os servidores e o despachante para troca de informações sobre seus estados.

A implementação deste trabalho consiste em duas partes: o serviço provido e implantado nos servidores e o despachante, chamado WS-LoadBalancer. A funcionalidade escolhida para o serviço de teste é bem simples: um serviço de tradução, que recebe um texto para ser traduzido, informando também de qual e para qual língua a tradução deve ser feita. A simplicidade do serviço facilita na comparação de desempenho do despachante usando os diferentes algoritmos.

Figura 2 – Três clientes acessando um serviço implementado em duas réplicas, usando WS-LoadBalancer.

Para a implementação do despachante encarregado do balanceamento de carga, usou-se como base o módulo WS-Dispatcher do projeto Web/XML Services Utility Library (XSUL) do laboratório Extreme! Lab [Slominski et al 2005], este projeto visa criar ferramentas e utilitários em diversos módulos para Web Services. O módulo WS-Dispatcher permite que serviços internos sejam expostos de maneira segura pela Internet, pois são acessados através de um despachante. Na implementação do despachante do presente trabalho, foi criado um novo módulo para o projeto XSUL, que estende o módulo WS-Dispatcher para que este possa realizar balanceamento de carga.

110

O WS-Dispatcher foi utilizado no modo RPC-Dispatcher. Nele, quando uma requisição chega ao despachante, este pesquisa pelo endereço físico do serviço. Logo após, o despachante abre uma nova conexão com o serviço, encaminhando a requisição. A sua resposta é enviada de volta ao despachante, que a envia ao consumidor na mesma conexão HTTP. Então, no caso do RPC-Dispatcher, consumidores esperam pela resposta do serviço e o WS-Dispatcher deve manter uma conexão com o consumidor e uma segunda com o serviço.

No presente trabalho a implementação do RPC-Dispatcher foi modificada para que o protocolo WS-Addressing fosse utilizado nas requisições síncronas. Assim, o despachante encaminharia somente as requisições aos servidores. E o próprio servidor, usando o cabeçalho replyTo da mensagem, enviaria a resposta diretamente ao consumidor. Se esse cabeçalho não for definido, a resposta é enviada para o endereço indicado no protocolo de transporte.

Para transformar o WS-Dispatcher em uma entidade que realiza balanceamento de carga, foram feitas outras modificações no despachante para que ele pudesse realizar essa tarefa. No projeto inicial do WS-Dispatcher, a classe que representa a tabela de roteamento continha somente uma lista de pares “endereço virtual”/“endereço físico”. Neste trabalho, para o WS-LoadBalancer, foi criada uma nova implementação da tabela de roteamento, que agora contém uma lista de objetos da classe LoadBalancingRoutingItem. Cada objeto dessa classe possui um endereço virtual (nome do serviço), uma lista de servidores que implementam o serviço e um objeto que implementa o algoritmo de balanceamento de carga que é utilizado para esse serviço. Na Figura 3 é apresentado o diagrama das novas classes implementadas neste trabalho.

Figura 3 – Diagrama de classes do despachante WS-LoadBalancer.

Um arquivo de configuração da tabela de roteamento do despachante foi criado pelo projeto XSUL para mapear os endereços virtuais aos endereços físicos. Essa escolha permite que essas informações sejam modificadas sem a necessidade de edição e nova compilação do código. Para o WS-LoadBalancer, esse arquivo foi modificado para que permita determinar mais de um servidor para um endereço virtual. Ou seja, para cada serviço disponível em um endereço virtual, define-se os servidores que implementam este serviço. Além disso, nas

111

configurações também é possível definir qual o algoritmo de balanceamento de carga será utilizado, permitindo que diferentes algoritmos de balanceamento de carga possam ser usados em diferentes serviços. O serviço é acessado pelo consumidor através do endereço do despachante e o nome do serviço. Um exemplo de arquivo de configuração para um serviço chamado “translator” usando algoritmo de balanceamento de carga randômico é apresentado na Figura 4.

Figura 4 – Exemplo de arquivo de configuração do despachante WS-LoadBalancer.

A implementação dos algoritmos de balanceamento de carga randômico e Round-robin foi simples e utilizou somente APIs padrões da linguagem Java. O algoritmo randômico, a cada requisição, seleciona um número randômico entre zero e o número de servidores. O número sorteado indica o índice do servidor selecionado na lista de servidores. O algoritmo Round-robin com pesos permite que seja indicado um peso, no arquivo de configurações, para cada servidor. O peso nada mais é do que o número de vezes que um servidor será selecionado em cada iteração na lista de servidores. Se nenhum peso é atribuído, o servidor será selecionado uma vez a cada rodada na lista de servidores. O algoritmo Round-robin sem pesos acontece quando pesos iguais são atribuídos a todos os servidores.

Por ser um algoritmo mais complexo, o Menor Carga exigiu o uso de APIs externas. Isso porque é necessário descobrir a carga atual dos servidores. Com esse propósito, escolheu-se o uso do protocolo Simple Network Management Protocol (SNMP) que permite acessar uma variedade de informações sobre uma máquina que execute um agente SNMP. Esse protocolo foi escolhido por ser um padrão na sua área e por possuir implementações em diversos tipos de máquinas.

Ao iniciar o despachante, é criada uma thread para cada servidor do serviço, que vai obter as suas informações de carga. Essa thread é responsável por questionar um servidor sobre o valor da sua carga disponível. Esse valor será usado pelo despachante ao selecionar um servidor para uma requisição. No SNMP, as informações encontram-se nas chamadas Management Information Bases (MIBs), uma coleção de objetos acessíveis através da chamada de métodos da interface SNMP. Nesse algoritmo, para sistemas Unix, foi utilizada a MIB ucdavis, que possui uma entrada contendo informações sobre a carga disponível na CPU de uma máquina (ssCpuRawIdle). Já para sistemas Windows, foi utilizada a MIB WTCS, que possui uma entrada com informações sobre a carga utilizada (cpuPercentProcessorTime) em uma máquina. A thread recebe o valor ssCpuRawIdle ou cpuPercentProcessorTime (nesse caso, esse valor deve ser subtraído de 100) e atualiza uma lista que contém a carga disponível para todos os servidores. Essa lista é usada para calcular a probabilidade de cada servidor ser sorteado, com a fórmula citada anteriormente.

Na Figura 5, um diagrama de seqüência de uma chamada a um serviço usando WS-LoadBalancer é apresentada.

1# Uso: [service]=[className]%[host:port/path],[host:port/path],[host:port/path]... 2translator=RandomPolicy%http://translator.example/WSATranslator,anotherserver:55

112

Figura 5 – Diagrama de Seqüência de chamada de serviço através do despachante WS-LoadBalancer.

A plataforma Axis [Axis] foi escolhida como plataforma de desenvolvimento de Web services para o servidor. Ela é uma implementação do protocolo SOAP desenvolvida pelo projeto Apache e foi escolhida por ser livre e de código aberto, o que facilita alterações necessárias ao modelo de manipulação das mensagens SOAP. A implementação WS-Addressing utilizada foi a Web-FX [W-FX], que é um manipulador SOAP (SOAP Handler) que interage com mensagens SOAP, colocando e extraindo informações de endereçamento dos seus cabeçalhos XML.

A plataforma Axis utilizada pelos servidores foi ligeiramente modificada, para que pudesse encaminhar as mensagens em nome do despachante. Para isso, é necessário que o próprio servidor indique nos cabeçalhos das mensagens de resposta ou falha que estas provêem do despachante e não do seu próprio endereço. Com esse intuito, foi implementado um novo manipulador (handler) para as mensagens SOAP, que é uma extensão do handler de processamento de mensagens WS-Addressing. Além de realizar o processamento necessário para mensagens WS-Addressing, ele possui um atributo com o valor do endereço do despachante. A cada mensagem enviada por um servidor, seja ela de resposta ou falta, os seus cabeçalhos from, replyTo e faultTo recebem o valor do atributo com o endereço do despachante.

O servidor, após processar a mensagem, envia a resposta ao endpoint indicado, se especificado o cabeçalho para resposta (replyTo) na mensagem de requisição. Se não, a resposta é enviada para o despachante, pela conexão HTTP, que enviará ao endereço do consumidor indicado na camada de transporte.

7. Testes e Resultados

Testes de carga foram realizados no despachante com o intuito de comparar o desempenho dos algoritmos de políticas de balanceamento implementados. Para melhor comparar os algoritmos em diferentes situações de carga, foram realizados testes para cada implementação de algoritmo em duas situações diferentes. Na primeira situação (cargas iguais), os dois servidores que implementam o serviço, utilizados nos testes, não estavam sobrecarregados. Já

113

na segunda (cargas diferentes), um dos servidores estava com muitos processos em execução e, por isso, ficou sobrecarregado, enquanto o outro servidor possuía carga normal.

Para cada situação de teste, foram realizados três testes em seqüência. Em cada um desses testes, foi simulado o envio de 100 requisições por 50 usuários, totalizando 5000 requisições por teste e 15.000 requisições por situação de teste e algoritmo. A média do tempo de resposta foi calculada pela média dos três testes em seqüência para cada algoritmo e cada situação de teste.

Entre as informações disponíveis na aplicação utilizada para simular as requisições estão a média de tempo de resposta de todas as amostras (requisições) em milissegundos e o desvio padrão em milissegundos. A seguir, é apresentado o gráfico com o resultado do tempo de resposta médio para cada algoritmo nos testes nas duas situações.

Tempo de resposta médio

149,67151175,34

207,67

168,34 147

0

50

100

150

200

250

Randôm

ico

Round

-robin

Menor ca

rga

Mili

sseg

un

do

s

Cargas diferentes

Cargas iguais

Figura 6 – Gráfico tempo de resposta médio dos algoritmos.

O gráfico da Figura 6 mostra que os algoritmos Round-robin e Randômico possuem comportamento parecido nas duas situações testadas: tanto em situações nas quais a carga dos dois servidores está baixa e igual quanto em situações nas quais um servidor está bem mais carregado que o outro. Ainda assim, o algoritmo de Round-robin possui o menor tempo de resposta dos dois.

Nesse gráfico também pode-se ver que o algoritmo de Menor Carga possui o mais alto tempo de resposta quando os dois servidores possuem cargas iguais e baixas. Isso acontece porque a escolha do servidor nesse algoritmo é mais complexa que nos outros dois. Entretanto, essa complexidade é superada pela implementação do algoritmo que escolhe o servidor menos carregado quando um deles possui um maior processamento. Assim, é demonstrado que, em cargas altas, o algoritmo de Menor Carga apresenta um melhor resultado, mostrando a importância de saber o estado atual dos servidores ao se selecionar um servidor para responder uma requisição.

8. Conclusões e Trabalhos Futuros

Os Web Services apresentam diversas qualidades, entre elas a flexibilidade, a interoperabilidade e o fraco acoplamento. Entretanto, a sua implementação ainda possui problemas de desempenho que este trabalho buscou endereçar. Com este trabalho, julgamos que foi possível obter êxito no emprego de replicação e de algoritmos de balanceamento de

114

carga com o intuito de limitar os problemas de desempenho apresentados pelos Web Services.

Com o estudo dos Web Services e de soluções já existentes de balanceamento de carga em outras arquiteturas, pôde-se propor um mecanismo para o balanceamento de carga específico para essa tecnologia. A solução apresentada ainda oferece diferentes algoritmos de balanceamento de carga, que podem ser escolhidos conforme as características do serviço e dos servidores que o implementam. Nos trabalhos e estudos pesquisados, não foi encontrada uma solução de balanceamento de carga que abordasse especificamente serviços Web.

Este trabalho ainda pode ser melhorado para aprimorar cada vez mais a qualidade de serviço oferecida pelos serviços Web. Uma sugestão para melhorar o desempenho do algoritmo de Menor Carga seria modificar este algoritmo para que o próprio servidor enviasse a sua carga para o despachante. Assim, torna-se desnecessário o uso de threads no despachante para questionar os servidores, diminuindo o número de processos que são executados nessa máquina.

Como o WS-Addressing permite a independência de transporte, pode-se receber mensagens de um protocolo de transporte e encaminhá-las para um serviço que tenha uma ligação com outro protocolo. O despachante poderia ser modificado para realizar essa intermediação. Atualmente, o servidor despachante é somente um servidor HTTP. Entretanto, com o uso da especificação WS-Addressing, para implementar essa nova solução seria necessário somente identificar o protocolo de transporte para cada servidor e criar a conexão adequada quando um servidor for escolhido. As informações de endereçamento e processamento encontram-se todas nas próprias mensagens.

O despachante WS-LoadBalancer também poderia ser aperfeiçoado com o intuito de prover tolerância a faltas. Para isto, seria necessário monitorar a atividade dos servidores e distribuir a carga entre os servidores não-faltosos.

Seria também interessante desenvolver um trabalho mais completo de avaliação dos algoritmos de balanceamento de carga sob diferentes condições, para embasar o desenvolvedor que utiliza o mecanismo proposto na escolha do algoritmo mais adequado para uma determinada aplicação.

É importante lembrar que a decisão de utilizar a tecnologia Web Services nunca vai ser justificada com base somente no seu desempenho, mas sim, em características de interoperabilidade, flexibilidade, redução de custos e melhor relacionamento com parceiros de negócio e clientes. Contudo, a disponibilidade e o desempenho dos serviços são imprescindíveis quando se deseja oferecer qualidade de serviços para os seus consumidores.

Referências Bibliográficas Tian, M. et al. Performance Impact of Web Services on Internet Servers . International Conference on

Parallel and Distributed Computing and Systems. Estados Unidos da América, nov. 2003.

Bustamante, Fabian et al. Efficient wire formats for high performance computing. Supercomputing 2000, Estados Unidos da América, nov. 2000.

Govindaraju, M. et al. Toward Characterizing the Performance of SOAP Toolkits. 5th IEEE/ACM International Workshop on Grid Computing. Nov, 2004.

115

Kohlhoff, C.; Steele, R. Evaluating SOAP for High Performance Business Applications: Real-Time Trading Systems. WWW2003, Hungria, 2003.

Cohen, F. Discover SOAP encoding's impact on Web service performance. Março 2003. Disponível em: <http://www-106.ibm.com/developerworks/webservices/library/ws-soapenc/>. Acesso em: 20 nov. 2004.

Harbaugh, Logan. Power Up XML Data Processing With the DataPower XA35 XML Accelerator. Dez. 2002. Disponível em: <http://www.serverwatch.com/hreviews/article.php/1550181>. Acesso em: 27 nov. 2004.

Systnet. Introduction to Web Services Architecture. 2002. Disponível em: <http://www.systinet.com/download/74c83b5cf8607b124e247426574e0943/wp_Systinet_SOA.pdf>. Acesso em: 20 nov. 2004.

SOAP Specifications. Disponível em: <http://www.w3.org/TR/soap/>. Acesso em: 20 nov. 2004.

Christensen, Erik et al. Web Services Description Language (WSDL) 1.1. Março 2001. Disponível em: <http://www.w3.org/TR/wsdl>. Acesso em: 20 nov. 2004.

Universal Description, Discovery and Integration (UDDI). Disponível em: <http://www.uddi.org/>. Acesso em: 20 nov. 2004.

Web Services Addressing (WS-Addressing). W3C Member Submission. Ago. 2004. Disponível em: <http://www.w3.org/Submission/ws-addressing/>. Acesso em: 29 abr. 2004.

Charter of the Web Services Addressing Working Group. Disponível em: <http://www.w3.org/2004/09/wsa-charter.html>. Acesso em: 20 nov. 2004.

Slominski, Aleksander et al. Asynchronous Peer-to-Peer Web Services and Firewalls. 7th International Workshop on Java for Parallel and Distributed Programming (IPDPS 2005). Abril 2005.

Apache Axis. Disponível em: <http://ws.apache.org>. Acesso em: 5 maio 2005.

Web Service FX (Functionality Extensions). Disponível em: <http://ws.apache.org/ws-fx/>. Acesso em: 20 nov. 2004.

COULOURIS, George; DOLLIMORE, Jean; KINDBERG, Tim. Distributed Systems: Concepts and Design. Terceira Edição. Addison-Wesley, 2001.

CARDELLINI, V.; COLAJANNI, M.; YU, P. Dynamic Load Balancing on Web-Server Systems. IEEE Internet Computing. Maio/jun. 1999.

VERÍSSIMO, P.; RODRIGUES, L. Distributed Systems for System Architects. Kluwer Academic Publishers, 2001.

MANI, Anbazhagan; Nagarajan, Arun. Understanding quality of service for Web services. Jan 2002. Disponível em: <http://www-106.ibm.com/developerworks/webservices/library/ws-quality.html>. Acesso em: 24 abr 2005.

DAVIS, Dan; PARASHAR, Manish. Latency Performance of SOAP Implementations. Proc. 2nd IEEE/ACM International Symposium on Cluster Computing and the Grid. Maio 2002.

TIAN, M. et al. Performance Impact of Web Services on Internet Servers. International Conference on Parallel and Distributed Computing and Systems . Estados Unidos da América, nov. 2003.

TEO, Y.; AYANI, R. Comparison of Load Balancing Strategies on Cluster-based Web Servers. Transactions of the Society for Modeling and Simulation, 2001.