JÔ SATO
BALANCEAMENTO DE REQUISIÇÕES EM CLUSTER DE
SERVIDORES WEB: UMA EXTENSÃO PARA O
MOD_PROXY_BALANCER DO APACHE
MARINGÁ
2007
JÔ SATO
BALANCEAMENTO DE REQUISIÇÕES EM CLUSTER DE
SERVIDORES WEB: UMA EXTENSÃO PARA O
MOD_PROXY_BALANCER DO APACHE
Dissertação apresentada ao Programa de
Pós-Graduação em Ciência da Computação
da Universidade Estadual de Maringá, como
requisito parcial para obtenção do grau de
Mestre em Ciência da Computação.
Orientador: Prof. Dr. Ronaldo Augusto de
Lara Gonçalves
MARINGÁ
2007
Dados Internacionais de catalogação-na-publicação
Universidade Norte do Paraná
Biblioteca Central
Ana Cristina Gasparini Freitas
Bibliotecária CRB9/792
J266b
Sato, Jô.
Balanceamento de requisições em cluster de servidores web: uma
extensão para o mod_proxy_balancer do apache / Jô Sato.
Maringá: [s.n], 2007.
xiv; 102p.
Dissertação (Mestrado). Ciência da computação. Universidade
Estadual de Maringá.
Orientador: Profº Drº Ronaldo Augusto de Lara Gonçalves
1- Ciência da Computação - dissertação de mestrado – UEM 2Clusters web 3- Servidor web 4- Apache – servidor web 5Mod_proxy_balancer - módulo I- Gonçalves, Ronaldo Augusto de
Lara, orient. II- Universidade Estadual de Maringá III- UEM
CDU 004.73
JÔ SATO
BALANCEAMENTO DE REQUISIÇÕES EM CLUSTER DE
SERVIDORES WEB: UMA EXTENSÃO PARA O
MOD_PROXY_BALANCER DO APACHE
Dissertação apresentada ao Programa de
Pós-Graduação em Ciência da Computação
da Universidade Estadual de Maringá, como
requisito parcial para obtenção do grau de
Mestre em Ciência da Computação.
Aprovado em 04/09/2007.
BANCA EXAMINADORA
AGRADECIMENTOS
Agradeço primeiramente a Deus, que sempre me deu forças e iluminou o meu
caminho. Por ter me acompanhado, por ter me dado a vida, saúde, bons amigos e uma ótima
família.
Ao meu orientador, professor Ronaldo Augusto de Lara Gonçalves, pessoa
formidável que contribuiu muito para o desenvolvimento do trabalho e para a minha formação
como pessoa e pesquisador.
Aos meus pais que sempre deram grande apoio, e os meus irmãos e minha
namorada que sempre foram grandes amigos, sendo todos eles fundamentais para o meu
triunfo.
Aos grandes amigos da minha turma, ao professor João Angelo Martini e a
secretária Inês que também me auxiliaram nesta jornada.
Aos meus amigos e a todos que direta ou indiretamente contribuíram para a
realização deste trabalho.
EPÍGRAFE
"A vida só pode ser compreendida
olhando-se para trás; mas só pode
ser vivida olhando-se para frente."
(Soren Kierkegaard)
RESUMO
A disponibilização cada vez mais ampla de serviços e informações diversas na Internet tais
como movimentações bancárias, pesquisas educacionais, transações comerciais e até jogos
interativos, tem aumentado o número de usuários e conseqüentemente o tráfego de dados. Os
provedores Web precisam estar preparados para atender esta demanda crescente de
processamento e comunicação. Neste sentido, o uso de cluster de servidores Web em conjunto
com o balanceamento de requisições tem sido uma estratégia importante pelo fato de
distribuir os serviços entre vários processadores de forma balanceada.
O presente trabalho descreve e discute questões arquiteturais e operacionais sobre o
balanceamento de requisições, principalmente o dinâmico, abordando técnicas, soluções e
trabalhos relacionados. Experimentos reais foram realizados sobre um cluster de servidores
Apache provido com o módulo de balanceamento de carga mod_proxy_balancer, usando
sobrecargas sintéticas intensivas e monitoradas em diferentes configurações. A partir da
análise e avaliação do comportamento e dos resultados destes experimentos, um novo método
de distribuição de requisições para o módulo mod_proxy_balancer, chamado de byquery, foi
proposto, experimentado e avaliado.
O método byquery tira proveito das situações em que a sobrecarga de rede não é detectada
pelo mod_proxy_balancer pelo fato de ser gerada por agentes externos ao serviço Web.
Nestas situações de sobrecarga, os resultados aqui apresentados mostram a eficiência do novo
método, quando comparado com os métodos já existentes, podendo reduzir o tempo de
atendimento em até 65% no melhor caso, sendo, portanto, recomendado para clusters não
dedicados exclusivamente ao serviço Web.
ABSTRACT
Several services and informations, such as bank transactions, educational researches,
commercial transactions and even interactive games are more and more available in Internet,
and it has been increasing the number of users and consequently the data traffic. Web
providers needs to be prepared to take care of this growing demand of processing and
communication. In this direction, the use of cluster of Web servers together with the requests
balancing has been an important strategy by the fact of distributing the services among several
processors in a balanced way.
The present work describes and argues architectural and operational questions on the request
balancing, mainly dynamic one, approaching techniques, solutions and related works. Real
experiments were accomplished on a cluster of Apache servers provided with the load balance
module mod_proxy_balancer, using intensive synthetic overloads and monitored in different
configurations. Starting from the analysis and evaluation of the behavior and the results of
these experiments, a new method of request distribution to mod_proxy_balancer module,
called byquery was proposed, experienced and evaluated.
The byquery method takes advantage in situations where network overload is not detected by
mod_proxy_balancer by the fact of being generated by external agents to the Web service. In
these overload situations, the results here presented show the efficiency of the new method,
when compared with the existing methods, being able to reduce the time of attendance up to
65% in the best case, being, therefore, recommended for clusters not dedicated exclusively to
the Web service.
vii
Lista de Definições, Abreviaturas e Siglas
Internet – Rede mundial de computadores que permite a transferência de dados. É baseada
nos protocolos TCP/IP.
Domínio – Nome que permite identificar uma instituição na Internet. O nome de um domínio
consiste de uma seqüência de palavras separadas por pontos (.). Por exemplo, uem.br.
TCP/IP - Transport Control Protocol/Internet Program é um conjunto de protocolos para a
comunicação de dados, utilizado na Internet e em muitas redes locais. Foi desenvolvido pelo
Departamento de Defesa dos Estados Unidos para a comunicação de computadores de sua
Rede ARPANET (Advanced Research Products Agency Network).
IP - Internet Protocol é um protocolo da camada de rede da família de protocolos TCP/IP,
sendo responsável pelo roteamento que permite que duas redes se comuniquem.
TCP - Transmission Control Protocol é um protocolo da camada de transporte da família
TCP/IP, orientado à conexão, usado com aplicações para serviços como HTTP, FTP e SMTP.
UDP - User Datagram Protocol é um protocolo da camada de transporte da família TCP/IP,
não orientado a conexão, usado por aplicações como serviço de nomes (DNS).
DNS - Domain Name System (DNS) é um serviço/protocolo da família TCP/IP responsável
pela conversão de nomes Internet em seus endereços IPs correspondentes.
HTTP - Hyper Text Transfer Protocol – protocolo que gerencia os acessos às páginas de um
site, cujas solicitações são atendidas/executadas por um servidor Web.
Browser – ou navegador, é um cliente para obter a informação em um servidor Web, sendo
responsável por localizar e exibir uma página html no computador requisitante.
HTML - Hyper Text Markup Language - linguagem utilizada para a elaboração de páginas
eletrônicas. Os browsers interpretam o código desta linguagem para assim exibir as páginas.
viii
URL - Uniform Resource Locator - Informa o endereço de um recurso na Internet. Possui o
seguinte formato: protocolo://máquina/caminho/recurso
Porta – Termo utilizado para distinguir entre conexões simultâneas em um único host
destino. Cada protocolo da camada de aplicação do TCP/IP utiliza uma porta padrão.
Servidor Proxy - servidor que recebe as requisições dos clientes e executa os pedidos de
conexões a outros servidores (por exemplo: arquivos ou Web).
WWW - World Wide Web, ou Web, é definição para a rede de computadores na Internet que
disponibiliza informações na forma de hipertexto.
Hypertexto - é um documento que apresenta informações nas quais textos, imagens, sons e
ações ficam interligados através de associações não lineares que permitem ao usuário
percorrer assuntos inter-relacionados de maneira independente da ordem em que são
apresentados, através de links.
Link – é uma referência a outros documentos dentro de um hypertexto.
Proxy – é um serviço que permite que clientes acessem serviços a partir dele. Também pode
fazer um cache de informações que trafegam entre um cliente e um servidor.
Nó - Qualquer dispositivo, inclusive servidores e estações de trabalho, ligado a uma rede.
Servidor - Programa responsável pelo atendimento a determinado serviço solicitado por um
cliente.
Cliente - É um processo ou programa que solicita serviços a um servidor.
SSI - Single System Image - Imagem Única do Sistema. Conjunto de técnicas que permite
ocultar a complexidade sistema distribuído, fazendo que um conjunto de máquinas se
comporte como uma única máquina para o cliente.
ix
HPPCA - High Performance and Parallel Computer Architecture Group – Grupo de pesquisa
em Computação de Alto Desempenho, abrangendo Simulação Computacional, Avaliação de
Desempenho, Arquiteturas Superescalares, Redes de Interconexão e Computação Paralela,
que atua junto ao DIN – Departamento de Informática da UEM – Universidade Estadual de
Maringá.
Throughput - quantidade de dados que é possível transferir no barramento de dados ou
através de um dispositivo por segundo;
x
LISTA DE FIGURAS
Figura 1: Funcionamento de uma Requisição Web. .............................................................. 19
Figura 2: Servidor Web/Aplicação – Servidor Banco de Dados. ........................................... 20
Figura 3: Sistema Web Distribuído. ...................................................................................... 24
Figura 4: Arquitetura de um Cluster Web. ............................................................................ 26
Figura 5: Modelo OSI Versus Arquitetura TCP/IP. .............................................................. 26
Figura 6: Redirecionamento na Camada 4/2. ........................................................................ 27
Figura 7: Redirecionamento na Camada 4/3. Reescrita Única de Pacotes. ............................ 28
Figura 8: Redirecionamento na Camada 4/3. Reescrita Dupla de Pacotes. ............................ 29
Figura 9: Redirecionamento na Camada7. ............................................................................ 30
Figura 10: Página de gerenciamento do Mod_proxy_balancer.............................................. 50
Figura 11: Análise de Requisição com o Mod_proxy_balancer. ........................................... 51
Figura 12: Diagrama de ligação dos equipamentos no ambiente de teste no cluster HPPCA. 53
Figura 13: Tempo de resposta utilizando páginas estáticas pelo método byrequests.............. 56
Figura 14: Tempo de resposta para páginas dinâmicas pelo método byrequests. ................... 57
Figura 15: Tempo de resposta ideal para o conjunto de teste 4.3 e 8.3. ................................. 65
Figura 16: Comparação tempos método bytraffic e byallproxytraffic. ................................... 67
Figura 17: Tempo de resposta utilizando o método byquery. ................................................ 71
Figura 18: Tempo de resposta utilizando o método byquery em intervalos de tempo fixo. .... 72
Figura 19: Tempo de resposta com método byquery. Intervalo x ociosidade da CPU............ 73
Figura 20: Tempos pelos métodos byrequests, bytraffic e byquery........................................ 74
Figura 21: Tempos pelos métodos byrequests, bytraffic e byquery nos testes 4.1 e 8.1.......... 74
Figura 22: Tempos pelos métodos byrequests, bytraffic e byquery nos testes 4.2 e 8.2.......... 75
Figura 23: Tempos pelos métodos byrequests, bytraffic e byquery nos testes 4.3 e 8.3.......... 76
xi
LISTA DE TABELAS
Tabela 1: Direcionamentos das requisições. ......................................................................... 55
Tabela 2: Tempos de Execução do Teste 4 com Sobrecarga. ................................................ 59
Tabela 3: Tempos de Execução do Teste 8 com Sobrecarga. ................................................ 59
Tabela 4: Teste 4 - Nós que executam download e número de requisições atendidas. ........... 59
Tabela 5: Teste 8 - Nós que executam download e número de requisições atendidas. ........... 60
Tabela 6: Tempos com download de arquivos específicos nos slaves 1 a 4........................... 61
Tabela 7: Tempos com download de arquivos específicos nos slaves 5 a 8.......................... 62
Tabela 8: Tempos de Execução do Teste 4 com Sobrecarga Slave – Slave............................ 63
Tabela 9: Tempos de Execução do Teste 8 com Sobrecarga Slave – Slave............................ 64
Tabela 10: Nós que executam download e número de requisições atendidas – byquery........ 76
xii
LISTA DE QUADROS
Quadro 1: Configuração Mod_proxy no httpd.conf. .............................................................. 44
Quadro 2: Exemplo de configuração Mod_proxy_balancer no httpd.conf............................. 45
Quadro 3: Algoritmo simplificado do método byrequests. .................................................... 47
Quadro 4: Exemplo de escalonamento byrequests com lbfactor igual a 1. ............................ 48
Quadro 5. Exemplo de escalonamento byrequests com lbfactor igua1 a 25........................... 48
Quadro 6: Exemplo do processo de escalonamento byrequests. ............................................ 48
Quadro 7: Exemplo do processo de escalonamento byrequests com a exclusão de um nó. .... 49
Quadro 8: Exemplo do processo de escalonamento bytraffic. ............................................... 49
Quadro 9: Algoritmo simplificado do método bytraffic. ....................................................... 50
Quadro 10: Configuração Mod_proxy_balancer no httpd.conf. ........................................... 54
Quadro 11. Configuração do apache para um direcionamento específico.............................. 61
Quadro 12: Algoritmo simplificado do método byallproxytraffic.......................................... 66
Quadro 13. Exemplo de utilização do comando mpstat......................................................... 68
Quadro 14: Algoritmo simplificado de funcionamento o método byquery. ........................... 69
Quadro 15: Exemplo do processo de escalonamento byquery. .............................................. 69
Quadro 16: Escalonamento byquery com S2 atendendo o dobro de requisições .................... 70
Quadro 17: Escalonamento byquery - S2 indisponível ou com 100% de carga de CPU......... 70
Quadro 18: Escalonamento byquery - S2 com 50% de carga de CPU. ................................. 71
xiii
SUMÁRIO
RESUMO
ABSTRACT
1. INTRODUÇÃO.............................................................................................................. 15
2. SERVIDOR WEB........................................................................................................... 18
2.1. Breve Descrição sobre o Apache ............................................................................... 20
3. CLUSTERS E O SERVIÇO WEB................................................................................... 22
3.1. Cluster de Servidores Web......................................................................................... 23
3.1.1. Sistema Web Distribuído .................................................................................... 24
3.1.2. Cluster Web........................................................................................................ 25
3.2. Arquitetura de um Cluster Web ................................................................................. 26
3.2.1. Redirecionamento na Camada 4/2....................................................................... 27
3.2.2. Redirecionamento na Camada 4/3....................................................................... 27
3.2.3. Redirecionamento na Camada 7.......................................................................... 29
3.3. Técnicas para Seleção de Servidores e Distribuição de Requisições........................... 30
3.4. Soluções de Balanceamento Implementadas em Hardware e Software....................... 32
4. REVISÃO BIBLIOGRÁFICA ...................................................................................... 35
4.1. Trabalhos Relacionados à Arquitetura de Clusters de Servidores Web ....................... 35
4.2. Trabalhos Relacionados às Técnicas para Balanceamento de Requisições WEB e
Aumento de Disponibilidade ............................................................................................ 38
5. INVESTIGAÇÃO DO BALANCEAMENTO DE REQUISIÇÕES NO APACHE E A
PROPOSTA DE UM NOVO MÉTODO........................................................................... 43
5.1. Visão geral ................................................................................................................ 43
xiv
5.2. Funcionamento do Apache com o Mod_Proxy e o Mod_Proxy_Balancer .................. 44
5.2.1. O método Byrequests.......................................................................................... 47
5.2.2. O método Bytraffic............................................................................................. 49
5.2.3. Monitoramento e Diagrama de Funcionamento................................................... 50
5.3. Experimentos Preliminares ........................................................................................ 51
5.3.1. Ferramentas Utilizadas ....................................................................................... 52
5.3.2. Ambiente de Teste.............................................................................................. 53
5.3.3. Configuração do Mod_proxy_balancer para Testes com Páginas Estáticas e
Dinamicamente Geradas............................................................................................... 54
5.3.4.Testes com Tráfego de Rede - Sobrecarga Slave-Master Detectada pelo
mod_proxy_balancer.................................................................................................... 58
5.3.5.Testes com Tráfego de Rede - Sobrecarga Slave-Master não Detectada pelo
Mod_proxy_balancer ................................................................................................... 60
5.3.6.Testes com Tráfego de Rede - Sobrecarga Slave-Slave não Detectada pelo
Mod_proxy_balancer ................................................................................................... 63
5.3.7. Sobrecarga Slave-Slave não Detectada pelo Mod_proxy_balancer - Exclusão do
nó com Sobrecarga....................................................................................................... 64
5.4. Novos Métodos para o Mod_proxy_balancer ............................................................ 65
5.4.1. O Método ByAllProxyTraffic .............................................................................. 65
5.4.2. O Método Byquery ............................................................................................. 67
5.4.3. Comparação do Método Byquery com os Métodos já existentes.......................... 73
6. CONCLUSÕES E TRABALHOS FUTUROS.............................................................. 77
REFERÊNCIAS BIBLIOGRÁFICAS .............................................................................. 80
APÊNDICE ........................................................................................................................ 83
15
1. INTRODUÇÃO
A popularização da Internet e o conseqüente aumento no número de usuários fizeram com
que a Web (World Wide Web) se tornasse a interface padrão para acesso a aplicações e
serviços remotos de sistemas de informação. Atualmente, a disponibilização de aplicações e
serviços Web permite movimentações bancárias, declaração de imposto de renda, solicitação
de certidões e compras, entre outras atividades. Isto produz um tráfego intenso de dados na
Internet, exigindo que os grandes provedores de conteúdo e serviços implementem arquitetura
de servidores Web escaláveis, que sejam capazes de lidar com a demanda atual bem como
cresçam de acordo com a futura necessidade de desempenho.
Segundo Cardellini et al (2002), a velocidade das redes de computadores cresce de
maneira mais rápida que a capacidade de processamento dos servidores, tornando o lado do
servidor Web um possível gargalo para todo o sistema. Contribui para isto, a substituição dos
mecanismos básicos de busca de conteúdo estático por complexos mecanismos para
disponibilização de conteúdo dinâmico, utilizados principalmente por aplicações e serviços
Web que requerem maiores recursos computacionais e maior segurança na comunicação de
dados. Um site popular pode receber milhares de requisições de acesso por segundo, exigindo
alta disponibilidade e capacidade de atendimento às requisições. Tais características podem
ser obtidas com o balanceamento de requisições entre vários servidores de um cluster
(Aversa, L. and Bestavros, 2000), (Iyengar et al, 2000), (Cardellini et al, 2002), (Schroeder
et all, 200).
Cluster de servidores Web é a solução mais popular para a construção de uma
plataforma que ofereça escalabilidade, provendo relativa economia de hardware e software
em relação aos grandes servidores de última geração. O estado da arte de soluções comerciais
para cluster de servidores Web utiliza um nó redirecionador (despachante, Web switch, frontend) especializado que é o único ponto de contato com os clientes Web e distribui as
16
requisições para os demais nós (back-end) no cluster. Estes nós são servidores Web comuns,
sendo construídos utilizando hardwares não especializados e executando sistema operacional
do tipo Unix-like ou Windows. O nó redirecionador é normalmente um dispositivo que integra
hardware e software proprietário desenvolvido pela empresa que fabrica o produto.
Os redirecionadores em um cluster de servidores Web podem ser normalmente
divididos naqueles que operam na camada 4 e na camada 7. A camada 4 se refere à mesma
camada do modelo de referência OSI e ao TCP em redes TCP/IP, indicando que o
redirecionador pode somente usar a informação TCP para a distribuição das requisições. Na
camada 7, o redirecionador utiliza as informações da camada de aplicação, como por
exemplo, o HTTP, caso de servidores Web, para a distribuição das requisições.
Uma alternativa gratuita em relação aos redirecionadores comerciais é a utilização do
Apache em conjunto com o módulo mod_proxy_balancer. Este módulo permite ao Apache
operar como redirecionador na camada 7, viabilizando a construção de cluster de servidores
Web de baixo custo. Apresenta dois métodos de balanceamento, byrequests e bytraffic, que
consideram o número de requisições e número de bytes, respectivamente, recebidos por cada
nó do cluster para a tomada de decisão sobre a distribuição das requisições.
Neste trabalho foram analisados os dois métodos de balanceamento do
mod_proxy_balancer, efetuados testes e avaliados os resultados. Com base nestes resultados
dois novos métodos de balanceamento foram propostos, byallproxytraffic e byquery, sendo o
segundo o mais importante e que justifica o presente trabalho. O primeiro é uma modificação
do método bytraffic, que utiliza o tráfego contabilizado pelo módulo mod_proxy para tomada
de decisão de balanceamento. O segundo considera a utilização das CPUs dos nós do cluster
como parâmetros para a tomada de decisão do redirecionamento das requisições. Foram
efetuados testes com os dois métodos e comparados os resultados. O método byallproxytraffic
17
apresentou melhoria apenas em uma situação. Já o método byquery mostrou a viabilidade de
sua implementação.
A presente dissertação está organizada da seguinte maneira: o capítulo 2 descreve a
organização e o funcionamento de um servidor Web. O capítulo 3 apresenta a arquitetura e
funcionamento de um cluster de servidores Web, descrevendo algumas técnicas de
balanceamento de requisições. O capítulo 4 apresenta alguns trabalhos relacionados a
arquitetura de clusters de servidores Web e algoritmos de balanceamento de requisições. O
capítulo 5 analisa o método de balanceamento de requisições do mod_proxy_balancer em
experimentos preliminares com os métodos byrequests e principalmente com o bytraffic.
Depois de identificadas as possíveis melhorias é prosposto um novo método de
balanceamento – byquery – para o módulo mod_proxy_balancer. Os resultados obtidos pelo
novo método são analisados e comparados com os métodos existentes, comprovando sua
viabilidade principalmente em clusters não dedicados exclusivamente ao serviço Web. O
capítulo 6 apresenta as conclusões finais e os trabalhos futuros.
18
2. SERVIDOR WEB
Um servidor Web é um aplicativo responsável por fornecer ao computador do cliente os dados
solicitados, em tempo real, disponibilizando páginas, fotos ou qualquer outro tipo de objeto ao
navegador (browser) do cliente, que interpreta estes dados. Também pode operar recebendo
dados do cliente, processando e enviando o resultado para que o cliente possa tomar a ação
desejada, como em sistemas de comércio eletrônico e consultas via Web.
Um sistema com servidor Web consiste da interação de um cliente, operado por um
usuário, com um servidor Web. Na Figura 1, quando o usuário solicita um acesso a um site
Web na Internet, o cliente Web solicita o endereço de IP deste site para o servidor DNS local
da rede onde está vinculado. O servidor DNS verifica se este site se encontra em cache e em
caso afirmativo retorna a informação para o cliente. Caso contrário solicita esta informação
aos servidores da hierarquia DNS até chegar ao servidor DNS autoritário do domínio
solicitado, que confirma ou não a existência de tal site em sua base de dados. Uma vez
confirmada a existência do site e recebida a informação do endereço IP do mesmo, o cliente
efetua requisições diretamente ao servidor Web do site desejado. Assim que recebe a
requisição, o servidor Web analisa-a e de acordo com restrições de segurança e a existência da
informação, transmite os resultados para o navegador (browser), que por sua vez os apresenta
para o usuário final.
Um site Web na Internet necessita de vários outros serviços, instalados em um ou
mais servidores, para que possa funcionar de maneira adequada. Além do protocolo padrão
HTTP, provido pelo servidor Web, os principais protocolos que compõem um sistema de
serviços Web, entre outros são:
• HTTPS: http seguro;
• DNS: para conversão de nomes de um domínio para endereço IP e vice-versa;
• SMTP, POP e IMAP: para serviços de correio eletrônico (e-mail)
19
• FTP: para transferência de arquivos;
Servidor DNS
Local
v
Cliente
Requisição
HTTP
Internet
Servidor DNS
Autoritário para
o domínio
Servidor
Web
Figura 1: Funcionamento de uma Requisição Web.
Na arquitetura mostrada na Figura 1, consideramos que o servidor Web só armazena
páginas estáticas, sem prover qualquer outro serviço. As páginas estáticas são na realidade
arquivos em formato html armazenados no servidor Web e distribuídos de acordo com as
requisições dos clientes. Dizemos estáticas, pois o servidor simplesmente disponibiliza estes
arquivos sem modificar seu conteúdo original. Nesta relação só existe a figura do cliente e do
servidor, como mostrado anteriormente na Figura 1.
Porém, a maioria dos grandes sites Web possui em sua estrutura, servidores capazes
de gerar dinamicamente as páginas html a serem exibidas. São as chamadas páginas
dinâmicas, que são montadas no lado do servidor, através de aplicações que obtêm conteúdo e
informações a partir de um servidor de banco de dados. Nesta arquitetura, os servidores Web
que trabalham com páginas dinâmicas também são chamados de servidores de aplicações
Web, na qual existe uma relação cliente, servidor Web/Aplicação e servidor de banco de
dados, como se pode verificar na Figura 2.
20
Figura 2: Servidor Web/Aplicação – Servidor Banco de Dados.
As páginas dinâmicas facilitam a manutenção do site Web, pois permitem
atualizações mais rápidas e em certos casos, um histórico de alterações. Suponha uma página
html que informe as datas para inscrição em um determinado evento. A simples prorrogação
do período de inscrição envolveria a alteração da página html por um projetista Web. No
entanto, se tal informação estivesse armazenada em um banco de dados, qualquer pessoa que
tenha acesso ao sistema de inscrição poderia alterar esta informação, que seria
automaticamente refletida na página html gerada dinamicamente. Atualmente, a maioria dos
provedores de conteúdo trabalha com páginas dinâmicas que podem ser geradas do lado
cliente, como em applets java ou em javascripts, ou geradas do lado servidor, como em
linguagens Asp, Php e Java (servlets).
2.1. Breve Descrição sobre o Apache
O Apache é atualmente o servidor Web mais utilizado no mundo, segundo Netcraft
(Netcraft, 2006). É um software livre e de código aberto, possuindo versões para sistemas
operacionais como Windows, Novell, Linux e diversos outros do padrão POSIX (Unix,
FreeBSD etc) . Foi criado em 1995 por Rob McCool, então funcionário do NCSA (National
Center for Supercomputing Applications), Universidade de Illinois. É extremamente
21
configurável, robusto e de alto desempenho, sendo continuamente atualizado por uma equipe
de voluntários (conhecida como Apache Group) que visam incluir neste servidor Web as
inovações pesquisadas no meio acadêmico e pelo próprio grupo, sempre disponibilizando o
código fonte gratuitamente via Internet. Este servidor é compatível com o protocolo HTTP
versão 1.1. e suas funcionalidades são mantidas através de uma estrutura de módulos,
permitindo inclusive que o usuário escreva seus próprios módulos utilizando a API do
software (Mockus, 2000).
Projetado para prover páginas estáticas, que são arquivos html prontos, quando
requisitado por um browser, o Apache pode ter sua funcionalidade ampliada trabalhando em
conjunto com uma linguagem que permita a geração dinâmica de páginas como o PHP - PHP:
Hypertext Preprocessor - (PHP, 2006), também software livre, é uma linguagem de
programação interpretada, muito parecida com a linguagem C em seus tipos de dados e
sintaxe. Permite que tags html sejam embutidas em seu código. No entanto, trata-se de uma
linguagem modularizada e orientada a objetos. Possui suporte para trabalhar com diversos
bancos de dados, como MySQL, PostgreSQL, Oracle e MS SQL Server. Possui versões para
sistemas operacionais: Linux, Windows, Mac OS, Novell Netware, Solaris dentre outros. Sites
Web como o Wikipédia utilizam o PHP, em conjunto com bases de dados MySQL.
O Apache também possui módulos que lhe permitem trabalhar de maneira integrada
com servidores de aplicações Web em Java. Devido ao grande crescimento da linguagem
Java, muitos desenvolvedores têm optado por criar aplicações Web nesta linguagem,
incrementando o uso de servidores de aplicações como Tomcat, Jetty entre outros.
22
3. CLUSTERS E O SERVIÇO WEB
O termo cluster é largamente utilizado para definir um conjunto de computadores combinados
através de software e equipamentos de rede para formar uma imagem única do sistema (SSI –
Single System Image) (Baker, 2000). O primeiro cluster de computadores pessoais (PC) foi
projetado por Donald Becker e Thomas Sterling para a NASA. Este cluster era composto de
16 computadores Intel 486-DX4 conectados por uma rede ethernet. Este tipo de cluster,
composto de computadores comuns e de baixo custo, é chamado de Beowulf (Beowulf, 2007)
Os clusters podem ser utilizados para diversos propósitos, cada um possuindo
características distintas: Os tipos mais comuns são (Hochstetler & Beringer, 2003):
• Computação de Alto Desempenho (HPC – High Performance Computing): são
implementados para prover maior poder de computação para solução de um
problema através da distribuição de tarefas entre os diferentes nós do cluster.
Comumente utilizados por aplicações científicas, de simulação ou de tratamento
de imagens.
• Alta Disponibilidade (HA – High Availability): são construídos para fornecer um
ambiente seguro contra falhas, fornecendo uma maior confiabilidade e
disponibilidade para serviços através da redundância de componentes (hardware e
software). Se um componente falhar, outro nó irá executar sua tarefa. Tais clusters
são muito utilizados para executar missões críticas.
Hochstetler & Beringer (2003) citam um terceiro tipo de cluster, que é o de
balanceamento de carga (HS – Horizontal Scaling). Este cluster é projetado para distribuir
requisições de serviços para todos os nós do cluster. Também provêem alta disponibilidade
através da redundância de componente e alto desempenho de computação pela distribuição de
tarefas para os membros do cluster. Um exemplo típico é o cluster de servidores Web. Alguns
23
autores, como Baker (2000), citam o balanceamento de carga como uma característica dos
clusters de alto desempenho e alta disponibilidade.
Segundo Buyya (Buyya, 1999), os clusters também podem ser classificados de
acordo com a localização física dos nós e se os recursos computacionais destes estão
dedicados ou não exclusivamente para ao processamento do cluster. Como exemplos
podemos citar:
• Pilha de PCs (PoPCs - Pile of PCs): Nesta estrutura, os nós, chamados de escravos
são dedicados exclusivamente ao processamento do cluster e conectados em rede
são gerenciados por um nó mestre. Os nós escravos não possuem monitor, teclado
ou mouse, sendo normalmente “empilhados”.
• Cluster de workstations: Nesta configuração, os nós são computadores completos
(workstation) utilizados pelos usuários para suas tarefas diárias. Estes nós são
utilizados somente em momentos em que estão ociosos, através de um
agendamento de tarefas do nó mestre. O nó mestre, diferentemente dos demais, se
encontra em local físico diferente e protegido.
3.1. Cluster de Servidores Web
Um cluster de servidores Web é classificado como de alta disponibilidade e
balanceamento de carga, sendo composto por nós dedicados ou não exclusivamente dedicados
ao serviço Web. Em um cluster de servidores Web é possível aumentar a capacidade de
atendimento de requisições de acordo com o aumento na quantidade de acessos dos clientes
através da inclusão de mais servidores respondendo pelo mesmo serviço.
Diversos estudos foram realizados sobre o assunto como por Cardelline et al (1999)
(2002) e Aversa & Bestavros (2000). Destes estudos, pode-se verificar que para sistemas com
mais de um servidor Web, existem duas classes principais e bem definidas de acordo com a
entidade que distribui as requisições: o sistema Web distribuído e o cluster Web.
24
3.1.1. Sistema Web Distribuído
O sistema Web distribuído é o mais antigo dos modelos de balanceamento de
requisições, consistindo de nós localmente distribuídos onde cada nó possui um endereço IP
publicamente visível aos clientes. O roteamento de requisições para um nó servidor é feito da
forma convencional (por um servidor DNS qualquer), durante a fase de resolução de endereço
IP. A Figura 3 apresenta esta arquitetura.
Figura 3: Sistema Web Distribuído.
Nesta figura, observamos que o servidor DNS autoritário do domínio faz parte do
sistema, pois é responsável pelo roteamento de requisições, apresentando uma transparência
para os clientes na obtenção de dados. O servidor DNS autoritário do domínio do sistema Web
distribuído traduz um nome simbólico do site (URL) para o endereço IP de um dos nós do
sistema a cada consulta que lhe é feita. Este processo permite ao servidor DNS, implementar
várias políticas para selecionar o servidor apropriado e propagar o endereço IP deste servidor
para os clientes.
25
O servidor DNS, entretanto, tem um controle limitado sobre o direcionamento das
requisições, pois existem muitos servidores de nomes intermediários que podem fazer cache
do mapeamento nome-endereço IP para reduzir tráfego de rede, assim como clientes também
podem fazer cache local dessas informações. Para manter um controle do tempo de validade
das informações em cache, o parâmetro TTL (time-to-live) é usado. Quando o TTL expira, os
servidores DNS intermediários devem buscar (atualizar) as informações no servidor DNS
autoritário para o domínio, da mesma maneira que os clientes devem buscar estas informações
nos servidores DNS a que eles estão diretamente vinculados (Iyengar, 2000).
Esta arquitetura com servidor DNS se diferencia pelo algoritmo de escalonamento
utilizado para balancear as requisições com os vários nós do sistema. Com o algoritmo de
TTL constante, o DNS seleciona os servidores com base em informações do sistema e atribui
o mesmo valor de TTL para todas as requisições de mapeamento de endereços. Existem
algoritmos baseados no estado dos servidores Web e no estado dos clientes. Mas o mais
famoso, por ser de fácil implementação, é o DNS Round Robin (RR-DNS), no qual não se
utiliza qualquer informação do sistema Web distribuído. Esta abordagem não é balanceada,
pois não é verificada qualquer informação sobre carga dos servidores do cluster, podendo
provocar sobrecarga em alguns nós.
3.1.2. Cluster Web
Este modelo refere-se a uma coleção de máquinas servidoras que se apresenta como
uma imagem única do sistema (SSI). Um nó do cluster é configurado como redirecionador
(Web switch), sendo o responsável pela tarefa de distribuir as requisições dos clientes aos
demais servidores do cluster. Somente o seu endereço IP é visível publicamente aos clientes.
Os demais nós têm seus endereços “mascarados” pelo redirecionador. Cada nó servidor do
cluster normalmente possui seu próprio disco e sistema operacional. O controle do
26
endereçamento das requisições dos clientes pode ser implementado em hardware ou em
software. Na Figura 4, o servidor DNS autoritário para o domínio não faz parte do cluster
Web, pois não possui função no sistema de direcionamento de requisições dos clientes.
Figura 4: Arquitetura de um Cluster Web.
3.2. Arquitetura de um Cluster Web
Em um cluster Web, cada nó deve possuir um endereço privado (interno) de forma
que possa ser identificado de maneira única pelo redirecionador e possa receber as requisições
de clientes.
A Figura 5 mostra as camadas do modelo OSI e as correspondentes no TCP/IP.
Camada
7
6
5
4
3
2
1
OSI
Aplicação
Apresentação
Sessão
Transporte
Rede
Enlace
Física
TCP/IP
Aplicação
TCP
IP
Interface de
Rede
Figura 5: Modelo OSI Versus Arquitetura TCP/IP.
27
A identificação de um nó pode ocorrer em diferentes camadas do modelo OSI, mas
principalmente em nível de camada de:
• transporte/enlace - popularmente denominadas de camadas 4/2;
• transporte/rede – chamadas de camadas 4/3;
• aplicação - camada 7
3.2.1. Redirecionamento na Camada 4/2
Nesta abordagem, existe um servidor de despacho na rede que seleciona um servidor
do cluster usando seu endereço físico (MAC) sem necessidade de modificação do cabeçalho
do pacote IP, tanto do lado cliente como do servidor Web. Esta solução é transparente para
ambos os lados, uma vez que não necessita de reescrita de pacotes. O servidor de despacho
pode definir políticas de despacho dinamicamente de acordo com a carga e a disponibilidade
do servidor. No entanto, existe uma maior complexidade para sua implementação. O
encaminhamento de pacotes (Cardellini, 1999) utiliza esta técnica de balanceamento.
Servidor
MAC: B
IP:X
Web Switch
MAC: A
IP:X
Servidor
MAC: C
IP:X
Figura 6: Redirecionamento na Camada 4/2.
3.2.2. Redirecionamento na Camada 4/3
Um Cluster Web com o redirecionador operando na camada 4/3 pode utilizar
técnicas como reescrita de pacotes única ou dupla (Cardellini, 1999):
28
• Reescrita Única de Pacotes: Na reescrita única de pacotes, existe um único
equipamento (redirecionador) visível na Internet que recebe a solicitação e
encaminha para um dos servidores do cluster através de um algoritmo roundrobin. Ao definir o servidor que irá atender as requisições do cliente, o
redirecionador passa a reescrever o destino dos pacotes IP com o endereço IP do
servidor escolhido, e este passa a responder diretamente ao cliente. É importante
observar que a comunicação cliente → nó servidor Web escolhido sempre passa
pelo redirecionador. Já a comunicação servidor Web → cliente é direta, sem
passar pelo redirecionador.
Servidor
MAC: B
IP: Y
Web Switch
MAC: A
IP: X
Servidor
MAC: C
IP: Z
Figura 7: Redirecionamento na Camada 4/3. Reescrita Única de Pacotes.
• Reescrita Dupla de Pacotes: Na reescrita dupla de pacotes, também existe um
único equipamento (redirecionador) visível na Internet que recebe a solicitação e
encaminha para um dos servidores do cluster através de um algoritmo roundrobin. Definido o servidor que irá atender as requisições do cliente, o
redirecionador passa a reescrever o destino dos pacotes IP com o endereço IP do
servidor escolhido, da mesma forma que reescreve a origem dos pacotes com o
endereço do cliente. A comunicação cliente → nó servidor Web e nó servidor Web
→ cliente é feita pelo redirecionador.
29
Figura 8: Redirecionamento na Camada 4/3. Reescrita Dupla de Pacotes.
O Linuxvirtualserver (Zhang, 2000) é um exemplo de redirecionador que trabalha na
camada 4. Consiste em implementações que quando aplicadas ao kernel do Linux adicionam
esta funcionalidade a este sistema operacional. O KTCPVS (Kernel TCP Virtual Server)
(Linux Virtual Server Project) é um projeto baseado no Linuxvirtualserver que implementa
funcionalidades para operar também na camada 7.
3.2.3. Redirecionamento na Camada 7
Um redirecionador operando na camada 7 tem controle do conteúdo da requisição
HTTP, podendo implementar algoritmos de balanceamento mais eficazes e prover requisitos
de acordo com os diferentes tipos de conteúdo.
No entanto, o redirecionamento nesta camada é mais lento se comparado ao
redirecionamento na camada 4, pois existe um maior gasto de tempo de processamento para
análise das requisições, mas não significando que seja menos eficiente. Entre as possíveis
configurações para esta técnica, temos o gateway TCP e a junção TCP:
• Gateway TCP: Após o redirecionador (proxy) definir o nó que irá atender a
requisição, uma conexão é estabelecida entre eles, e o redirecionador passará a
agir como uma porta de ligação entre o servidor e o cliente.
30
• Junção TCP (TCP Splice ) (Marwah, 2006): Existe uma conexão entre o cliente e
o redirecionador (proxy), e uma conexão diferente entre o redirecionador e o
servidor. Os pacotes são encaminhados a nível de camada de rede.
Figura 9: Redirecionamento na Camada7.
O redirecionamento na camada 7 também é chamado redirecionamento em nível de
aplicação, podendo ser implementado em software operando de forma autônoma ou no
próprio servidor Web/Aplicação, como no caso do Apache com mod_proxy_balancer.
3.3. Técnicas para Seleção de Servidores e Distribuição de Requisições
As técnicas que um redirecionador pode utilizar para selecionar o servidor que irá
receber uma determinada requisição podem ser classificadas (Andreolini, 2002) em estáticas
(State-blind), baseadas em informações do servidor (server state-aware), do cliente (client
state-aware) e do cliente e servidor (client and server state-aware).
O redirecionamento estático gera um custo mínimo de processamento, sendo mais
rápido, pois não verifica o estado do servidor que irá receber a requisição. Classificam-se
nesta categoria os seguintes métodos:
31
• Random: Seleção de servidores que receberão as requisições é feita
randomicamente;
• Round-Robin: Utiliza uma fila circular e um ponteiro para o último servidor
selecionado para tomar a decisão de despacho;
• Weighted Round-Robin: Variação do Round-Robin que utiliza um peso para cada
servidor, baseado em sua capacidade de atendimento.
Já nos redirecionamentos baseados em informações do servidor, são consideradas
informações como utilização de cpu, memória, I/O de rede. Encontram-se nesta categoria:
• Least Load (LL): Método que seleciona o servidor com menor índice de carga, de
acordo com os seguintes fatores:
•
LL-CONN (Connection): Menor número de conexões ativas;
•
LL-CPU: Menor utilização da CPU;
•
LL-DISK: Menor utilização de disco;
• Dinamic Weighted Round-Robin (WRR):Variação da versão estática, em que
considera a capacidade do servidor como um peso, calculado dinamicamente, de
acordo com seu índice de carga.
No redirecionamento baseado em informações do cliente, primeiramente é avaliada a
URL solicitada pelo cliente, definindo assim servidores especializados para atendimento a
determinadas requisições, como servidores de cache, multimídia, conteúdo dinâmico, serviços
especializados entre outros. São exemplos de métodos que utilizam esta informação:
• PART - Service Partitioning: Requisições são estaticamente redirecionadas de
acordo com os arquivos que manipulam e os serviços que disponibilizam.
32
• CAP - Client Aware Policy: O Web switch estima o impacto de uma requisição no
sistema Web, distribuindo as requisições entre os servidores através da
manipulação de uma fila circular, de modo que nenhum componente do sistema
seja sobrecarregado. A definição do servidor que irá atender a solicitação é feita
de maneira estática de acordo com o serviço requisitado pelo cliente.
A combinação de informações do servidor e do cliente é utilizada pela última técnica
de seleção de servidores para distribuição de requisições. Nesta categoria, temos:
• Locality-aware Request Distribution (LARD): analisa o conteúdo da requisição
visando distribuí-la de acordo com a localidade e o balanceamento. O princípio é
de direcionar as requisições de um objeto Web sempre para um mesmo servidor,
aproveitando características de cache de disco.
• CAP-ALARM: Utiliza um mecanismo de comunicação assíncrona para trocar
mensagens de alarme entre os servidores e o redirecionador. Os parâmetros
utilizados podem ser carga de CPU, disco, rede etc. Quando ultrapassam um
determinado valor, o alarme é disparado.
3.4. Soluções de Balanceamento Implementadas em Hardware e Software
Atualmente, a necessidade de um balanceamento de requisições eficiente em
sistemas com muitos servidores Web cresce com o aumento no número de aplicações para
Internet. Acompanhando esta tendência, muitas empresas e organizações estão concentradas
em construir produtos comerciais, desenvolver protótipos para sistemas de servidores Web.
Instituições educacionais e indústrias buscam soluções inovadoras e avançadas para esta área.
Produtos comerciais implementam soluções em software e hardware proprietário, utilizando
algoritmos simples para roteamento e mais fáceis de implementar. Protótipos em pesquisa
tendem a explorar áreas novas e prover soluções engenhosas.
33
As soluções em hardware proprietário normalmente são mais eficientes, pois são
especialmente desenvolvidas para o balanceamento de carga. Como exemplos podemos citar:
• CSS 11500 (Cisco Systems, 2007): Fabricado pela Cisco, esta série de
equipamentos possui algoritmos de balanceamento tradicionais e tendo como
destaque o ACA (ArrowPoint Content Aware) que utiliza o tempo de resposta do
nós para distribuição de requisições. Segundo o fabricante, opera nas camadas 3 a
5 (parcialmente na camada 7).
• ServerIron (Foundry Network, 2007): Produzido pela Foundry Network, destacase pela facilidade de configuração e aplicativos de gerenciamento de tráfego de
Internet. Segundo o fabricante, opera nas camadas 2 e 7.
• Big-IP (F5 Network, 2007): Da F5 Network. Combina o uso de hardware
especializado com algum controle de funções implementadas em software para
roteamento de requisições, para garantir a qualidade de serviços para o usuário
final;
• Application Switches (Nortel Networks, 2007): Da Nortel Networks. Como
principais características, possui funções de filtro, balanceamento e segurança de
serviços implementados em software. Opera nas camadas 4 e 7.
Entre as soluções para técnicas de roteamento implementadas em software, temos as
soluções como:
• LVS (LVS, 2007): Linux Virtual Server é uma ferramenta que é executada no
sistema operacional Linux. Suporta serviços de rede com alta escalabilidade e
disponibilidade. O balanceamento é feito em nível de protocolo IP (Camada 4).
As três técnicas são usadas: tradução de endereço de rede (NAT), por tunelamento
IP e via roteamento direto;
34
• NLB (Microsoft Corporation, 2007): Microsoft's Network Load Balancing usa
uma tecnologia de software que suporta uma arquitetura cluster Web. Tem como
características principais a segurança de comunicação, roteamento e serviço de
acesso remoto.
• Akamai (Akamai, 2007): Da Akamai Technologies. Provê uma infra-estrutura para
comércio eletrônico que garante implementação rápida e fácil;
• Network Dispatcher (IBM, 2007): Desenvolvida pela IBM, esta solução é capaz
de suportar grande escala de acessos a um site Web, através de extensões de kernel
que efetuam o rápido repasse de pacotes IP. É fornecido como um componente do
IBM WebSphere(R) Edge Server;
• Zeus's Load Balancer (Zeus Technology, 2007): Da Zeus Technology é uma
aplicação que opera exclusivamente na camada 7, para roteamento de requisições
para os servidores Web.
Outras inúmeras soluções em software, não comerciais e de código aberto, que
podemos citar são: Apache com Mod_proxy_balancer, Pen, Pound, Balance e Magicrouter.
35
4. REVISÃO BIBLIOGRÁFICA
Neste capítulo são apresentados os conceitos relevantes de arquiteturas de clusters de
servidores Web, técnicas para balanceamento de requisições WEB e aumento de
disponibilidade, que são usados para fundamentação deste trabalho e apoiam o
desenvolvimento das implementações.
4.1. Trabalhos Relacionados à Arquitetura de Clusters de Servidores Web
Colajanni e Yu (Colajanni e Yu, 1997) propõem um algoritmo, chamado adaptive
TTL, que define o valor TTL de uma informação de mapeamento DNS considerando a
distribuição desigual de requisições dos clientes e a heterogeneidade dos servidores Web. O
resultado de suas simulações mostrou que esta estratégia obteve resultados positivos no
balanceamento de carga em servidores Web heterogêneos e geograficamente distribuídos.
Cardellini
(Cardellini,
1999)
discute
vários
esquemas
de
balanceamento,
classificando-os de acordo com o local onde o balanceamento é realizado. Na abordagem
cliente, o balanceamento é feito pelo navegador, como ocorria com o browser Netscape no
acesso ao site www.netscape.com na qual era gerado randomicamente um número de 1 a i, na
qual i é número de servidores que podem atender a requisição do usuário e direcionando-a
para wwwi.netscape.com. A abordagem DNS classifica os algoritmos utilizados no
balanceamento nos que utilizam informação sobre estado do servidor Web, e os que não
utilizam esta informação, como o round robin. Uma outra categoria é a baseada em um
redirecionador no qual uma máquina central atua como escalonador e efetua o balanceamento
através de redirecionamento http (Berners-lee, 1996) ou reescrita de pacote.
Apostolopoulos et al (Apostolopoulos, 2000) propuseram a implementação de um
roteamento baseado em conteúdo em nível de hardware que proveria um desempenho melhor
que as soluções baseadas em softwares. O sistema chamado de L5 utiliza informações da
camada de aplicação em conjunto com os das camadas 2, 3 e 4 para rotear o tráfego de rede.
36
Aversa e Bestavros (Aversa e Bestavros, 2000) apresentaram a avaliação de um
protótipo de um sistema com servidores Web escalável, utilizando a reescrita de pacotes
distribuída (DPR-distributed Packet Rewriting), no qual todos os servidores Web do cluster
podem receber e encaminhar as requisições para outros servidores Web que respondem
diretamente ao cliente. Comprovaram os benefícios desta técnica em uma comparação com
um sistema sem balanceamento e outro com balanceamento randômico. Tem como
desvantagem não apresentar um único endereço ip para o sistema e nem desempenhar funções
de gateway de rede. Existe um redirecionador que centraliza o recebimento de todas as
conexões TCP dos clientes e as encaminha para os verdadeiros servidores Web que podem
responder diretamente ao cliente (reescrita única de pacotes) ou responder para o
redirecionador para que este encaminhe os pacotes para o cliente (reescrita dupla de pacotes).
Também abordando o mapeamento DNS, Cherkasova (Cherkasova, 2000) propõe o
FLEX, que visa balanceamento de carga e uso eficiente de memória em um cluster de
máquinas hospedando vários sites Web. Os sites são alocados para cada máquina de acordo
com suas características de tráfego, visando evitar a duplicação desnecessária de documentos.
O direcionamento de tráfego é feito através de um servidor DNS, desde que cada site Web
tenha um único nome de domínio. A partir da análise periódica do log de acesso de cada
servidor Web é criada uma configuração DNS para os sites hospedados no cluster. Comparado
ao método round robin, o FLEX apresentou um desempenho de 2 a 5 vezes superior.
Teodoro et al (Teodoro, 2003) definem uma estratégia de balanceamento para cluster
Web stateful, comum em sites de comércio eletrônico, na qual é estabelecida uma conexão
entre produtos, clientes e sessões. Eles propõem uma estrutura para armazenamento de
informações de sessões no caso da necessidade de migração de um cliente para um outro
servidor Web. Na maioria das soluções, conexões de um determinado cliente são inicialmente
definidas pelo Web switch (redirecionador) para um servidor. Outros pacotes do mesmo
37
cliente são roteados para o mesmo servidor por algum tempo (alguns minutos). Após isto o
switch limpa a entrada para aquela sessão de sua tabela e computa uma nova associação se
uma nova requisição chegar. A migração de sessão está sempre presente quando o Web switch
decide rotear todo o tráfego de uma específica sessão para um servidor diferente. Isto é feito
para conseguir um melhor balanceamento de carga, no entanto, a decisão de migração de
sessão não considera a carga que representa cada sessão nem o custo de migração.
A solução proposta visa um balanceamento baseado em sessão, utilizando um PID
controller, que define a sessão que deverá ser migrada considerando a carga do servidor e a
carga associada com cada sessão. Esta estratégia foi avaliada em uma aplicação e-store (loja
virtual) e mostrou uma melhora de desempenho ( mais de 50% para tempo de resposta e 16%
para throughput).
Xu e Huang (2004) abordam a arquitetura de servidores Web distribuídos, focando
principalmente o despachante baseado em DNS. Trazem uma breve introdução sobre cluster
Web, na abordagem despachante IP e DNS, além de informações sobre os algoritmos de
balanceamento:
• Round Robin: Concluem que fila circular tem desempenho ruim;
• Two-Tier-Round-Robin (RR2): classificam os gateways em duas classes: normal e
hot. A idéia básica é reduzir a probabilidade que hot domains sejam designados
para um mesmo servidor Web. Para isso, é feita uma estatística de requisições por
domínio. Dado um período, são contados o número de requisições de endereços
de cada domínio e a soma do número atual de conexões http de cada domínio no
servidor Web. A razão entre a soma de requisições http sobre o número de
requisições de endereço IP é chamada de hidden load weight. O algoritmo RR2
particiona os domínios locais em dois grupos baseados na verificação de que o
hidden load weight do domínio local correspondente é menor que o valor limite.
38
Se for menor é um domínio normal, caso contrário é um domínio hot.
4.2. Trabalhos Relacionados às Técnicas para Balanceamento de Requisições WEB e
Aumento de Disponibilidade
Eager (Eager, 1985) descreve as políticas estáticas e adaptativas para transferência de
carga de trabalho entre os vários nós de um sistema distribuído. A política estática utiliza-se
somente da informação do comportamento padrão do sistema. As decisões de transferência de
carga são independentes do estado atual do sistema. Assim, as políticas estáticas também
podem ser classificadas como determinísticas (toda carga de trabalho é transferida de um nó
para outro) ou probabilísticas (parte da carga de trabalho vai para um nó e a outra parte vai
para um outro nó). As políticas estáticas têm a vantagem de serem simples de implementar,
pois não necessitam manter e processar informações sobre o estado do sistema. Já as políticas
adaptativas, ao contrário, são mais complexas, uma vez que trabalham com a informação atual
do estado do sistema para tomada de decisão de transferência de carga de trabalho. No
entanto, esta informação possibilita trazer grandes benefícios de desempenho. Visando avaliar
as políticas adaptativas, o autor efetua um estudo sobre as estratégias de transferência de carga
no qual a decisão é feita pelo nó que vai transferir (sender-initiated) e pelo nó que vai receber
(receiver-initiated). Um terceiro método, chamado reservation é similar ao sender-initiated,
no entanto, não há divisão de tarefa e somente novas tarefas são transferidas.
O Distributed Cooperative Apache Web Server (DC-Apache) é uma proposta de Li e
Moon (Li e Moon, 2001) para encontrar escalabilidade de desempenho para servidores Web.
Esta solução se baseia na hipótese que a maioria de sites Web tem somente alguns pontos de
entrada bem conhecidos que os usuários utilizam para iniciar a navegação. O sistema de DCApache manipula dinamicamente os hyperlinks dos documentos html a fim de distribuir
pedidos do acesso de clientes entre os múltiplos servidores Web cooperados. Apresenta como
características:
39
1. Possibilidade de migrar e copiar documentos entre os servidores cooperados;
2. Distribuir requisições para balanceamento de carga;
3. Manter cópias em estado consistente;
A solução de DC-Apache apresenta benefícios em relação aos sistemas tradicionais
baseados em manipulação de pacotes, serviços DNS e sistemas em que os arquivos se
encontram distribuídos:
• A manipulação de pacotes não é necessária. Não existe entidade redirecionadora
que precise manipular cada pacote transferido entre o cliente e o servidor. Isto
evita um possível gargalo;
• Emprega a conectividade dos hyperlinks para controlar diretamente o
balanceamento de carga. Não há redirecionamento de requisições que necessitem
que o cliente faça duas conexões para um pedido;
• Pela replicação de dados, pode resolver problemas causados por páginas populares
e extremamente acessados;
• A inclusão de novos servidores é fácil e flexível. Qualquer máquina disponível
pode ser adicionada como um servidor cooperativo.
Nesta solução, o servidor Web Apache foi modificado para alterar dinamicamente
hiperlinks de uma página, a cada requisição de clientes, para os vários servidores cooperados
que atendem pelo domínio. Os experimentos mostram que o DC-Apache obteve resultados
positivos na distribuição de requisições entre os vários membros do grupo de servidores. O
gargalo de desempenho pode ser eliminado pela distribuição de documentos em vários
servidores.
O projeto Mod_Backhand (Schlossnagle, 2000) é um módulo para o Apache versão
1.x, desenvolvido na universidade Johns Hopkins, destinado a efetuar a distribuição da carga
entre vários servidores HTTP. Sua implementação é composta de vários módulos:
40
• Gerenciamento de Informação de Recurso (RIM): Responsável por obter
informações sobre utilização do servidor Web local, e espalhar esta informação
para o cluster e coletar informações de utilização de recursos das outras máquinas
do cluster;
• Assistente de Manutenção de Recuso (RMA): Provê a pré-alocação de recursos
para operações importantes que não devem ser feitas sob demanda. Mantém um
pool de conexões existentes para outros servidores dentro do cluster;
• Tomador de Decisão (DM): Projetada sobre o conceito de funções candidatas que
servem para fazer a escolha do servidor que irá processar a requisição:
• Ferramenta de Diagnóstico (DT): Provê um mecanismo para monitorar a
utilização dos recursos do cluster.
• Proxy Interno: Executa o trabalho de redirecionamento de requisições.
Funcionamento muito similar ao mod_proxy.
As funções existentes para tomada de decisão de distribuição são:
• Off: desabilita o mod_backhand.
• addSelf: adiciona um servidor local no final da lista.
• removeSelf: remove um servidor da lista.
• byAge (segundos): remove da lista os servidores aqueles que não respondem por
um determinado período. O valor padrão é 20 segundos.
• byLoad: reordena a lista de acordo com a carga dos servidores.
• byBusyChildren: reordena a lista de servidores de acordo com a quantidade de
processos do Apache em espera.
• byCPU: reordena a lista do servidor da maior quantidade de CPU inativa.
Servidores com menor utilização de CPU ficam no topo da lista.
41
• byLogWindow: elimina os servidores utilizando o critério log2(n). Com 8
servidores ativo, n=3. A escolha será feita entre os 3 primeiros.
• byRandom: reordena, aleatoriamente, a lista de servidores.
• byCost: define um custo para cada servidor.
• bySession (id) : verifica a existência de algum cookie chamado (id).
O mod_backhand se mostrou uma solução viável. Atualmente o projeto Wackmole
(wackamole, 2007) é sua continuação.
O algoritmo de balanceamento, chamado de MOLL (Migration-Optimized Least
Loaded), é proposto por Nilson et al (Nilson, 2005). MOOL combina a utilização de duas
variáveis muito importantes na tomada de decisão para o redirecionamento: a carga do
servidor e o tempo de atraso durante a migração de sessão. A migração pode causar um
overhead significativo durante o balanceamento de carga. Por exemplo, sites de comércio
eletrônico necessitam da informação armazenada de cada sessão de um usuário. Esta
informação de sessão, pode em alguns casos, atingir até vários megabytes. Por isso, a
migração de sessão durante um balanceamento pode gerar atrasos que podem representar
metade do tempo de resposta.
O trabalho descreve e analisa os métodos existentes: random, round robin, least
visited e least load; executando 3 experimentos comparativos com o novo método de
balanceamento, para 10000 requisições, em função da:
• Carga do servidor: Simulação considerando a carga de CPU baixa (0% a 25%),
média (26% a 65%) e alta (66% a 100%). Na primeira situação, MOLL reduziu o
tempo de resposta em relação aos algoritmos random, round robin, least visited e
least load em 37,9, 36,9, 19,4 e 34,9%, respectivamente. Na terceira situação, a
redução foi de 52,1, 51,7, 40,7 e 12,3%;
• Precisão de carga de servidor: São geradas cargas no servidor que simulam a
42
utilização de CPU de 5% a 95%, em intervalos de 5%. Neste experimento é
mensurada a precisão do novo método em função do efeito da carga de CPU sobre
o tempo de resposta. Somente os métodos least visited e MOLL se mostraram
eficientes;
• Erro de previsão: Neste experimento é estudado o efeito do erro na distribuição e
sua relação com o tempo de resposta. Tal situação ocorre quando o servidor
escolhido não é o melhor. Após análises com várias porcentagens de carga de
CPU, no pior caso o MOLL aumentou o tempo de resposta em 7,1%. O tempo de
resposta absoluto foi 8,3 % menor que o do método least load.
Assim, os autores concluíram que o novo método é viável na otimização do tempo de
resposta para clusters de servidores Web.
43
5. INVESTIGAÇÃO DO BALANCEAMENTO DE REQUISIÇÕES NO APACHE E A
PROPOSTA DE UM NOVO MÉTODO
Neste capítulo é apresentada uma visão geral do balanceamento de requisições no Apache,
introduzindo alguns conceitos e termos utilizados, bem como é apresentado o mecanismo de
funcionamento do mod_proxy_balancer e dos métodos de balanceamento já existentes: o
byrequests e o bytraffic. Estes métodos são avaliados através de ferramentas de benchmark e
os resultados são utilizados para identificação de melhorias implementadas em um novo
método de balanceamento, chamado de byquery. O novo método é avaliado e seus resultados
comparados com os obtidos pelos já existentes, visando comprovar a viabilidade do novo
método.
5.1. Visão geral
Quando a Internet surgiu, achava-se que o endereçamento provido pelo protocolo IP
seria suficiente para atender a demanda do mundo inteiro. Instituições que solicitavam
endereços válidos recebiam uma ou mais faixas inteiras com 256 possibilidades de
endereçamento. Assim, computadores da rede interna tinham endereços válidos, podendo
acessar e serem acessados por qualquer computador ligado a esta rede no mundo inteiro.
No entanto, com o grande crescimento da Internet, foi necessário restringir o número
de endereços IPs válidos disponibilizados para os solicitantes, pois caso contrário faltariam
endereços para o mundo inteiro. Assim passou-se a utilizar mais criteriosamente o
endereçamento para redes internas, já previstas no protocolo, no qual três faixas de endereços
em três classes foram disponibilizadas para esse fim. Os endereços dessas classes são
utilizados em redes locais e são inválidos na Internet.
O termo proxy, que traduzido significa procurador ou intermediário, surgiu da
necessidade de permitir acesso de uma rede local à Internet através de um computador ligado
à rede interna e à rede externa válida, que compartilha sua conexão com as demais máquinas.
44
Toda solicitação de conexão de uma máquina da rede local para um host da Internet é
direcionada ao proxy, este, por sua vez, realiza o contato com o host desejado, repassando a
resposta à solicitação para a máquina da rede local.
De forma semelhante, esta mesma máquina pode permitir que um computador da
rede externa acesse algum serviço disponibilizado em um computador da rede interna. Para tal
configuração, a máquina ligada às duas redes está atuando como um proxy reverso.
5.2. Funcionamento do Apache com o Mod_Proxy e o Mod_Proxy_Balancer
O servidor Web Apache opera como proxy convencional e reverso através da
utilização do módulo mod_proxy e realiza o balanceamento de requisições através do
mod_proxy_balancer. O mod_proxy é geralmente usado para a distribuição de requisições
entre vários servidores Web, ou para prover uma cache de páginas HTML para servidores Web
mais lentos. Permite que vários servidores compartilhem uma mesma URL (Uniform
Resource Locator).
Para os clientes, o servidor proxy representa o servidor Web do domínio, que recebe
as requisições e executa os pedidos de conexões à outros servidores que podem ser hosts
remotos ou máquinas da rede interna (que não pode ser acessada diretamente via Internet). O
mod_proxy tem controle de todas as solicitações dos clientes e das respostas dos servidores a
estes clientes.
<VirtualHost 200.200.46.168>
ServerAdmin [email protected]
ServerName: www.cl.din.uem.br
ProxyRequests On
ProxyPass /download http://192.168.1.1
ProxyPassReverse /download http://192.168.1.1
</VirtualHost>
Quadro 1: Configuração Mod_proxy no httpd.conf.
45
O quadro 1 apresenta um exemplo de configuração proxy que deve ser inserido no
arquivo de configuração do Apache, o httpd.conf. O termo redirecionador aqui utilizado é
sinônimo de proxy, não tendo relação com a diretiva redirect de um outro módulo do
Apache, o mod_rewrite.
A diretiva ProxyPass permite que a requisição para a URL seja repassada para o
servidor
local e diretório especificado. No exemplo, toda requisição para a URL
http://www.cl.uem.br/download será atendida pelo servidor 192.168.1.1, localizado na rede
privada. A diretiva ProxyPassReverse permite a modificação do cabeçalho Location nas
mensagens de respostas de redirecionamento enviadas pelo Apache. Isto faz com que o
endereço retornado seja o do servidor que realmente atendeu a requisição e não da máquina
do redirecionamento. Conseqüentemente, a máquina 192.168.1.1 conseguirá obter endereço
do verdadeiro requisitante (não será mais o endereço do redirecionador).
O mod_proxy possui suporte para os protocolos AJP13 (Apache JServe Protocol
version 1.3), FTP, CONNECT (para SSL), HTTP/0.9, HTTP/1.0, e HTTP/1.1. Também pode
ser configurado para conectar com outros módulos proxy. A funcionalidade de proxy do
Apache é expandida através de vários módulos adicionais ao mod_proxy tais como:
mod_proxy_http,
mod_proxy_ftp,
mod_proxy_ajp,
mod_proxy_balancer
e
mod_proxy_connect. O suporte ao protocolo SSL/TSL é oferecido pelo mod_ssl enquanto a
função de cache é provida pelo mod_cache entre outros.
ProxyPass /din22 balancer://master lbmethod=byrequests
<Proxy balancer://master/din22>
BalancerMember http://slave1.din.uem.br1:8080/din22 loadfactor=1
route slave1
BalancerMember http://slave2.din.uem.br1:8080/din22 loadfactor=1
route slave2
</Proxy>
Quadro 2: Exemplo de configuração Mod_proxy_balancer no httpd.conf.
46
O módulo mod_proxy_balancer, disponível a partir da versão 2.1 do Apache,
adiciona a funcionalidade de balanceamento de requisições ao mod_proxy, provendo suporte
para os protocolos HTTP, FTP e AJP13. O balanceamento de requisições permite que no caso
de falha de algum nó, este seja excluído do redirecionamento em tempo de execução. O
quadro 2 apresenta um exemplo de configuração para o mod_proxy_balancer.
No mod_proxy_balancer, a diretiva ProxyPass permite a inclusão dos seguintes
parâmetros utilizados para o balanceamento:
• Stickysession: Nome da sessão sticky, se definido. Uma sessão sticky permite
manter uma conexão persistente para um específico nó do cluster até que a sessão
do cliente seja finalizada;
• Nofailover: Se habilitada, a sessão corrente é cancelada se um nó for desabilitado;
• Lbmethod: Define o método de balanceamento, byrequests ou bytraffic;
• Timeout: Tempo de espera para um nó do cluster;
• Maxattempts: Número de tentativa antes de desistir de repassar uma requisição
para um nó;
A diretiva Proxy balancer informa a URL a ter as requisições distribuídas enquanto a
diretiva BalancerMember especifica os nós que irão participar do balanceamento. Os
seguintes parâmetros podem ser definidos para esta diretiva:
• lbfactor: É o fator de balanceamento. Informa como as requisições devem ser
divididas entre os servidores, ou seja, “quanto nós esperamos que cada servidor
trabalhe". Quanto maior este valor, mais requisições um servidor irá atender.
Representa a quota normalizada de trabalho de um servidor;
• route: Rota para o nó. A rota é um valor anexado ao nome da sessão, se definida;
• redirect: rota de redirecionamento do nó.
47
Atualmente, o mod_proxy_balancer possui 2 métodos de balanceamento: por
quantidade de requisições (byrequests - request counting) e por quantidade de sobrecarga de
tráfego (bytraffic - weighted traffic counting). A definição do método de balanceamento é
feita pela diretiva lbmethod, previamente definida no arquivo de configurações do Apache.
5.2.1. O método Byrequests
Este método é habilitado definindo-se a diretiva lbmethod como byrequests
(lbmethod=byrequests). Tem como princípio distribuir as requisições entre os servidores que
participam de um balanceamento de acordo com a configuração pré-definida pela diretiva
lbfactor e pela atualização constante da variável lbstatus. O lbstatus informa qual é prioridade
(urgência) de servidor em receber requisições para cumprir esta quota de trabalho.
Inicialmente é definida a quota de trabalho para cada servidor e então se localiza o
servidor candidato (para atender a requisição) com maior prioridade de trabalho (maior
lbstatus) dentre todos os servidores que participam do balanceamento. Assim que um servidor
é selecionado, seu valor de lbstatus é subtraído da soma do lbfactor de todos os servidores.
Como esta soma não muda, a distribuição é feita da maneira especificada pelo fator de
balanceamento (Mod_proxy_balancer, 2007). O algoritmo de balanceamento é descrito no
quadro 3.
para cada servidor que participa do balanceamento
servidor lbstatus += servidor lbfactor
total factor += servidor lbfactor
se servidor lbstatus > candidato lbstatus
candidato = servidor
candidato lbstatus -= total factor
Quadro 3: Algoritmo simplificado do método byrequests.
48
O exemplo a seguir mostra um balanceamento em que todos os membros recebem a
mesma quantidade de requisições.
Servidor
S1 S2 S3 S4
Lbfactor
1
1
1
1
Quadro 4: Exemplo de escalonamento byrequests com lbfactor igual a 1.
O escalonamento produzido será: S1 S2 S3 S4... Uma vez que os valores são
normalizados, o escalonamento acima tem o mesmo comportamento a seguir.
Servidor
S1 S2 S3 S4
Lbfactor
25 25 25 25
Quadro 5. Exemplo de escalonamento byrequests com lbfactor igua1 a 25.
Alterando o valor de S2 para 3 informaríamos que o servidor S2 atenderá, em média,
3 vezes mais requisições que S1, S3 e S4.
Servidor
S1 S2 S3 S4
Lbfactor
1 3
1
1
Lbstatus
1 -3
1
1
Lbstatus
-4 0
2
1
Lbstatus
-3 3
-3
3
Lbstatus
-2 0
-2
4
Lbstatus
-1 3
-1
-1
Lbstatus
0
0
0
0
(repetir)
Quadro 6: Exemplo do processo de escalonamento byrequests.
O escalonamento produzido será: S2 S1 S3 S2 S4 S2... A seqüência de distribuição
de requisições se repete após 6 escalonamentos. Se algum servidor estiver indisponível, por
49
exemplo, S3, o algoritmo permite o escalonamento correto entre os demais. O escalonamento
produzido será: S1 S2 S4... . Nenhuma requisição é encaminhada para o servidor S3 e o
escalonamento também não é afetado.
Servidor
S1 S2 S3 S4
Lbfactor
1
1
1
1
Lbstatus
0
0
0
0
Lbstatus
-2
1
0
1
Lbstatus
-1 -1 0
2
Lbstatus
0
0
0
0
(repetir)
Quadro 7: Exemplo do processo de escalonamento byrequests com a exclusão de um nó.
5.2.2. O método Bytraffic
A diretiva lbmethod configurada como bytraffic (lbmethod=bytraffic) habilita este
método. A idéia deste escalonamento é semelhante ao do método byrequests, no entanto,
contabilizando a quantidade de tráfego (bytes entrando e saindo) manipulada por cada
servidor. Este tráfego é normalizado de acordo com o peso de cada servidor no
balanceamento, também definido pela diretiva lbfactor: Quanto maior o valor do lbfactor,
maior a quantidade de tráfego que um servidor irá receber (Mod_proxy_balancer, 2007). No
exemplo a seguir, a configuração indica que o servidor S1 processará um tráfego em bytes
duas vezes maior que S2, S3 e S4.
Servidor
S1 S2 S3 S4
Lbfactor
2
1
1
1
Quadro 8: Exemplo do processo de escalonamento bytraffic.
50
Isto não significa necessariamente que S1 processaria duas vezes mais requisições
que os demais servidores. Assim, o tamanho da requisição e a resposta são aplicados ao
algoritmo de seleção.
curmin = 0
para cada servidor que participa do balanceamento
trafego=(servidor bytes_transferidos /servidor lbfactor) +
(servidor bytes recebidos / servidor lbfactor);
se ( nenhum candidato ou trafego < curmin)
candidato = servidor
curmin =trafego
Quadro 9: Algoritmo simplificado do método bytraffic.
O servidor com menor soma de bytes transferidos e recebidos será o escolhido para
atender a uma requisição entrante.
5.2.3. Monitoramento e Diagrama de Funcionamento
O mod_proxy_balancer possui uma página de gerenciamento, mostrada na figura 10,
que permite verificar e alterar parâmetros de balanceamento, além do monitoramento do
status dos nós membros.
Figura 10: Página de gerenciamento do Mod_proxy_balancer.
51
A Figura 11 apresenta um esquema simplificado do processo de análise de uma
requisição pelo mod_proxy_balancer.
Figura 11: Análise de Requisição com o Mod_proxy_balancer.
Observa-se neste fluxograma que os métodos byrequets e bytraffic estão
implementados no item “Verifica Lbfator e define o melhor nó”. Se após a seleção de um nó,
o mesmo se encontrar indisponível, uma nova seleção será feita.
5.3. Experimentos Preliminares
Visando avaliar o balanceamento de requisições do Apache, na versão 2.2.4,
operando em conjunto com os módulos mod_proxy e mod_proxy_balancer, foram realizados
testes com cada um dos métodos de escalonamento. Os experimentos simularam solicitações
de clientes para o servidor Web, medindo o tempo para atendimento às mesmas. Neste
contexto, para facilitar a investigação, foi necessário pesquisar algumas de ferramentas que
medem o desempenho de servidores Web no atendimento a requisições.
52
5.3.1. Ferramentas Utilizadas
As ferramentas para avaliação de desempenho de sites Web têm por princípio básico
simular requisições de clientes a determinadas URLs e medir o tempo, em segundos ou
milisegundos, que o servidor Web necessita para atendê-las (Barford and Crovella, 1998) (Hu
et al, 1999). Existem inúmeras ferramentas, comerciais e gratuitas. Neste trabalho foram
experimentadas três ferramentas:
• ApacheBench (ApacheBench, 2006): Ferramenta de benchmark desenvolvida pelo
Apache Group para teste da capacidade de atendimento do servidor Web Apache.
Desenvolvido na linguagem Perl, basicamente mostra quantas requisições por
segundo um servidor Web Apache é capaz de atender. Esta ferramenta vem junto
com o código fonte do Apache;
• Http_load (Poskanzer, 2007): Ferramenta de teste de carga desenvolvido pelo
ACME Labs para gerar requisições para um servidor Web. Desenvolvido para
ambiente Unix, manipula requisições HTTP e HTTPS. O http_load executa
múltiplas consultas http em paralelo para testar a capacidade de atendimento
(throughput) do servidor Web. Pode simular conexões com modem de 33,6 kbps
(opção throttle) e permite que seja especificada uma lista de URLs a serem
testadas. Também é possível especificar a quantidade de conexões em paralelo
(opção parallel ) ou o número de requisições geradas por segundo (opção rate). O
tempo de teste pode também ser definido (opção seconds N);
• Httperf (Mosberger, 1998): Aplicativo desenvolvido por David Mosberger do HP
Research Labs. É uma ferramenta similar ao Apachebench, provendo um
mecanismo para geração de requisições HTTP e medindo o desempenho do
servidor Web. Seu código fonte é aberto e é gratuito.
53
As três ferramentas de avaliação de desempenho apresentam características
semelhantes, no entanto cada uma apresentava suas limitações, como tamanho de página
(ApacheBench), número de máximo de requisições (http_load). O httperf atendeu ao requisito
de simular 100.000 requisições de clientes para o servidor Web, informando o tempo
necessário para que tais requisições fossem atendidas, sendo o escolhido para ser utilizado nos
testes.
5.3.2. Ambiente de Teste
Os testes foram realizados no cluster heterogêneo do HPPCA/DIN/UEM que é
composto de um nó mestre – chamado de master - e oito nós escravos – chamados de slave1 a
slave8. A Figura 12 mostra como os equipamentos estão conectados:
Cliente
Switch
Master
Switch
Slave1 Slave2 Slave3
Slave4 Slave5 Slave6
Slave7 Slave8
Figura 12: Diagrama de ligação dos equipamentos no ambiente de teste no cluster HPPCA.
Os equipamentos deste cluster possuem as seguintes configurações:
• Master: Possui um processador ATHLON de 1,0 GHz, com 512 MB de memória
e 20 GB de espaço em disco, com duas interfaces de rede padrão fast ethernet;
• Slave 1 a 4: Possuem processadores Pentium IV HT de 1,8 GHz, com 512 MB de
memória, com uma interface de rede padrão fast ethernet;
54
• Slave 5 a 8: Possuem processadores Pentium IV HT de 3,0 GHz, com 512 MB de
memória, também com uma interface de rede padrão fast ethernet;
A máquina cliente onde foi instalada a ferramenta Httperf possui um Pentium IV HT
de 2.8 GHz, com 256 MB de memória, com duas interfaces de rede padrão fast ethernet. Uma
das interfaces de rede do nó master e da máquina cliente estão conectados aos nós slaves por
um switch 3COM padrão fast ethernet. A outra interface de rede do nó master e da máquina
cliente estão conectados a um switch Encore, também padrão fast ethernet.
5.3.3. Configuração do Mod_proxy_balancer para Testes com Páginas Estáticas e
Dinamicamente Geradas
O Apache com mod_proxy_balancer e PHP foram instalados no nó master, que
passou a desempenhar a função de direcionador de requisições. Os nós slaves ficaram apenas
com o Apache e PHP instalados, que atendiam as requisições HTTP na porta 8080. Nestas
URLs foram colocadas páginas html estáticas e distintas, mas com o mesmo tamanho de 13
Kb (para melhor cercar os experimentos e facilitar a análise dos resultados) e páginas
dinâmicas, em PHP, para o cálculo do número PI. O caminho da requisição foi previamente
definido no arquivo httpd.conf do master.
ProxyPass /din22 balancer://master lbmethod=byrequests
ProxyPassReverse /din22/ http://192.168.1.1:8080/din22/
ProxyPassReverse /din22/ http://192.168.1.2:8080/din22/
ProxyPassReverse /din22/ http://192.168.1.3:8080/din22/
ProxyPassReverse /din22/ http://192.168.1.4:8080/din22/
<Proxy balancer://master/din22>
BalancerMember http://192.168.1.1:8080/din22 loadfactor=1
BalancerMember http://192.168.1.2:8080/din22 loadfactor=1
BalancerMember http://192.168.1.3:8080/din22 loadfactor=1
BalancerMember http://192.168.1.4:8080/din22 loadfactor=1
</Proxy>
Quadro 10: Configuração Mod_proxy_balancer no httpd.conf.
55
O quadro 10 mostra um exemplo de configuração com balanceamento para quatro
servidores Web pelo método byrequests e com fator de balanceamento (loadfactor) igual a 1.
Este mesmo método e fator de balanceamento foram utilizados nos testes descritos a seguir.
Neste trabalho são apresentados os resultados do Httperf, pré-definido para simular 100.000
requisições de clientes para o servidor Web, em termos do tempo necessário para que tais
requisições fossem atendidas.
A Tabela 1 mostra os direcionamentos das requisições recebidas pelo master e
repassadas aos slaves em cada teste realizado, divididos em 3 grupos.
Tabela 1: Direcionamentos das requisições.
Teste
URL
0
http://192.168.1.254:8080/din20/
Servidores para os quais o master repassa as requisições
Usando os slaves mais lentos
1
http://192.168.1.254:8080/din22/
slave1
2
http://192.168.1.254:8080/din22/
slave1; slave2
3
http://192.168.1.254:8080/din22/
slave1; slave2; slave3
4
http://192.168.1.254:8080/din22/
slave1; slave2; slave3; slave4;
Usando os slaves mais rápidos
5
http://192.168.1.254:8080/din23/
slave5
6
http://192.168.1.254:8080/din23/
slave5; slave6
7
http://192.168.1.254:8080/din23/
slave5; slave6; slave7
8
http://192.168.1.254:8080/din23/
slave5; slave6; slave7; slave8
Usando os slaves mais lentos e mais rápidos
9
http://192.168.1.254:8080/din21/
slave1; slave2; slave3; slave4; slave5
10
http://192.168.1.254:8080/din21/
slave1; slave2; slave3; slave4; slave5; slave6
11
http://192.168.1.254:8080/din21/
slave1; slave2; slave3; slave4; slave5; slave6; slave7
12
http://192.168.1.254:8080/din21/
slave1; slave2; slave3; slave4; slave5; slave6; slave7; slave8
Para os testes de redirecionamentos, a URL foi hospedada nos nós slaves e os acessos
foram realizados da máquina cliente que efetua solicitações ao nó master. A cada teste, o
serviço Web do master e dos slaves era inicializado, sendo finalizado após o término do teste.
O arquivo de log era renomeado para ser posteriormente analisado.
56
A Figura 13 mostra um comparativo com o tempo para atendimento às 100.000
requisições às páginas estáticas em cada teste realizado. O teste 0 representa a situação em
que o nó mestre atendeu sozinho às requisições e comparado aos demais, pode-se observar
que o uso do balanceamento aumenta o tempo de resposta. Este fato mostra que o uso do
cluster Web para páginas estáticas se justifica somente para prover maior disponibilidade.
300
Tempo (s)
250
200
150
100
50
0
0
1
2
3
4
5
6
7
8
9
10
11
12
Teste
Figura 13: Tempo de resposta utilizando páginas estáticas pelo método byrequests.
Nos testes de 1 a 4, utilizando apenas as máquinas mais lentas, os tempos de
atendimento são os maiores. Nos testes de 5 a 8, utilizando máquinas mais rápidas, os tempos
são menores. Nos testes de 9 a 12, onde máquinas mais rápidas foram utilizadas em conjunto
com as máquinas mais lentas, os tempos praticamente representavam uma média dos tempos
maiores e menores. Em cada grupo de simulação, os tempos são praticamente os mesmos
entre si, independentemente do número de nós envolvidos no redirecionamento.
Analisando o arquivo de log do Apache, verificou-se que as requisições são
distribuídas igualmente entre os nós participantes do balanceamento, característica do
algoritmo round robin, e que o fator de balanceamento é o mesmo para todos os servidores.
Assim, não importa se o balanceamento possui 1, 2, 3 ou 4 máquinas envolvidas, pois o
tempo é determinado pela velocidade de atendimento do mais lento.
57
O método bytraffic também foi experimentado, nas mesmas condições das
simulações até aqui relatadas para o método byrequests. Entretanto, os tempos obtidos não
foram menores e, de fato, se apresentaram semelhantes aos tempos mostrados na Figura 13.
Uma observação a ser feita e que poderia explicar a inércia do balanceamento na redução do
tempo de atendimento apóia-se no fato de não ter havido qualquer interferência de carga de
rede.
O teste com páginas geradas dinamicamente consistiu na comparação dos tempos
para atendimento para 10 chamadas a uma página PHP que calcula o número pi. O resultado
obtido é mostrado na Figura 14.
350
300
Tempo (s)
250
200
150
100
50
0
0
1
2
3
4
5
6
7
8
9
10
11
12
Teste
Figura 14: Tempo de resposta para páginas dinâmicas pelo método byrequests.
No teste 0, o tempo de atendimento foi mais alto, em média 292 segundos, pois todas
as 10 requisições foram atendidas pelo nó master, que por sua vez tem uma capacidade de
processamento inferior ao dos nós slaves. Nos testes 1 a 4 os tempos são superiores aos dos
testes de 5 a 8, pois a capacidade de processamento dos slaves 1 a 4 é inferior. Nos testes de 9
a 12 pode-se observar que a combinação de máquinas mais rápidas com máquinas mais lentas
gera um tempo de atendimento que representa a média dos tempos de atendimentos destas
duas configurações. Percebe-se que à medida que máquinas mais rápidas passam a participar
58
do balanceamento, o tempo de atendimento diminui. Neste caso, observa-se uma melhora no
desempenho com a utilização do balanceamento de requisições.
5.3.4.Testes com Tráfego de Rede - Sobrecarga Slave-Master Detectada pelo
mod_proxy_balancer
Na tentativa de melhor analisar o módulo mod_proxy_balancer, o mesmo foi
avaliado mediante uma sobrecarga de rede, utilizando-se as configurações dos testes 4 e 8,
com fator de balanceamento igual a 1, para 100.000 requisições as páginas estáticas, mas pelo
método bytraffic. No teste 4, o balanceamento foi feito com os slaves 1 a 4, com menor poder
de processamento e no teste 8 o cluster era composto pelos slaves 5 a 8, de máquinas mais
rápidas. O objetivo foi o de simular a sobrecarga em até 4 nós, com a ajuda do wget, um
programa para efetuar download de arquivos, instalado nos slaves.
Os testes utilizando os slaves 1 a 4 foram realizados ao mesmo tempo em que o
programa wget instalado nos slaves 5 a 8 efetuava downloads de vários arquivos de 1 e 1,5GB
localizados nos slaves 1 a 4. Da mesma maneira os testes utilizando os slaves 5 a 8 foram
realizados com o programa wget instalado nos slaves 1 a 4 que também efetuava downloads
de arquivos de 1 e 1,5 GB. Esta não seria a simulação ideal, pois as máquinas que simulam
clientes efetuando downloads (dependendo do teste slaves 5 a 8 ou slaves 1 a 4) se encontram
no mesmo barramento de rede que terá, teoricamente, o dobro de carga, influindo diretamente
do tempo de atendimento às requisições dos testes. No entanto, este ambiente será o mesmo
para todos os testes realizados com sobrecarga de rede.
Na primeira simulação, baseada no teste 4, somente o slave 5 solicitava o
downloads de arquivos para o master. Na segunda simulação os slaves 5 e 6 solicitavam os
downloads e assim sucessivamente até que na quarta simulação quando os slaves 5, 6, 7 e 8
realizam os downloads. Para cada teste primeiramente eram iniciados os downloads e em
seguida era executada a ferramenta httperf na máquina cliente. O mesmo procedimento foi
59
adotado para os testes utilizando a configuração do teste 8. Os tempos obtidos são
apresentados nas tabelas 2 e 3.
Tabela 2: Tempos de Execução do Teste 4 com Sobrecarga.
Teste
Nó gerando sobrecarga
Tempo (s)
% em relação ao
Teste 4
4.1a
slave5
608,23
233,84
4.1b
slave5, slave6
1997,48
767,95
4.1c
slave5, slave6, slave7
2834,64
1089,81
4.1d
slave5, slave6, slave7, slave8
3264,83
1255,20
Tabela 3: Tempos de Execução do Teste 8 com Sobrecarga.
Nó gerando sobrecarga
Teste
Tempo (s)
% em relação ao
Teste 8
8.1a
slave1
1676,02
702,88
8.1b
slave1, slave2
4155,59
1742,75
8.1c
slave1, slave2, slave3
4989,92
2092,64
8.1d
slave1, slave2, slave3, slave4
5725,49
2401,12
Observa-se que todos os tempos obtidos nos atendimentos foram superiores aos
apresentados na Figura 13 (para o teste 4, aproximadamente 260 segundos e para o teste 8,
238 segundos). Quanto maior o número de nós com sobrecarga, maior o tempo necessário
para o atendimento às requisições, atingindo um aumento máximo acima de 2401,12%. As
requisições foram direcionadas aos slaves de acordo com o volume de tráfego, em bytes, de
cada slave. As tabelas 4 e 5 mostram o número de requisições atendidas pelos slaves nos
testes em uma situação de sobrecarga de tráfego de rede.
Tabela 4: Teste 4 - Nós que executam download e número de requisições atendidas.
Teste
Nó gerando sobrecarga
N° Req.
Slave1
N° Req.
Slave2
N° Req.
Slave3
N° Req.
Slave4
1
86967
5180
7871
4.1a
Slave5
4.1b
slave5, slave6
10644
20941
14506
53934
4.1c
slave5, slave6, slave7
30303
32267
7170
30303
4.1d
slave5, slave6, slave7, slave8
18036
38036
13159
30805
60
Tabela 5: Teste 8 - Nós que executam download e número de requisições atendidas.
Teste
Nó gerando sobrecarga
N° Req.
Slave1
N° Req.
Slave2
N° Req.
Slave3
N° Req.
Slave4
8.1a
slave1
29794
37093
15452
17714
8.1b
slave1, slave2
30926
12034
33187
22197
8.1c
slave1, slave2, slave3
18278
26067
27751
27985
8.1d
slave1, slave2, slave3, slave4
20520
20970
32061
26554
Na tabela 4 observa-se que com somente o slave5 executando downloads, o slave1 só
atendeu 1 requisição, que era a requisição de download. As requisições teste da máquina
cliente foram atendidas pelos slave2, slave3 e slave4. Concluiu-se, portanto, que o método
bytraffic foi efetivo no balanceamento das requisições de acordo com o tráfego de rede de
cada nó. Para melhor identificar o conjunto de testes 4.1 e 8.1, passaremos a chamá-lo de
“Sobrecarga Slave-Master detectada pelo mod_proxy_balancer”.
Em uma nova simulação utilizando com as configurações dos testes 4.1 e 8.1 para o
método byrequests, verificou-se tempos de atendimento superiores e uma análise do arquivo
de log mostrou que neste método as requisições não eram balanceadas, portanto todos os nós
recebiam o mesmo número de requisições. Já no método bytraffic, as requisições e os
downloads eram distribuídos entre todos os nós que participam do balanceamento,
respeitando a regra do respectivo método.
5.3.5.Testes com Tráfego de Rede - Sobrecarga Slave-Master não Detectada pelo
Mod_proxy_balancer
A
próxima
simulação
vislumbrou
verificar
o
comportamento
do
mod_proxy_balancer na configuração em que o Apache possui um direcionamento específico,
que não se deseja balancear. Tal situação pode ocorrer quando não temos um armazenamento
de dados centralizado (uma storage, por exemplo) e existe heterogeneidade entre os
servidores Web participantes do cluster, principalmente em relação à capacidade de
processamento e armazenamento. Os arquivos de programas executáveis para download, por
61
exemplo, que ocupam muito espaço e que não são freqüentemente acessados, poderiam estar
armazenados em somente uma máquina do cluster. A configuração a ser feita no Apache para
a referida situação é mostrada no quadro 11.
ProxyPass /download1 http://192.168.1.1:8080/download1/
ProxyPassReverse /download1/ http://192.168.1.1:8080/download1/
ProxyPass /download2 http://192.168.1.2:8080/download2/
ProxyPassReverse /download2/ http://192.168.121:8080/download2/
ProxyPass /download3 http://192.168.1.3:8080/download3/
ProxyPassReverse /download3/ http://192.168.1.3:8080/download3/
ProxyPass /download4 http://192.168.1.4:8080/download4/
ProxyPassReverse /download4/ http://192.168.1.4:8080/download4/
ProxyPass /download5 http://192.168.1.5:8080/download5/
ProxyPassReverse /download5/ http://192.168.1.5:8080/download5/
ProxyPass /download6 http://192.168.1.6:8080/download6/
ProxyPassReverse /download6/ http://192.168.1.6:8080/download6/
ProxyPass /download7 http://192.168.1.7:8080/download7/
ProxyPassReverse /download7/ http://192.168.1.7:8080/download7/
ProxyPass /download8 http://192.168.1.8:8080/download8/
ProxyPassReverse /download8/ http://192.168.1.8:8080/download8/
Quadro 11. Configuração do apache para um direcionamento específico.
Os testes executados foram similares aos testes 4.1a, 4.1b, 4.1c, 4.1d, 8.1a, 8.1b,
8.1c, 8.1d, no entanto, os slaves de 5 a 8 e de 1 a 4 executavam downloads de arquivos que só
existiam nos slaves 1 a 4 e 5 a 8, respectivamente Os resultados obtidos são mostrados nas
tabelas 6 e 7.
Tabela 6: Tempos com download de arquivos específicos nos slaves 1 a 4
Teste Nó com sobrecarga
Tempo (s)
% em relação ao
Teste 4
% em relação aos
Testes 4.1a a 4.1d
4.2a
slave1
1862,56
716,08
306,22
4.2b
slave1, slave2
3992,21
1534,85
199,86
4.2c
slave1, slave2, slave3
5989,90
2302,89
211,31
4.2d
slave1, slave2, slave3, slave4
6660,27
2560,62
204,00
62
Tabela 7: Tempos com download de arquivos específicos nos slaves 5 a 8.
Teste Nó com sobrecarga
Tempo (s)
% em relação ao
Teste 8
% em relação aos
Testes 8.1a a 8.d
8.2a
slave5
3653,28
1532,09
217,97
8.2b
slave5, slave6
5500,62
2306,82
132,37
8.2c
slave5, slave6, slave7
4492,50
1884,04
90,03
8.2d
slave5, slave6, slave7, slave8
7201,43
3020,09
125,78
Após a execução destes testes, verificou-se que o tempo para atendimento as
requisições aumentou muito em relação aos testes 4 e 8, chegando a mais de 3000%. Já em
relação aos testes 4.1a, 4.1b, 4.1c e 4.1d, houve um aumento de mais de 300% para o primeiro
teste e e em torno de 200% para os demais. O mesmo ocorre em relação aos testes 8.1a, 8.1b,
8.1c e 8.1d, com aumentos de aproximadamente 200%, 130%, 90% e 125%, respectivamente.
Tais situações ocorreram pelo fato dos nós com sobrecarga continuarem recebendo o mesmo
número de requisições. O tráfego a mais decorrente dos downloads nos slaves não foi
computado no balanceamento, pois no log de acesso de cada um dos 4 slaves constava 1/4
(um quarto) do total de requisições, ficando o tempo de atendimento das requisições
condicionado ao tempo do nó mais lento.
Desta maneira, conclui-se que o Apache com o mod_proxy_balancer executa um
balanceamento efetivo de requisições quando os direcionamentos se encontram declarados em
suas diretivas, não percebendo o tráfego de dados que até “passa” pelo Apache, mas não é
controlado pelo mod_proxy_balancer. Isto ocorre porque a contabilização de tráfego, em
bytes, é feita somente dentro do módulo e direcionamentos feitos por outros módulos, como o
mod_proxy, não são considerados para o balanceamento. Também para facilitar a
identificação dos testes, passamos a chamar o conjunto de testes 4.2 e 8.2 de “Sobrecarga
Slave-Master não detectada pelo mod_proxy_balancer”.
Os tempos obtidos são superiores aos dos testes com sobrecarga slave-master
detectada pelo mod_proxy_balancer, pois os downloads não são balanceados.
63
5.3.6.Testes com Tráfego de Rede - Sobrecarga Slave-Slave não Detectada pelo
Mod_proxy_balancer
Como visto no início deste capítulo, o mod_proxy_balancer atualmente só possuí
dois métodos de balanceamento: o byrequests e o bytraffic. Estes verificam se o nó está ou
não ativo, mas nenhum deles considera fatores como utilização de CPU ou memória antes da
distribuição de requisições.
Neste conjunto de testes, simulou-se o aumento de carga de cpu nos nós slaves
através de solicitações de downloads efetuadas de slave para outro slave. As configurações
dos testes 4 e 8 foram novamente utilizadas.
Para simulação de aumento de carga de CPU e conseqüentemente I/O de rede, um
slave executava downloads de arquivos de 1Gb e 1,5Gb diretamente em outro slave. No teste
4.3a, o slave1 era avaliado ao mesmo tempo em que o slave5 executava downloads de
arquivos dele. No teste 4.3b, a sobrecarga foi feita nos slave1 e slave2 com os slave5 e slave6
executando downloads neles, e assim sucessivamente até o teste 4.3d, no qual havia uma
sobrecarga nos slaves 1 a 4, com os slave5 a 8 executando downloads. Tais configurações de
testes se repetiram para o conjunto de testes 8.3. Os tempos obtidos são mostrados nas tabelas
8 e 9.
Tabela 8: Tempos de Execução do Teste 4 com Sobrecarga Slave – Slave.
Teste Nó com sobrecarga
Tempo (s)
% Aumento em
relação ao Teste 4
4.3a
slave1
421,75
162,14
4.3b
slave1, slave2
628,07
241,47
4.3c
slave1, slave2, slave3
1465,11
563,28
4.3d
slave1, slave2, slave3, slave4
1357,14
521,77
Nesta simulação, também se observa que todos os tempos obtidos nos
atendimentos foram superiores aos apresentados para os testes 4 e 8.
64
Tabela 9: Tempos de Execução do Teste 8 com Sobrecarga Slave – Slave.
Teste Nó com sobrecarga
Tempo (s)
% Aumento em
relação ao Teste 8
8.3a
slave5
396,47
166,27
8.3b
slave5, slave6
612,80
256,99
8.3c
slave5, slave6, slave7
592,19
248,35
8.3d
slave5, slave6, slave7, slave8
756,36
317,20
O tempo necessário para o atendimento às requisições aumenta de maneira
proporcional ao número de nós com sobrecarga, atingindo um aumento máximo acima de
563,28%. Confirmando aquilo que havia sido previsto, as cargas externas também não foram
computadas no balanceamento, pois, assim como no conjunto de testes 4.2 e 8.2, o log de
acesso de cada um dos 4 slaves envolvidos no balanceamento mostrava que havia sido
atendido 1/4 (um quarto) do total de requisições. As máquinas com maior utilização de CPU
receberam o mesmo número de requisições que as máquinas sem sobrecarga. Identificamos o
conjunto de testes 4.3 e 8.3 como “Sobrecarga Slave-Slave não detectada pelo
mod_proxy_balancer”.
Os tempos obtidos são melhores que os dos demais testes, pois o tráfego gerado é
externo ao nó master, não concorrendo diretamente com as requisições geradas pela
ferramenta httperf.
5.3.7. Sobrecarga Slave-Slave não Detectada pelo Mod_proxy_balancer - Exclusão do nó
com Sobrecarga
No intuito de obter os tempos ideais para o conjunto de testes 4.3 e 8.3, foi simulada
a situação em que os nós com sobrecarga são excluídos do balanceamento. Os tempos obtidos
são mostrados na Figura 15. Como podemos observar os tempos ideais para a sobrecarga
slave-slave não detectada pelo mod_proxy_balancer são muito próximos aos dos testes 4 e 8,
comprovando que o isolamento dos nós com sobrecarga traz benefícios no tempo para
atendimento das requisições.
65
Bytraffic
350
300
Tempo (s)
250
200
150
100
50
0
4.4a
4.4b
4.4c
8.4a
8.4b
8.4c
Teste
Figura 15: Tempo de resposta ideal para o conjunto de teste 4.3 e 8.3.
5.4. Novos Métodos para o Mod_proxy_balancer
A partir da análise dos resultados dos testes, verificou-se que os métodos de
balanceamento do mod_proxy_balancer poderiam ser aprimorados considerando-se algumas
informações como:
• Tráfego de dados de outros direcionamentos controlados pelo Apache e;
• Carga de CPU, memória, I/O dos nós do cluster;
Inicialmente, pensou-se em aprimorar o método bytraffic fazendo com que ele
considerasse o tráfego de rede gerado por direcionamentos do mod_proxy. Criou-se então o
método byallproxytraffic, que basicamente foi uma modificação do método bytraffic.
5.4.1. O Método ByAllProxyTraffic
Uma vez que o módulo mod_proxy_balancer deriva do módulo mod_proxy, as
informações deste são acessíveis pelo módulo mais especializado. Durante o processo de
seleção de um nó para o encaminhamento de requisições, soma-se o tráfego do host, em bytes,
contabilizado pelo mod_proxy_balancer ao tráfego de todos os outros direcionamentos do
mod_proxy que tenham este mesmo host como destino. Após esta contabilização, o nó que
66
tiver o menor volume de tráfego será o escolhido. O algoritmo simplificado para este método
é mostrado no quadro 12.
curmin = 0
para cada servidor que participa do balanceamento
transf = servidor bytes_transferidos;
read =servidor bytes recebidos;
worker = primeiroservidor do conjunto de servidores (mod_proxy)
para (j = 0; j < qtde de servidores; j++) {
se ( worker.hostname =servidor.hostname)
transf = transf + worker1 bytes_transferidos;
read = read +worker1 bytes recebidos;
worker1++;
trafego=( transf /servidor lbfactor) +
( read / servidor lbfactor);
se ( nenhum candidato ou trafego < curmin)
candidato = servidor
curmin =trafego
Quadro 12: Algoritmo simplificado do método byallproxytraffic.
Na simulação com sobrecarga slave-master detectada pelo mod_proxy_balancer, o
método byallproxytraffic apresentou praticamente os mesmos resultados mostrados nas
tabelas 2 e 3 para o conjunto de testes 4.1 e 8.1. Os cálculos para determinação do total de
tráfego nos módulos mod_proxy e mod_proxy_balancer não significaram perda de
desempenho em relação ao método bytraffic.
Já no conjunto de testes 4.2 e 8.2, anteriormente denominada sobrecarga slavemaster não detectada pelo mod_proxy_balancer verificamos uma significativa melhora nos
tempos, conforme mostra a Figura 16. No entanto, para o teste de sobrecarga slave-slave não
detectada pelo mod_proxy_balancer, o método byallproxytraffic, como era de se esperar, não
identificou possíveis cargas de processamento nos nós slaves. Os tempos ficaram muito
próximos aos do método bytraffic.
Tempo (s)
67
7700
7000
6300
5600
4900
4200
3500
2800
2100
1400
700
0
Bytraffic
Byallproxytraffic
4.2a
4.2b
4.2c
4.2d
8.2a
8.2b
8.2c
8.2d
Teste
Figura 16: Comparação tempos método bytraffic e byallproxytraffic.
Era necessário criar um método que conseguisse obter esta informação do estado dos
slaves para depois tomar a decisão de redirecionamento de requisições. A inspiração veio dos
trabalhos de Eager (Eager, 1985), Nilson (Nilson, 2005) e do projeto Mod_Backhand
(Schlossnagle,2000). A partir do estudo destes trabalhos, decidiu-se criar um novo método de
balanceamento: o Byquery.
5.4.2. O Método Byquery
O método consiste da verificação de quanto um nó está sem processamento de CPU
(ocioso - idle), para tomada de decisão de balanceamento. Os nós mais ociosos, ou seja, com
menos carga de CPU, atenderão mais requisições. A informação sobre quanto um nó está
ocioso é fornecida pelo serviço (daemon) servidor em conjunto com o programa sysidle. O
sysidle foi desenvolvido a partir da ferramenta de monitoramento de desempenho chamada
sysstat (Sysstat, 2007). Um de seus módulos, o mpstat, fornece informações de utilização de
um processador específico ou de todos da máquina em tempo real. O quadro 13 mostra o
exemplo de utilização deste programa.
Em sistemas com múltiplos processadores, o mpstat permite exibir a utilização de
cada CPU separadamente, possibilitando determinar a utilização efetiva de cada CPU.
68
Observa-se também que a máquina master possui apenas um processador, chamado de CPU
0. A linha all, mostra a média dos valores da(s) CPU(s) para cada campo de informação. O
mpstat foi modificado para trazer somente a informação do campo idle da linha all em valores
inteiros.
#mpstat -P ALL
Linux 2.4.29-1smp (master.cluster)
07/09/2007
07:34:12 PM CPU %user %nice %system %idle
intr/s
07:34:12 PM
all
3.67
0.01
10.99
85.34
724.70
07:34:12 PM
0
3.67
0.01
10.99
85.34 724.70
Quadro 13. Exemplo de utilização do comando mpstat.
O serviço chamado servidor é um programa que aceita conexões TCP na porta 3054,
executando o programa sysidle e retornando a informação de ociosidade do sistema para o
cliente que efetuou a conexão. Após testados, os dois programas foram instalados nos nós
slaves.
O próximo passo foi implementar o método byquery no mod_proxy_balancer. O
novo método utiliza o mesmo conceito do método byrequests, no entanto, em vez de
contabilizar as requisições foi utilizada a porcentagem de ociosidade de cada nó.
A cada intervalo de tempo, a ser discutido posteriormente, o nó master se conecta
aos nós slaves solicitando a informação de ociosidade. Este valor é multiplicado pelo fator de
balanceamento para a quota de trabalho de cada nó naquele determinado momento. Essa
multiplicação se faz necessária para manter a proporcionalidade na distribuição de requisições
especificada pelo fator de balanceamento.
O quadro 14 mostra o princípio de funcionamento do método byquery. No exemplo
mostrado a seguir, analisamos o funcionamento do algoritmo. Todos os membros têm,
hipoteticamente, 100% de CPU ociosa e recebem a mesma quantidade de requisições.
69
para cada servidor que participa do balanceamento
carga_idle_cpu = 0
se intervalo
carga_idle_cpu = verifica_carga_idle servidor
se carga_idle_cpu = 0
servidor lbstatus += servidor lbfactor*carga_idle_cpu
total factor += servidor lbfactor*carga_idle_cpu
senão
servidor lbstatus += servidor lbfactor
total factor += servidor lbfactor
se servidor lbstatus > candidato lbstatus
candidato = servidor
candidato lbstatus -= total factor
(repetir)
Quadro 14: Algoritmo simplificado de funcionamento o método byquery.
O escalonamento produzindo no exemplo do quadro 15 é S1 S2 S3 S4..., com todos
os nós recebendo o mesmo número de requisições.
Servidor
S1
S2
S3
S4
Lbfactor
1
1
1
1
Lbstatus
-300 100
100
100
Lbstatus
-200 -200
200
200
Lbstatus
-100 -100 -100
300
Lbstatus
0
0
0
0
(repetir)
Quadro 15: Exemplo do processo de escalonamento byquery.
Alterando o fator de balanceamento de S2 para 2 e também com 100% de CPU
ociosa, teríamos a seguinte distribuição de requisições mostrada no quadro 16.
70
Servidor
S1
S2
S3
S4
Lbfactor
1
2
1
1
Lbstatus
100 -300
100
100
Lbstatus
-300 -100
200
200
Lbstatus
-200
100 -200
300
Lbstatus
-100
300 -100 -100
Lbstatus
0
0
0
0
Lbstatus
100 -300
100
100
Lbstatus
-300 -100
200
200
Lbstatus
-200
100 -200
300
Lbstatus
-100
300 -100 -100
Lbstatus
0
0
0
0
(repetir)
Quadro 16: Escalonamento byquery com S2 atendendo o dobro de requisições
Esta configuração produziu o seguinte escalonamento: S2 S1 S3 S4 S2 S2 S1 S3 S4
S2.... Pode-se verificar que S2 atendeu o dobro de requisições dos demais. No próximo
exemplo, quadro 17 supõe-se que S2 está indisponível ou com 100% de utilização de cpu e os
demais nós com 100% de CPU ociosa.
Servidor
S1
S2
S3
S4
Lbfactor
1
1
1
1
Lbstatus
-200
0
100
100
Lbstatus
-100
0 -100
200
Lbstatus
0
0
0
0
(repetir)
Quadro 17: Escalonamento byquery - S2 indisponível ou com 100% de carga de CPU.
O escalonamento produzido foi S1 S3 S4.... Nenhuma requisição foi encaminhada
para S2 e o escalonamento continuou correto. O exemplo a seguir mostra uma configuração
em que S1, S3 e S4 possuem 100% de CPU ociosa e S2 está com 50% de CPU ociosa.
71
Observando o quadro 18, verifica-se que o escalonamento produzido foi S1 S3 S4 S2 S1 S3
S4 S2 S1
Servidor
S1
S2
S3
S4
Lbfactor
1
1
1
1
Lbstatus
-250
50
100
100
Lbstatus
-150
100 -150
200
Lbstatus
-50
150
-50
-50
Lbstatus
50 -150
50
50
Lbstatus
-200 -100
150
150
Lbstatus
-100
-50 -100
250
Lbstatus
0
0
0
0
Lbstatus
-250
50
100
100
Lbstatus
-150
100 -150
200
Lbstatus
-50
150
-50
-50
Lbstatus
50 -150
50
50
150
150
Lbstatus -200
-100
…
Quadro 18: Escalonamento byquery - S2 com 50% de carga de CPU.
Apesar de S2 estar sobrecarregado, muitas requisições ainda são enviadas para este
nó. Tal fato pode ser comprovado através da execução do testes 4.3, no qual os tempos
obtidos pelo método byquery foram muito similares aos dos métodos byrequests e bytraffic. A
Figura 17 apresenta um gráfico comparativo dos tempos dos 3 métodos.
2100
1800
Tempo (s)
1500
byrequest
1200
bytraffic
900
byquery
600
300
0
4.3a
4.3b
4.3c
4.3d
Teste
Figura 17: Tempo de resposta utilizando o método byquery.
72
Como visto nos testes já realizados, o tempo de atendimento total a um conjunto de
requisições fica condicionado ao tempo de atendimento do nó mais lento. Visando evitar o
envio de requisições para nós com sobrecarga, decidiu-se que a partir de uma certa
porcentagem de utilização de CPU, este nó seria considerado indisponível. No entanto, era
necessário definir qual seria esta porcentagem ideal. Paralelamente a isto, também era
necessário definir o intervalo de tempo para realização das consultas aos nós do cluster. Um
intervalo muito grande poderia não conseguir identificar situações de sobrecarga de CPU e
intervalos muito pequenos poderiam gerar overhead.
Primeiramente, decidiu-se investigar a influência que o intervalo de consulta aos nós
slaves teria sobre o tempo total de atendimento. Para isto, foi utilizada a configuração do teste
8, no qual os direcionamentos são para os slaves 5 a 8, sem sobrecarga, com 100.000
requisições solicitadas. Os intervalos de consulta foram de 5, 10, 15, 20, 30 e 60 segundos. Os
tempos obtidos com a ferramenta httperf são mostrados na Figura 18.
350
300
Tempo (s)
250
200
150
100
50
0
5s
10s
15s
20s
30s
60s
Intervalo
Figura 18: Tempo de resposta utilizando o método byquery em intervalos de tempo fixo.
Observa-se que intervalos muito pequenos (5 s) geram demora no atendimento às
requisições, sendo descartados dos próximos testes. E apesar do intervalo de tempo de 60s
possuir o melhor resultado, este também foi descartado por ser considerado muito grande.
Para a continuidade dos testes, os intervalos de tempo 10s, 15s, 20s e 30s foram combinados
73
com 75%, 80%, 85%, 90% e 95% de ociosidade de CPU. Conforme pode se observar na
Figura 19 o melhor intervalo de tempo para consulta aos slaves foi de 15 segundos e as
melhores porcentagens foram de 90% e 95%, que representa 10% e 5% de utilização de CPU.
Sendo 10% de utilização de CPU um valor que melhor represente um cenário de sobrecarga,
decidiu-se que com menos de 90% de ociosidade um nó é considerado com sobrecarga.
600
Tempo (s)
500
400
10s
15s
300
20s
200
30s
100
0
75
80
85
90
95
Ociosidade da CPU (%)
Figura 19: Tempo de resposta com método byquery. Intervalo x ociosidade da CPU.
5.4.3. Comparação do Método Byquery com os Métodos já Existentes
Definidos estes valores, iniciou-se os testes para verificar a validade do novo
método. Inicialmente, os direcionamentos indicados na Tabela 1 foram efetuados com o
método byquery e os tempos registrados. A Figura 20 mostra um gráfico comparativo dos
tempos. Observa-se que os tempos médios obtidos pelo método byquery (270s) foram
superiores aos dos demais métodos (250s).
Isto se deve ao tempo utilizado pelo método durante a consulta de ociosidade de
CPU nos nós slaves. Em uma situação de normalidade, sem nenhuma sobrecarga nos slaves, o
método byquery não se mostrou vantajoso.
74
300
Tempo (s)
250
200
Byrequest
150
Bytraffic
Byquery
100
50
0
1
2
3
4
5
6
7
8
9
10
11
12
Teste
Figura 20: Tempos pelos métodos byrequests, bytraffic e byquery.
As próximas simulações utilizaram o conjunto de testes identificados como
“Sobrecarga Slave-Master detectada pelo mod_proxy_balancer”, “Sobrecarga Slave-Master
não detectada pelo mod_proxy_balancer” e “Sobrecarga Slave-Slave não detectada pelo
mod_proxy_balancer”.
A Figura 21 mostra um gráfico comparativo dos tempos para atendimento das
100.000 requisições, obtidos pelos métodos byrequests, bytraffic e byquery na situação de
sobrecarga slave-master detectada pelo mod_proxy_balancer, no qual o nó master detecta
Tempo (s)
sobrecarga de tráfego de rede.
8000
7200
6400
5600
4800
4000
Byrequests
Bytraffic
3200
2400
1600
800
0
Byquery
4.1a
4.1b
4.1c
4.1d
8.1a
8.1b
8.1c
8.1d
Teste
Figura 21: Tempos pelos métodos byrequests, bytraffic e byquery nos testes 4.1 e 8.1.
75
Neste comparativo observa-se que o método byrequests não é a configuração
apropriada para esta situação. O método byquery possui desempenho superior ao método
bytraffic nos testes 8.1b e 8.1d, desempenho similar para os testes 4.1a, 4.1b, 4.1d. No
entanto, para os testes 4.1c, 8.1a e 8.1c seu desempenho ficou aquém do desejado. Apesar do
melhor desempenho em alguns testes, percebe-se que o overhead gerado pela consulta
freqüente de status dos nós slaves gera uma perda de desempenho em relação ao método
bytraffic.
A próxima simulação executa a sobrecarga slave-master não detectada pelo
mod_proxy_balancer, definida pelo conjunto de testes 4.2 e 8.2. Os resultados obtidos
também são comparados com os dos métodos byrequests e bytraffic, conforme mostra a
Figura 22.
8000
7200
Tempo (s)
6400
5600
Byrequests
4800
4000
3200
Bytraffic
Byquery
2400
1600
800
0
4.2a
4.2b
4.2c
4.2d
8.2a
8.2b
8.2c
8.2d
Teste
Figura 22: Tempos pelos métodos byrequests, bytraffic e byquery nos testes 4.2 e 8.2.
Nesta figura observamos o melhor desempenho do método byquery em todo o
conjunto de testes 4.2 e 8.2. Os tempos obtidos são em média 30% menores, para o melhor
caso, e os tempos são similares no pior caso. A descoberta de nós com sobrecarga de CPU foi
benéfica ao mod_proxy_balancer como pode ser constatado através da análise do log de
acesso do Apache (slaves) nos testes 4.2a a 4.2d.
76
Tabela 10: Nós que executam download e número de requisições atendidas – byquery.
Teste
Nó gerando sobrecarga
N° Req.
Slave1
N° Req.
Slave2
N° Req.
Slave3
N° Req.
Slave4
4.2a
Slave5
217
22588
30206
47101
4.2b
slave5, slave6
90
101
41889
57962
4.2c
slave5, slave6, slave7
280
260
108
99309
4.2d
slave5, slave6, slave7, slave8
30564
15945
50
53485
Na tabela 10, observa-se que as requisições são encaminhadas normalmente para os
nós com menos utilização de CPU.
No último teste, com todos os nós sobrecarregados, verifica-se uma distribuição
aleatória de requisições. O último conjunto de testes, 4.3 e 8.3 – sobrecarga slave-slave não
detectada pelo mod_proxy_balancer teve por objetivo simular uma sobrecarga de CPU nos
nós slaves. Tal situação pode ocorrer em um cluster não-dedicado exclusivamente ao serviço
Web, no qual aplicações paralelas podem estar sendo executadas concorrentemente. Nesta
situação, obtiveram-se os resultados apresentados na Figura 23.
2000
Tempo (s)
1800
1600
1400
1200
1000
800
Byrequests
Bytraffic
Byquery
600
400
200
0
4.3a
4.3b
4.3c
4.3d
8.3a
8.3b
8.3c
8.3d
Teste
Figura 23: Tempos pelos métodos byrequests, bytraffic e byquery nos testes 4.3 e 8.3.
Os tempos obtidos pelos testes 4.3a, 4.3b, 8.3a e 8.3b são muito próximos aos
tempos de uma situação sem sobrecarga, para o método byquery, em torno de 5% superiores.
Comparando-se com o método bytraffic, a melhora chega a 65% no melhor caso (4.3c) e 8%
no pior caso (8.3d).
77
6. CONCLUSÕES E TRABALHOS FUTUROS
Os estudos preliminares se concentraram na avaliação de clusters Web trabalhando na camada
de aplicação, na qual a própria aplicação – no caso o Apache em conjunto com
mod_proxy_balancer – se encarregava de realizar o direcionamento das requisições.
Conforme a Figura 13, a existência de um redirecionador (web switch ou despachante)
representa um acréscimo de tempo no atendimento às requisições a páginas estáticas. No
entanto, se existir a necessidade de algum processamento de informação para a geração de
páginas dinâmicas, esta configuração é benéfica, aumentando, além da disponibilidade, o
desempenho no atendimento às requisições.
O redirecionamento provido pelo Apache+mod_proxy_balancer consegue verificar
se o servidor nó está disponível para atender requisições. Caso não esteja, ele é
automaticamente excluído do balanceamento e incluído quando seu status indica normalidade.
O método de balanceamento, por quantidade de requisição (byrequests) e por quantidade de
sobrecarga de tráfego (bytraffic), deve ser previamente definido no arquivo de configuração
do Apache, assim como o fator de balanceamento. Se o fator de balanceamento indicar
distribuição igual de requisições entre os nós, todos os servidores receberão o mesmo número
de requisições. Assim, o redirecionador deverá aguardar que o servidor mais lento receba sua
requisição para depois distribuir uma nova requisição para outro servidor.
Três tipos de testes foram executados visando avaliar estes métodos de
balanceamento, posteriormente denominados: 1 - sobrecarga slave-master detectado pelo
mod_proxy_balancer; 2 – sobrecarga slave-master não detectado pelo mod_proxy_balancer e
3 – sobrecarga slave-slave não detectado pelo mod_proxy. No primeiro teste, no qual os
direcionamentos se encontram declarados em suas diretivas, o mod_proxy_balancer através
do método bytraffic, detectou um aumento no tráfego de rede, balanceando as requisições de
acordo com a quantidade de bytes recebida por cada nó. O segundo teste mostrou que o
78
tráfego gerado por direcionamentos de outros módulos não são considerados pelo
mod_proxy_balancer. No exemplo utilizado, o tráfego de dados gerado por direcionamentos
do módulo mod_proxy não é considerado, pois a contabilização, em bytes, é independente em
cada módulo. O terceiro teste simulou a situação de sobrecarga de CPU, comum em clusters
não dedicados exclusivamente ao serviço Web. Para simular a sobrecarga, alguns slaves
executavam downloads de arquivos diretamente de outros slaves. Também para esta situação,
nenhum dos módulos do mod_proxy_balancer detectou a sobrecarga, pois as requisições
foram distribuídas igualmente entre todos os nós.
Visando solucionar este problema, dois métodos foram criados: o byallproxytraffic e
o byquery. O primeiro método foi uma modificação do método bytraffic para que
contabilizasse também o tráfego de dados do módulo mod_proxy. Este método detectou o
tráfego de direcionamentos mod_proxy, contabilizando o mesmo para a decisão de
balanceamento. Os tempos foram melhores que o do mod_proxy_balancer, mas como era de
se esperar, não apresentou melhora para o teste 3. Para solucionar este problema, criou se
então o método byquery, que verifica a ociosidade de CPU dos slaves para decisão de
direcionamento. Foram criados serviços que executados nos nós slaves, permitem a consulta
da ociosidade da cpu através de uma conexão TCP na porta 3054. O novo método apresentou
melhora no tempo de atendimento às requisições, principalmente nos testes 2 e 3.
Apesar de aumentar a disponibilidade, pois mais de um servidor Web responde por
um serviço, a existência de um elemento que centraliza o recebimento de requisições
representa um “gargalo” na transferência de dados e um ponto único de falha (SPOF – Single
Point of Failure). Uma solução para este problema é prover alguma forma de redundância
através de combinações de técnicas como Sistema Web Distribuído e Cluster Web.
Uma melhoria para o método byquery seria a utilização de outros parâmetros, como
utilização de memória e I/O de rede para verificar se um nó está ou não sobrecarregado, bem
79
como, o tempo utilizado para o repasse da requisição para cada nó do cluster. Outra melhoria
seria a atualização dinâmica do valor do intervalo de tempo para consulta de informações dos
nós. Também seria interessante avaliar a utilização do protocolo UDP para troca de
informações bem como a comunicação multicast.
80
REFERÊNCIAS BIBLIOGRÁFICAS
Akamai Technologies, Inc. "Akamai". Disponível em http://www.akamai.com/. Acessado em
01 de agosto 2007
Andreolini,M., Colajanni M. and Morselli M.” Performance study of dispatching algorithms
in multi-tier Web architectures”. SIGMETRICS Performance Evaluation Review 30(2):
pag.10-20, 2002.
ApacheBench. “AB-Apache HTTP server benchmarking tool”. Disponível
http://httpd.apache.org/docs/2.2/programs/ab.html. Acessado em 02 de abril de 2006.
em
Apostolopoulos, G., Aubespin, D., Peris, V.G.J., Pradhan, P., and Saha, D.
“Design,implementation and performance of a content-based switch”. In INFOCOM,
1117-1126, 2000.
Aversa, L. and Bestavros, A. “Load balancing a cluster of Web servers using Distributed
Packet Rewriting”. In Proceedings of the 19th IEEE International Performance,
Computing, and Communication Conference (Phoenix, AZ, Feb.). IEEE Computer, 2000
Baker, Mark. “Cluster Computing White Paper”. University of Portsmouth, UK, Dez. 2000.
Barford, P. and Crovella M. “Generating representative Web workloads for network and
server performance evaluation,” in Measurement and Modeling of Computer Systems, p.
151-160 1998.
Beowulf. “Beowulf”. Disponível em http://www.beowulf.org/overview/index.html. Acessado
em 01 de julho de 2007.
Berners-Lee, T., Fielding, R., and Frystyk,H. “Hypertext Transfer Protocol HTTP/1.0”. RFC
1945 (Informational), Maio 1996.
Buyya, R. "High Performance Cluster Computing: Architectures and Systems", vol. 1,
Prentice-Hall,1999.
Cardellini, V., Colajanni, M., AND YU, P. S. “Dynamic load balancing on Web-server
systems”. IEEE Internet Computing 3, 3 (May/June), p. 28–39, 1999.
Cardellini, V., Casalicchio, E., Colajanni, M. and Yu, P. S. “The State of the Art in Locally
Distributed Web-Server Systems”, ACM Computing Surveys, p. 263-311, 2002.
Cherkasova,L.. “FLEX: Load balancing and management strategy for scalable Web hosting
service”. In Proceedings of the Fifth International Symposium on Computers and
Communications (ISCC'00), pages 8--13, July 2000.
Cisco System, Inc. "Cisco CSS 11500 Series Content Services Switch". Disponível em
http://www.cisco.com/en/US/products/hw/contnetw/ps792/index.html. Acessado em 01 de
agosto 2007.
Colajanni, M. and Yu, P.S. “Adaptive TTL schemes for load balancing of distributed Web
servers”. ACM Sigmetrics Performance Evaluation Review, 25(2):36-42, Setembro 1997.
Eager, Derek L., Lazowska, Edward D. and Zahorjan, John. "A Comparison of ReceiverInitiated and Sender-Initiated Adaptive Load Sharing". ACM SIGMETRICS Performance
Evaluation Review. Vol. 13(2), pag. 1-3, 1985
F5Networks, Inc. "BIG-IP". Disponível em http://www.f5.com/products/bigip/. Acessado em
01 de agosto 2007.
81
Fondry Networks. "ServerIron".Disponível em http://www.foundrynet.com/products/appswitch/. Acessado em 01 de agosto 2007
Foundation, T. A. S, “Apache HTTP Server Documentation”.
http://httpd.apache.org/docs/. Acessado em 22 de março 2006.
Disponível
Hochstetler, S., Beringer, B. Linux Clustering with CSM and
http://www.redbooks.ibm.com/redpieces/pdfs/sg246601.pdf, Redbooks, 2003
em
GPFS.
Hu, Y., Nanda, A. and Yang, Q.. “Measurement, Analysis and Performance Improvement of
Apache Web Server”. Proceedings of the IEEE International Performance, Computing,
and Communications Conference, Feb. 1999.
IBM.
"IBM
WebSphere
Edge
Server".
Disponível
em
http://www306.ibm.com/software/Webservers/edgeserver/. Acessado em 01 de agosto 2007.
Iyengar, A., Challenger, J. Dias, D. and Dantzig, P. “High performance Web site design
techniques” IBM Thomas J. Watson Res. Center, Yorktown Heights, NY; p. 17-26,
Mar/Apr 2000.
Li, Quanzhong, Moon, Bongki. "Distributed Cooperative Apache Web Server". Proceedings
of the 10th International World Wide Web Conference, Hong Kong, May 2001
LVS - Linux Virtual Server Project “Linux Virtual Server Documentation” Disponível em
http://www.Linuxvirtualserver.org. Acessado em 02 de maio de 2006.
Marwah, M., Mishra, S. and Fetzer, C. “Fault-Tolerant and Scalable TCP Splice and Web
Server Architecture”. Technical Report. Department of Computer Science, University of
Colorado, Boulder, CO. Number: CU-CS-1003-06, jan 2006.
Microsoft
Corporation.
"Network
Load
Balancing".
Disponível
em
http://www.microsoft.com/technet/prodtechnol/windows2000serv/deploy/confeat/nlbovw.
mspx. Acessado em 01 de agosto 2007.
Mockus, A., R. Fielding, and J. Herbsleb. “A Case Study of Open Source Software
Development: The Apache Server” in Proceedings of 2000 International Conference on
Software Engineering (1CSE2000), p. 263-272, (Limerick, Ireland, 2000).
Mod_proxy_balancer.
“Apache
Module
Mod_proxy_balancer”.
Disponível em
http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html. Acessado em 01 de
agosto de 2007.
Mosberger, D. and Jin, T. “httperf: A tool for measuring Web server performance” in First
Workshop on Internet Server Performance. ACM, p. 59-67, jun 1998.
Netcraft. “Web Server Survey” Disponível em http://news.netcraft.com/. Acessado em 20 de
março 2006.
Nilson, K.L, Peyyeti, S. and Fujinoki,H. "An Efficient Load Balancing Algorithm for Web
Server Clusters: MOLL (Migration-Optimized Least Loaded) Load-Balancing
Algorithm", Proceedings of Networks and Communication Systems (NCS), Krabi,
Thailand, 2005.
Nortel
Networks.
Ltd.
"Application
Switches".
Disponível
em
http://products.nortel.com/go/product_content.jsp?segId=0&catId=null&parId=0&prod_id
=37160&locale=en-US. Acessado em 01 de agosto 2007.
PHP: Hypertext Preprocessor. “Manual do PHP”. Disponível em http://www.php.net/docs/.
Acessado em 01 de maio de 2006.
82
Poskanzer, Jef. “Http load - multiprocessing http test client,” Disponível em
www.acme.com/software/http_load/. Acessado em agosto de 2007
Schroeder, T., Goddard, S. and Ramamurthy, B. “Scalable Web server clustering
technologies”. IEEE Network, p. 38-45, may 2000.
Sysstat. “Sysstat”. Disponível em http://perso.orange.fr/sebastien.godard/, Acessado em 01 de
agosto de 2007.
Schlossnagle, T. “Mod_Backhand: A load balancing module for the Apache Web server”. In:
Proceedings of the ApacheCon2000, Orlando, Florida, 2000. Disponível em
http://www.cnds.jhu.edu/pub/papers/cnds-2000-2.ps.gz. Acessado em 01 agosto 2007.
Teodoro, G., Tavares, T., Coutinho, B., Meira Jr, W. and D. Guedes, ”Load Balancing on
Stateful Clustered Web Servers, ” in 15th Symposium on Computer Architecture and High
Performance Computing (SBAC-PAD’03), Novembro, 2003.
Wackmole. “Wackmole”. Disponível em http://www.backhand.org/wackamole/. Acessado em
07 de setembro de 2007.
Xu. Zhong, Huang, Rong. “Performance Study of Load Balancing Algorithms in Distributed
Web Server Systems”. Department of Computer Science and Engineering. University of
California, Março 2004. http://www.cs.ucr.edu/~bhuyan/CS213/load_balancing.ps
Zeus Technology, Inc. "Zeus Load Balancer". Disponível em http://www.zeus.com, Acessado
em 01 de agosto 2007.
Zhang, W., Jin, S. and Wu, Q. Linux Virtual Server: Server Clustering for Scalable Network
Services, Ottawa Linux Symposium, 2000.
83
APÊNDICE
Código para o método byallproxytraffic
static proxy_worker *find_best_byallproxytraffic(proxy_balancer *balancer,
request_rec *r)
{
int i,j;
apr_off_t mytraffic = 0;
apr_off_t curmin = 0;
proxy_worker *worker;
proxy_worker *mycandidate = NULL;
int cur_lbset = 0;
int max_lbset = 0;
int checking_standby;
int checked_standby;
proxy_worker *worker1;
apr_off_t transf = 0;
apr_off_t read = 0;
void *sconf = r->server->module_config;
proxy_server_conf *conf = (proxy_server_conf
&proxy_module);
*)
ap_get_module_config(sconf,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: Entering byallproxytraffic for BALANCER (%s)",
balancer->name);
// Primeiramente verificamos se existem candidatos disponíveis
do {
checking_standby = checked_standby = 0;
while (!mycandidate && !checked_standby) {
worker = (proxy_worker *)balancer->workers->elts;
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
if (!checking_standby) { // primeira vez completamente/
if (worker->s->lbset > max_lbset)
max_lbset = worker->s->lbset;
}
if (worker->s->lbset > cur_lbset)
continue;
if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker)
PROXY_WORKER_IS_STANDBY(worker)) )
continue;
//Se o worker (nó) estiver funcionamento em estado de erro
//uma nova tentativa é feita para esse worker. Será marcado como
//operacional se o intervalo para nova tentativa for decorrido.
//O worke poderia ainda não ser usuável,mas em todo caso, é feita a tentativa
if (!PROXY_WORKER_IS_USABLE(worker))
ap_proxy_retry_worker("BALANCER", worker, r->server);
// Utilizamos no cálco somente os worker que
:
84
// não estao em estado de erro ou nao estao desabilitados
if (PROXY_WORKER_IS_USABLE(worker)) {
transf = worker->s->transferred;
read = worker->s->read;
worker1 = (proxy_worker *)conf->workers->elts;
for (j = 0; j < conf->workers->nelts; j++) {
if (strcasecmp(worker->hostname, worker1->hostname) == 0) {
if (strcasecmp(worker->name, worker1->name) != 0) {
transf = transf + worker1->s->transferred;
read = read + worker1->s->read;
}
}
worker1++;
}
mytraffic = (transf/worker->s->lbfactor)+(read/worker->s->lbfactor);
if (!mycandidate || mytraffic < curmin) {
mycandidate = worker;
curmin = mytraffic;
}
}
}
checked_standby = checking_standby++;
}
cur_lbset++;
} while (cur_lbset <= max_lbset && !mycandidate);
return mycandidate;
}
85
Código para o método byquery
static proxy_worker *find_best_byquery(proxy_balancer *balancer,
request_rec *r)
// Porta TCP utilizada para conexão com o cliente
#define PORT 3054
// Número máximo de bytes lidos
#define MAXDATASIZE 4
#define MAXWORKS 16
{
int i;
int total_factor = 0;
proxy_worker *worker;
proxy_worker *mycandidate = NULL;
int cur_lbset = 0;
int max_lbset = 0;
int checking_standby;
int checked_standby;
//-----time_t rawtime;
struct tm * timeinfo;
char buffer [3];
int seg;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
strftime (buffer,3,"%S",timeinfo);
seg = atoi(buffer);
int sockfd;
int numbytes=0, erro=0,cont=0;
char buf[MAXDATASIZE], clientip[15];
struct sockaddr_in client, server;
int namelen,client_address_size;
worker = (proxy_worker *)balancer->workers->elts;
if (seg%15==0)
{
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(worker->hostname);
server.sin_port = htons(PORT);
memset(server.sin_zero, '\0', sizeof server.sin_zero);
// Criando socket
if(( sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)
{
erro=1;
}
else
{
86
//Conectando-se
if( connect( sockfd, (struct sockaddr*) &server, sizeof(server)) == 0)
{
//recebendo informacao
memset( buf, '\0', MAXDATASIZE);
numbytes = recv( sockfd, buf, MAXDATASIZE-1, 0 );
if( numbytes > 0 )
{
worker->s->lbidle= atoi(buf);
if (worker->s->lbidle < 90)
worker->s->lbidle=0;
}
}
else
{
erro=1;
}
close(sockfd);
}
}
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: Entering byquery for BALANCER (%s)",
balancer->name);
// Primeiramente verificamos se existem candidatos disponíveis
do {
checking_standby = checked_standby = 0;
while (!mycandidate && !checked_standby) {
worker = (proxy_worker *)balancer->workers->elts;
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
if (!checking_standby) { // primeira vez completamente/
if (worker->s->lbset > max_lbset)
max_lbset = worker->s->lbset;
}
if (worker->s->lbset > cur_lbset)
continue;
if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker)
PROXY_WORKER_IS_STANDBY(worker)) )
continue;
//Se o worker (nó) estiver funcionamento em estado de erro
//uma nova tentativa é feita para esse worker. Será marcado como
//operacional se o intervalo para nova tentativa for decorrido.
//O worke poderia ainda não ser usuável,mas em todo caso, é feita a tentativa
if (!PROXY_WORKER_IS_USABLE(worker))
ap_proxy_retry_worker("BALANCER", worker, r->server);
// Utilizamos no cálco somente os worker que
:
87
// não estao em estado de erro ou nao estao desabilitados
if (PROXY_WORKER_IS_USABLE(worker)) {
if (seg%15==0)
{
worker->s->lbstatus += worker->s->lbfactor* worker->s->lbidle;
total_factor += worker->s->lbfactor* worker->s->lbidle;
}
else{
worker->s->lbstatus += worker->s->lbfactor;
total_factor += worker->s->lbfactor;
}
if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus){
mycandidate = worker;
}
}
}
checked_standby = checking_standby++;
}
cur_lbset++;
} while (cur_lbset <= max_lbset && !mycandidate);
if (mycandidate) {
mycandidate->s->lbstatus -= total_factor;
}
return mycandidate;
}
88
Código fonte do programa Sysidle
/*
***************************************************************************
* sysidle:
* modificação do codigo do mpstat da ferramenta sysstat de
* Sebastien GODARD (sysstat <at> wanadoo.fr)
*
***************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <ctype.h>
#include <sys/utsname.h>
#include "mpstat.h"
#include "common.h"
#ifdef USE_NLS
#include <locale.h>
#include <libintl.h>
#define _(string) gettext(string)
#else
#define _(string) (string)
#endif
unsigned long long uptime[3] = {0, 0, 0};
unsigned long long uptime0[3] = {0, 0, 0};
struct mp_stats *st_mp_cpu[3];
/* NOTE: Use array of _char_ for bitmaps to avoid endianness problems...*/
unsigned char *cpu_bitmap; /* Bit 0: Global; Bit 1: 1st proc; etc. */
struct tm mp_tstamp[3];
long interval = -1, count = 0;
/* Nb of processors on the machine */
int cpu_nr = 0;
/*
***************************************************************************
* Print usage and exit
***************************************************************************
*/
89
void usage(char *progname)
{
fprintf(stderr, _("Usage: %s [ options... ] [ <interval> [ <count> ] ]\n"
"Options are:\n"
"[ -P { <cpu> | ALL } ] [ -V ]\n"),
progname);
exit(1);
}
/*
***************************************************************************
* SIGALRM signal handler
***************************************************************************
*/
void alarm_handler(int sig)
{
signal(SIGALRM, alarm_handler);
alarm(interval);
}
/*
***************************************************************************
* Allocate mp_stats structures and cpu bitmap
***************************************************************************
*/
void salloc_mp_cpu(int nr_cpus)
{
int i;
for (i = 0; i < 3; i++) {
if ((st_mp_cpu[i] = (struct mp_stats *) malloc(MP_STATS_SIZE * nr_cpus)) == NULL)
{
perror("malloc");
exit(4);
}
memset(st_mp_cpu[i], 0, MP_STATS_SIZE * nr_cpus);
}
if ((cpu_bitmap = (unsigned char *) malloc((nr_cpus >> 3) + 1)) == NULL) {
perror("malloc");
exit(4);
}
memset(cpu_bitmap, 0, (nr_cpus >> 3) + 1);
}
90
/*
***************************************************************************
* Recalculate interval based on each CPU's tick count
***************************************************************************
*/
unsigned long long mget_per_cpu_interval(struct mp_stats *st_mp_cpu_i,
struct mp_stats *st_mp_cpu_j)
{
return ((st_mp_cpu_i->cpu_user + st_mp_cpu_i->cpu_nice +
st_mp_cpu_i->cpu_system + st_mp_cpu_i->cpu_iowait +
st_mp_cpu_i->cpu_hardirq + st_mp_cpu_i->cpu_softirq +
st_mp_cpu_i->cpu_steal + st_mp_cpu_i->cpu_idle) (st_mp_cpu_j->cpu_user + st_mp_cpu_j->cpu_nice +
st_mp_cpu_j->cpu_system + st_mp_cpu_j->cpu_iowait +
st_mp_cpu_j->cpu_hardirq + st_mp_cpu_j->cpu_softirq +
st_mp_cpu_j->cpu_steal + st_mp_cpu_j->cpu_idle));
}
/*
***************************************************************************
* Core function used to display statistics
***************************************************************************
*/
void write_stats_core(int prev, int curr, int dis,
char *prev_string, char *curr_string)
{
struct mp_stats
*smci = st_mp_cpu[curr] + 1,
*smcj = st_mp_cpu[prev] + 1;
unsigned long long itv, pc_itv;
int cpu;
/* Test stdout */
TEST_STDOUT(STDOUT_FILENO);
/* Compute time interval */
itv = get_interval(uptime[prev], uptime[curr]);
/* Print stats */
if (dis)
//
printf("\n%-11s CPU %%user %%nice %%sys %%iowait %%irq "
//
"%%soft %%steal %%idle intr/s\n",
//
prev_string);
/* Check if we want global stats among all proc */
if (*cpu_bitmap & 1) {
//
/*
printf("%-11s all", curr_string);
91
printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f",
ll_sp_value(st_mp_cpu[prev]->cpu_user, st_mp_cpu[curr]->cpu_user, itv),
ll_sp_value(st_mp_cpu[prev]->cpu_nice, st_mp_cpu[curr]->cpu_nice, itv),
ll_sp_value(st_mp_cpu[prev]->cpu_system, st_mp_cpu[curr]->cpu_system, itv),
ll_sp_value(st_mp_cpu[prev]->cpu_iowait, st_mp_cpu[curr]->cpu_iowait, itv),
ll_sp_value(st_mp_cpu[prev]->cpu_hardirq, st_mp_cpu[curr]->cpu_hardirq, itv),
ll_sp_value(st_mp_cpu[prev]->cpu_softirq, st_mp_cpu[curr]->cpu_softirq, itv),
ll_sp_value(st_mp_cpu[prev]->cpu_steal, st_mp_cpu[curr]->cpu_steal , itv),
(st_mp_cpu[curr]->cpu_idle < st_mp_cpu[prev]->cpu_idle) ?
0.0 : // Handle buggy kernels
ll_sp_value(st_mp_cpu[prev]->cpu_idle, st_mp_cpu[curr]->cpu_idle, itv));
*/
printf("%6.2f\n",
(st_mp_cpu[curr]->cpu_idle < st_mp_cpu[prev]->cpu_idle) ?
0.0 : /* Handle buggy kernels */
ll_sp_value(st_mp_cpu[prev]->cpu_idle, st_mp_cpu[curr]->cpu_idle, itv));
}
/* Reduce interval value to one processor */
if (cpu_nr > 1)
itv = get_interval(uptime0[prev], uptime0[curr]);
for (cpu = 1; cpu <= cpu_nr; cpu++, smci++, smcj++) {
/* Check if we want stats about this proc */
if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))))
continue;
/* Recalculate itv for current proc */
pc_itv = mget_per_cpu_interval(smci, smcj);
if (!pc_itv)
/* Current CPU is offline */
printf("0.00\n");
else {
printf("%6.2f\n",
(smci->cpu_idle < smcj->cpu_idle) ?
0.0 :
ll_sp_value(smcj->cpu_idle, smci->cpu_idle, pc_itv));
}
}
}
/*
***************************************************************************
* Print statistics average
***************************************************************************
*/
void write_stats_avg(int curr, int dis)
92
{
char string[16];
strcpy(string, _("Average:"));
write_stats_core(2, curr, dis, string, string);
}
/*
***************************************************************************
* Print statistics
***************************************************************************
*/
void write_stats(int curr, int dis)
{
char cur_time[2][16];
/* Get previous timestamp */
strftime(cur_time[!curr], 16, "%X", &(mp_tstamp[!curr]));
/* Get current timestamp */
strftime(cur_time[curr], 16, "%X", &(mp_tstamp[curr]));
write_stats_core(!curr, curr, dis, cur_time[!curr], cur_time[curr]);
}
/*
***************************************************************************
* Read stats from /proc/stat
***************************************************************************
*/
void read_proc_stat(int curr)
{
{
FILE *fp;
struct mp_stats *st_mp_cpu_i;
static char line[80];
unsigned long long cc_user, cc_nice, cc_system, cc_hardirq, cc_softirq;
unsigned long long cc_idle, cc_iowait, cc_steal;
int proc_nb;
if ((fp = fopen(STAT, "r")) == NULL) {
fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
exit(2);
}
while (fgets(line, 80, fp) != NULL) {
if (!strncmp(line, "cpu ", 4)) {
93
/*
* Read the number of jiffies spent in the different modes
* among all proc. CPU usage is not reduced to one
* processor to avoid rounding problems.
*/
st_mp_cpu[curr]->cpu_iowait = 0;
/* For pre 2.5 kernels */
cc_hardirq = cc_softirq = cc_steal = 0;
/* CPU counters became unsigned long long with kernel 2.6.5 */
sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu",
&(st_mp_cpu[curr]->cpu_user),
&(st_mp_cpu[curr]->cpu_nice),
&(st_mp_cpu[curr]->cpu_system),
&(st_mp_cpu[curr]->cpu_idle),
&(st_mp_cpu[curr]->cpu_iowait),
&(st_mp_cpu[curr]->cpu_hardirq),
&(st_mp_cpu[curr]->cpu_softirq),
&(st_mp_cpu[curr]->cpu_steal));
/*
* Compute the uptime of the system in jiffies (1/100ths of a second
* if HZ=100).
* Machine uptime is multiplied by the number of processors here.
*/
uptime[curr] = st_mp_cpu[curr]->cpu_user +
st_mp_cpu[curr]->cpu_nice +
st_mp_cpu[curr]->cpu_system +
st_mp_cpu[curr]->cpu_idle +
st_mp_cpu[curr]->cpu_iowait +
st_mp_cpu[curr]->cpu_hardirq +
st_mp_cpu[curr]->cpu_softirq +
st_mp_cpu[curr]->cpu_steal;
}
else if (!strncmp(line, "cpu", 3)) {
/*
* Read the number of jiffies spent in the different modes
* (user, nice, etc.) for current proc.
* This is done only on SMP machines.
*/
cc_iowait = cc_hardirq = cc_softirq = cc_steal = 0;
sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu",
&proc_nb,
&cc_user, &cc_nice, &cc_system, &cc_idle, &cc_iowait,
&cc_hardirq, &cc_softirq, &cc_steal);
if (proc_nb < cpu_nr) {
st_mp_cpu_i = st_mp_cpu[curr] + proc_nb + 1;
st_mp_cpu_i->cpu_user = cc_user;
st_mp_cpu_i->cpu_nice = cc_nice;
st_mp_cpu_i->cpu_system = cc_system;
94
st_mp_cpu_i->cpu_idle = cc_idle;
st_mp_cpu_i->cpu_iowait = cc_iowait;
st_mp_cpu_i->cpu_hardirq = cc_hardirq;
st_mp_cpu_i->cpu_softirq = cc_softirq;
st_mp_cpu_i->cpu_steal = cc_steal;
}
/* else additional CPUs have been dynamically registered in /proc/stat */
if (!proc_nb && !uptime0[curr])
/*
* Compute uptime reduced for one proc using proc#0.
* Done only if /proc/uptime was unavailable.
*/
uptime0[curr] = cc_user + cc_nice + cc_system + cc_idle +
cc_iowait + cc_hardirq + cc_softirq + cc_steal;
}
else if (!strncmp(line, "intr ", 5))
/*
* Read total number of interrupts received since system boot.
* Interrupts counter became unsigned long long with kernel 2.6.5.
*/
sscanf(line + 5, "%llu", &(st_mp_cpu[curr]->irq));
}
fclose(fp);
}
/*
***************************************************************************
* Read stats from /proc/interrupts
***************************************************************************
*/
void read_interrupts_stat(int curr)
{
FILE *fp;
struct mp_stats *st_mp_cpu_i;
static char line[INTERRUPTS_LINE];
unsigned long irq = 0;
unsigned int cpu;
char *cp, *next;
for (cpu = 0; cpu < cpu_nr; cpu++) {
st_mp_cpu_i = st_mp_cpu[curr] + cpu + 1;
st_mp_cpu_i->irq = 0;
}
if ((fp = fopen(INTERRUPTS, "r")) != NULL) {
95
while (fgets(line, INTERRUPTS_LINE, fp) != NULL) {
if (isdigit(line[2])) {
/* Skip over "<irq>:" */
if ((cp = strchr(line, ':')) == NULL)
continue;
cp++;
for (cpu = 0; cpu < cpu_nr; cpu++) {
st_mp_cpu_i = st_mp_cpu[curr] + cpu + 1;
irq = strtol(cp, &next, 10);
st_mp_cpu_i->irq += irq;
cp = next;
}
}
}
fclose(fp);
}
}
/*
***************************************************************************
* Main loop: read stats from the relevant sources,
* and display them.
***************************************************************************
*/
void rw_mpstat_loop(int dis_hdr, unsigned long lines, int rows)
{
struct mp_stats *st_mp_cpu_i, *st_mp_cpu_j;
int cpu;
int curr = 1, dis = 1;
/* Read stats */
if (cpu_nr > 1) {
/*
* Init uptime0. So if /proc/uptime cannot fill it,
* this will be done by /proc/stat.
*/
uptime0[0] = 0;
readp_uptime(&(uptime0[0]));
}
read_proc_stat(0);
read_interrupts_stat(0);
if (!interval) {
/* Display since boot time */
mp_tstamp[1] = mp_tstamp[0];
96
memset(st_mp_cpu[1], 0, MP_STATS_SIZE * (cpu_nr + 1));
write_stats(0, DISP_HDR);
exit(0);
}
/* Set a handler for SIGALRM */
alarm_handler(0);
/* Save the first stats collected. Will be used to compute the average */
mp_tstamp[2] = mp_tstamp[0];
uptime[2] = uptime[0];
uptime0[2] = uptime0[0];
memcpy(st_mp_cpu[2], st_mp_cpu[0], MP_STATS_SIZE * (cpu_nr + 1));
pause();
do {
/*
* Resetting the structure not needed since every fields will be set.
* Exceptions are per-CPU structures: some of them may not be filled
* if corresponding processor is disabled (offline).
*/
for (cpu = 1; cpu <= cpu_nr; cpu++) {
st_mp_cpu_i = st_mp_cpu[curr] + cpu;
st_mp_cpu_j = st_mp_cpu[!curr] + cpu;
*st_mp_cpu_i = *st_mp_cpu_j;
}
/* Get time */
get_localtime(&(mp_tstamp[curr]));
/* Read stats */
if (cpu_nr > 1) {
uptime0[curr] = 0;
readp_uptime(&(uptime0[curr]));
}
read_proc_stat(curr);
read_interrupts_stat(curr);
/* Write stats */
if (!dis_hdr) {
dis = lines / rows;
if (dis)
lines %= rows;
lines++;
}
write_stats(curr, dis);
/* Flush data */
fflush(stdout);
97
if (count > 0)
count--;
if (count) {
curr ^= 1;
pause();
}
}
while (count);
/* Write stats average */
write_stats_avg(curr, dis_hdr);
}
/*
***************************************************************************
* Main entry to the program
***************************************************************************
*/
int main(int argc, char **argv)
{
int opt = 0, i;
struct utsname header;
int dis_hdr = -1, opt_used = 0;
unsigned long lines = 0;
int rows = 23;
#ifdef USE_NLS
/* Init National Language Support */
init_nls();
#endif
/* Get HZ */
get_HZ();
/* How many processors on this machine ? */
cpu_nr = get_cpu_nr(~0);
/*
* cpu_nr: a value of 2 means there are 2 processors (0 and 1).
* In this case, we have to allocate 3 structures: global, proc0 and proc1.
*/
salloc_mp_cpu(cpu_nr + 1);
while (++opt < argc) {
if (!strcmp(argv[opt], "-V"))
print_version();
98
else if (!strcmp(argv[opt], "-P")) {
/* '-P ALL' can be used on UP machines */
if (argv[++opt]) {
opt_used = 1;
dis_hdr++;
if (!strcmp(argv[opt], K_ALL)) {
if (cpu_nr)
dis_hdr = 9;
/*
* Set bit for every processor.
* Also indicate to display stats for CPU 'all'.
*/
memset(cpu_bitmap, 0xff, ((cpu_nr + 1) >> 3) + 1);
}
else {
if (strspn(argv[opt], DIGITS) != strlen(argv[opt]))
usage(argv[0]);
i = atoi(argv[opt]); /* Get cpu number */
if (i >= cpu_nr) {
fprintf(stderr, _("Not that many processors!\n"));
exit(1);
}
i++;
*(cpu_bitmap + (i >> 3)) |= 1 << (i & 0x07);
}
}
else
usage(argv[0]);
}
else if (interval < 0) {
/* Get interval */
if (strspn(argv[opt], DIGITS) != strlen(argv[opt]))
usage(argv[0]);
interval = atol(argv[opt]);
if (interval < 0)
usage(argv[0]);
count = -1;
}
else if (count <= 0) {
/* Get count value */
if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) ||
!interval)
usage(argv[0]);
count = atol(argv[opt]);
if (count < 1)
usage(argv[0]);
}
else
usage(argv[0]);
99
}
if (!opt_used)
/* Option -P not used: set bit 0 (global stats among all proc) */
*cpu_bitmap = 1;
if (dis_hdr < 0)
dis_hdr = 0;
if (!dis_hdr) {
/* Get window size */
rows = get_win_height();
lines = rows;
}
if (interval < 0)
/* Interval not set => display stats since boot time */
interval = 1;
/* Get time */
get_localtime(&(mp_tstamp[0]));
/* Get system name, release number and hostname */
uname(&header);
// print_gal_header(&(mp_tstamp[0]), header.sysname, header.release,
//
header.nodename);
/* Main loop */
rw_mpstat_loop(dis_hdr, lines, rows);
return 0;
}
100
Código fonte do programa Servidor
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
//Porta TCP que os clientes irão se conectar
#define MYPORT 3054
//Quantidade de conexoes pendendes em espera na fila
#define BACKLOG 10
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
int main(void)
{
int sockfd, new_fd; // escutando em sock_fd, novas conexões em new_fd
struct sockaddr_in my_addr; // informações sobre meu endereço
struct sockaddr_in their_addr; // informações sobre o endereço do cliente
socklen_t sin_size;
struct sigaction sa;
int yes=1;
//o comando a ser executado
FILE *fpipe;
char *command="sysidle";
char line[256];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
// host byte order
// short, network byte order
101
my_addr.sin_addr.s_addr = INADDR_ANY;
// automaticamente preenchido com meu
IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // obtem todos os processos dead
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
while(1) { // loop
if ( !(fpipe = (FILE*)popen(command,"r")) )
{ // se fpipe é NULL
perror("Problemas com o pipe");
exit(1);
}
fgets( line, sizeof line, fpipe);
pclose(fpipe);
sin_size = sizeof their_addr;
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}
if (!fork()) { // este é o processo filho
close(sockfd); // o filho não necessida de listener
if (send(new_fd, line, 3, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd); // o pai não necessita disto
}
return 0;
}
Download

balanceamento de requisições em cluster de servidores web