# data[].attributes.attachment_link.readable_text
Arquitetura

Sistemas distribuídos são sistemas complexos, que contem diversos componentes espalhados por várias máquinas em diferentes redes de computador. Saber administrar e organizar estes sistemas é um ponto crucial para obter um melhor desempenho.

Existem dois tipos organização que devem ser feitos, ao se planejar o desenvolvomento de um sistema distribuído, o tipo lógico que trata de onde e como organizar os softwares deste sistema, e o físico, que trata da organização física das máquinas em cada rede.

A arquitetura de um sistema distribuído deve levar em conta quais são os seus componentes de software e como eles interagem entre si, para que com esta análise, seja possível decidir qual é a melhor maneira de alocar as máquinas disponíveis para constituí-lo.

Construir um sistema distribuído depende da instanciação de vários componentes de software, como um servidor web, um servidor de cache, um servidor de banco de dados, servidor da camada de negócios, um firewall, um proxy, etc, e existem diversas maneiras diferentes de se organizar estes sistemas.

Esta organização também é conhecida como arquitetura de software, que pode ser classificada em dois tipos a centralizada onde uma máquina contém muitos dos componentes daquele sistema e a descentralizada, onde cada software roda em um servidor diferente.

Monitorar as máquinas destes sistemas também é um passo importante para obter-se alta disponibilidade. Fatores como o desempenho ou o tempo de resposta de uma certa máquina podem ser utilizados para se decidir quando criar novas instâncias daquele software ou camada, ou quando derrubá-las para economizar recursos. O monitoramento também pode indicar áreas de gargalo onde melhorias de desempenho devem ser implementadas a fim de obter-se um melhor aproveitamento do parque máquinas disponíveis.

Existem ferramentas de mercado que ajudam a descobrir o comportamento dos seus usuários, monitorando os seus cliques, o movimento do mouse. Estas ferramentas também disponibilizam dados como, sexo, idade, profissão, onde mora, quais lugares frequenta, quando acorda, que horas chega ao trabalho e algumas vezes inclusive a renda provável.

Estes dados são capturados pelas empresas afim de prover anúncios, ou mostrar produtos de forma a conseguir uma maior taxa de vendas. Como cada usuário gera uma quantidade considerável de dados, e os sites possuem milhares de usuários, a forma de armazenar e processar estes dados será diferente, eles geralmente não se encaixam em um sistema de armazenamento comum, como um banco de dados SQL, mas isto será discutido em um outro momento neste blog.

Estilos de arquitetura

A discussão sobre os estilos de arquitetura será realizada no nível dos componentes, em como eles se conectam entre si, como eles trocam dados e finalmente em como eles serão configurados em um sistema.

Os estilos de arquitetura de componentes são mostrados a seguir:

1. Arquitetura nivelada

2. Arquitetura baseada em Objetos

3. Arquitetura de Dados Centralizados

4. Arquitetura baseada em Eventos

Na arquitetura nivelada os componentes são organizados em várias camadas e uma requisição percorre os componentes apenas em uma direção.

Em uma arquitetura baseada em Objetos cada objeto é definido como um componente, e estes componentes são conectados através de chamadas do tipo RPC, que será utilizada por sistemas do tipo Cliente-Servidor.

Arquitetura baseada em dados centralizado diz que todos os processos devem se comunicar através de um sistema de repositórios (ativo ou passivo) comum. Exemplo temos softwares que utilizam apenas um tipo de banco de dados.

Arquitetura baseada em eventos os processos se comunicam através da propagação de eventos os quais opcionalmente poderão carregar dados. Como exemplo temos sistemas de publish/subscribe, ou mesmo aplicativos que usam o Akka Toolkit. Um processo publica um evento enquanto o middleware garante que alguém estará escutando aquele evento, a grande vantagem desta arquitetura é que os processos são desacoplados e ocorrem em paralelo, sem depender um do outro.

Arquiteturas de Sistema

Sistemas distribuídos são divididos em várias camadas, neste tópico serão abortados os sistemas de duas, três e multicamadas.

Duas Camadas

Um sistema de duas camadas é composto por um servidor, que contém algum tipo de armazenamento de dados como um banco de dados ou um sistema de arquivos distribuídos e por um cliente, onde ficam as regras de negócio e a interface do usuário. Este sistema era muito comum nos anos 90, onde os sistemas não eram tão complexos e poucas máquinas se conectavam ao servidor de banco de dados.

Neste modelo o servidor será responsável pelo armazenamento dos dados compartilhado, os clientes serão responsáveis por processar os dados retornados pelo servidor, fazendo com que o tráfego de dados seja muito alto entre o servidor e os seus clientes, pois muitas vezes os dados são selecionados crus no servidor e enviados ao cliente, que é quem realiza um tratamento nos dados. Por exemplo para fazer uma query ordenada, todos os dados serão selecionados no servidor e a ordenação será realizada no cliente.

Esta configuração funciona muito bem em locais onde a velocidade de rede alta, como em uma rede local, já que o tráfego de dados pela rede será alto.

A grande vantagem desta configuração é que o processamento dos dados será realizado por muitas máquinas diferentes, aliviando o processamento no servidor. Entretanto como o código de execução está instalado em várias máquinas diferentes, a instalação e manutenção destas máquinas torna-se uma tarefa muito complicada, fazendo com que a execução do software dependa das várias plataformas onde cada uma delas estiver instalada, o que costuma gerar muitos erros e incompatibilidades.

Um outro ponto a ser observado é que como a interface com o usuário está junto das regras de negócio, muitas vezes o código que desenha a interface e o código das regras de negócio estão misturados, o que dificulta a manutenção deste tipo de sistema, pois os designers (responsáveis pelas telas) e os desenvolvedores (responsáveis pelas regras de negócio) acabam trabalhando no mesmo código.

Três Camadas

Com a popularização de aplicativos web, ou mesmo a evolução dos escritórios para multi pontos em várias cidades, tornou necessário o desenvolvimento de uma nova arquitetura para atender estas novas limitações.

Em um sistema web ou multi pontos, velocidade da rede é bem inferior ao de uma rede local, além existirem muitas plataformas que acessam a web, como celular, pda, tablet, netbooks, pcs, servidores, etc. Com este novo modo de negócio a utilização de um sistema distribuído de duas camadas caiu em desuso.

A criação da terceira camada, serviu para parametrizar a separação entre as camadas de software, o que não existia no sistema de duas camadas.

Pela definição as três camadas deste sistemas são, o repositório de dados, a camada intermediária, que contem as regras de negócio e por último a camada de interface, que contem as interfaces do sistema, como telas, páginas web, etc.

A separação das regras de negócio em uma camada, facilitou a organização do código, isolando o código que será utilizado pelos desenvolvedores, dos códigos que serão alterados pelos designers, além de possibilitar o escalonamento desta camada.

Multicamadas

Na arquitetura multicamada existem diversos tipos de separação que podemos realizar entre o cliente e o servidor, que serão mostradas na figura abaixo:

A linha roxa indica a separação de o que é realizado no servidor e o que é realizado no cliente.

Começando a analise da esquerda para a direita, no primeiro caso "a" o servidor tem total controle do que será mostrado ao usuário, neste caso temos uma tela burra que somente mostra informações para o usuário não realiza nenhuma validação.

Uma alternativa a este caso é colocar toda a camada de interface na máquina do cliente, como mostra o caso "b", nestes casos a aplicação será dividida em duas, o front end o qual se comunica com o servidor em um protocolo específico do aplicativo e neste caso o front end ainda não faz nenhum tipo de processamento para apresentar a interface ao usuário. E um aplicativo que será executado no servidor com todas as regras de negócio, algo similar a web 1.0.

No caso c é mostrado que também podemos mover parte do aplicativo para o cliente e um exemplo típico deste caso é um aplicativo que tenha um formulário que deve ser preenchido completamente antes de ser processado, neste caso o front end pode checar a consistência dos dados e interagir com o usuário, um exemplo de aplicativo assim são os forms que preenchemos ao se cadastrar em sites que usam a Web 2.0. Se o nome do usuário já está cadastrado, eles já avisam ao usuário pedindo a troca, assim como CPF inválido, etc.

Muitos dos sistemas cliente servidor possuem as organizações mostradas nos casos d e e. Estes casos são utilizados quando a máquina cliente é um PC que se conectam a um sistema distribuído de arquivos, ou um banco de dados, através de uma rede interna. Essencialmente todas as operações como regra de negócios rodam no cliente, e somente o armazenamento dos arquivos/dados é feito no servidor.

Além da separação física das camadas, cliente-servidor, um sistema multicamadas consiste em separar as camadas de execução do código, como serviços, repositórios, lógica, apis, etc.

Em um sistema multicamadas, pode conter mais de um sistema de armazenamento de dados, como um sistema de cache, ou um sistema de armazenamento de arquivos (imagens, etc).

Arquiteturas Descentralizadas

Cada camada de um aplicativo multicamadas corresponde diretamente a organização das aplicações e a distribuição em camadas é conhecida como distribuição vertical. Esta distribuição vertical consiste em dividir o aplicativo em camadas lógicas que ficam alocadas em diferentes servidores.

Nos sistemas de hoje, o que conta geralmente é como os clientes e os servidores estão distribuídos, o que é chamado de distribuição horizontal, ou também de sistemas ponto a ponto.

Arquitetura Microserviços

Uma outra forma de distribuir um sistema em multicamadas é a chamada arquitetura de microserviços, onde temos diversas máquinas provendo serviços para um sistema. Estes sistemas podem rodar cada um em um servidor diferente, ou podemos ter serviços classificados por tipos, por exemplo serviços referentes ao usuário, como o cadastro, alteração e remoção da conta do usuário, rodar em um servidor isolado.

Estes serviços podem ser colocados em servidores bem pequenos que ficarão isolados.

Nesta arquitetura tem-se a possibilidade de escalar muito bem cada tipo de serviço, se o sistema está passando por uma grande demanda no cadastro dos usuários, podemos replicar as máquinas que serão responsáveis por este tipo de serviço e esta demanda será atendida.

Este comportamento é bem diferente de um sistema onde todos os serviços ficam em uma mesma máquina, neste caso para atender uma demanda destas, deveríamos replicar todos os serviços do sistema.

Como desvantagens nesta arquitetura estão a maior dificuldade de administrar uma maior quantidade de sistemas rodando em paralelo, assim como repositório de código, entre outros. Um outro fator que pode ser citado é, dependendo de como foi implementado o software, o compartilhamento de código comum pode ficar complicado, e decisões erradas de arquitetura podem levar a reescrever boa parte do código.

Arquiteturas ponto a ponto Estruturadas

Neste tipo de arquitetura os componentes são organizados dentro de uma rede e eles são construídos através da configuração de rede. A configuração mais utilizada é a de Tabela Hash Distribuída. Neste sistema os itens de dados recebem uma chave randômica de 128 ou 160 bits. Além dos dados cada ponto, ou cada nó da rede, também recebe uma chave randômica. O ponto chave deste tipo de sistema é conseguir implementar um sistema eficiente e determinístico em que cada chave aponta para apenas um objeto.

Em um sistema de Chord (Acorde) os nós ficam disponíveis em círculo já que cada nó aponta, pelo menos, para o seu sucessor.

Porém caso cada nó contivesse somente o seu antecessor, uma busca por um nó poderia ter que percorrer a rede inteira até encontrá-lo, por isso no sistema Chord cada nó também contém uma tabela que aponta para os outros nós do círculo, sendo que esta tabela pode conter até todos os elementos do circulo, formando uma espécie de cache dos endereços dos componentes do sistema. Com esta tabela o tempo de busca de um nó dentro de um Chord cai consideravelmente.

Para um novo nó se juntar a rede, ele precisa saber somente o dado do seu antecessor, já quando um nó deixa a rede, uma reorganização deverá ser feita, já que o seu sucessor deverá alterar o seu antecessor para o antecessor do nó que está deixando a rede.

Content Addressable Network (CAN) é um outro sistema baseado em DHT, que foi desenvolvida para ser escalável, tolerante a falhas e auto organizável. O design desta rede é um plano cartesiano de coordenadas virtuais, onde são colocados os endereços virtuais dos pontos de rede o que não tem nenhum relacionamento com a localização física desta rede. Cada ponto é uma área do plano cartesiano e cada ponto da rede contém os endereços de todos os seus vizinhos e ele usa o posicionamento virtual para estabelecer a melhor rota entre dois pontos de uma rede. Quando um novo ponto é adicionado ele pega um valor arbitrário de um ponto, o qual terá a sua área divida em dois, sendo que o ponto novo e o ponto escolhido, ficarão cada um com uma metade da sua área anterior.

Porém quando um ponto sai da rede um dos seus vizinhos assumirá a sua área, o que nem sempre gerará um retângulo. Neste caso todos os vizinhos do nó que está deixando a rede é informado do seu novo vizinho, gerando uma distorção no caminho da rede. Por isso existe um processamento que roda em background para reorganizar a rede, que neste caso irá cuidar da reorganização daquela área da rede.

Arquiteturas de ponto a ponto não estruturadas

Sistemas de ponto a ponto não estruturados utilizam algoritmos randômicos para conectar os pontos, fazendo com que cada ponto tenha uma lista de pontos vizinhos que é construída randomicamente. Esta lista possui um parâmetro de tempo de vida, o qual indica quão velho é a conexão com aquele nó. Os nós, quando se comunicam, trocam informações sobre seus vizinhos.

Em um algoritmo que cuida de uma rede não estruturada, existem threads que varrem estas listas tentando otimizar as conexões destas redes.

O principal fator da troca de informações entre dois nós, é a construção de uma lista otimizada, para isso eles devem decidir quais informações descartar na criação da nova lista de vizinhos. Existem muitas formas de se fazer isso, incluindo o descarte das informações que foram enviadas ao outro nó, descartar os nós mais antigos.

Como não existe uma maneira especifica de determinar uma rota entre dois pontos de uma rede não estruturada, este tipo não é escalável.

Superpontos

Os superpontos foram uma solução proposta para resolver o problema de escalabilidade de redes não estruturadas. Nesta proposta os superpontos são nós que contém as ligações para os seus vizinhos, e qualquer nós que queira contactar algum nó em outra rede, deverá antes passar por um superponto. Neste tipo de rede, todo nó comum deve estar conectado a um superponto.

Qualquer ponto que se junte a rede, deverá se conectar a um superponto, e ao deixá-la ele somente deverá atualizar a conexão com o superponto.

O grande desafio desta arquitetura é como eleger os pontos que serão usados como superpontos, uma vez que um superponto deverá ser confiável e duradoura.

Arquiteturas hibridas

Até aqui abordamos separadamente arquiteturas ponto a ponto e de sistemas cliente servidor, mas muitos dos sistemas distribuídos utilizam um mix destas arquiteturas, unindo estes dois tipos de arquiteturas torna-se possível aproveitar os pontos positivos de cada uma delas.

Sistemas Edge Server

Os sistemas de Servidores Edge são um dos exemplos híbridos a serem mostrados neste post. Estes sistemas fazem parte da arquitetura de provedores de internet.

Os provedores de internet são utilizados por muitos usuários, incluindo empresas inteiras e também usuários caseiros. Estes servidores são deployados no ponto de conexão com a internet, e a principal função deles é servir conteúdo, aplicando-se alguns filtros e funções de transcrição. Os servidores de edge também são utilizados para replicar parte dos dados que ele pegam da internet, para que com isso, diminua a necessidade de conexão e de transporte de dados entre os provedores e a internet em si. Uma vez tendo a informação mais perto, no caso armazenada no provedor, o usuário final terá um acesso mais rápido as informações, pois ao invés de sua requisição ter que passar pela internet, ela já estará armazenada no seu provedor.

Sistemas Colaborativos Distribuídos

Estes sistemas proveem um sistema descentralizado de distribuição de conteúdo. Um bom exemplo deste tipo de sistema é o BitTorrent, que é um sistema de download ponto a ponto. Neste sistema os arquivos são quebrados em pacotes e quando um usuário deseja pegar algum arquivo, ele poderá baixar vários pacotes de lugares diferentes. Um dos principais pontos do design do BitTorrent é a colaboração, pois uma vez que um usuário não compartilha nada, o servidor irá baixar a velocidade com a que ele realiza os downloads.

Para fazer um download de um arquivo, o usuário deverá acessar um diretório global, que contém os arquivos .torrent. Estes arquivos carregam as informações sobre o arquivo que o usuário deseja baixar, incluindo as informações conhecidas com tracker.

Um tracker é um servidor que o usuário deverá se conectar para saber onde se encontram os nós ativos que estão provendo partes deste arquivo. Os trackers ordenam os nós de acordo com a velocidade de conexão dele, a quantidade de arquivos compartilhados, etc.

Claramente o BitTorrent faz a utilização de sistemas centralizados e sistemas descentralizados.

Um outro exemplo clássico de sistemas colaborativos é o Globule, que se trata de um sistema de colaboração de conteúdo distribuído. Este sistema se baseia nos sistemas de arquitetura Edge discutidos anteriormente. Porém neste caso, ao invés de provedores de internet disponibilizarem os servidores Edge, usuários comuns e empresas disponibilizam servidores web onde o conteúdo da rede Globule será armazenado. Estes servidores devem conter as seguintes funcionalidades:

1. Componente que consiga redirecionar requisições a outros servidores.

2. Componente para analisar os padrões de acesso.

3. Componente para administra a replicação de páginas da Web.

Arquitetura versus Middleware

O middleware fica em uma camada entre os aplicativos e as plataformas dos sistemas distribuídos, e o que geralmente acontece é que eles seguem um estilo de arquitetura específico. Com isso o desenvolvimento de sistemas fica mais simples, entretanto nem sempre o estilo de arquitetura do middleware condiz com o aplicativo que o desenvolvedor irá fazer.

Interceptadores

Os interceptadores são um tipo de software que desvia o fluxo de um aplicativo, permitindo a execução de um código específico, entre duas camadas. Alguns exemplos de interceptadores incluem particionamento dos pacotes e a sua montagem posterior, transformações na mensagem a fim de adaptá-la, incluindo modificações de encoding, etc.

Monitoramento

Sistemas distribuídos auto administrados

Sistemas distribuídos com gerenciamento manual

Arquitetura sem servidor (Serverless)

Apresentação

# data[].attributes.attachment_link.description
Sistemas distribuídos são sistemas complexos, que contem diversos componentes espalhados por várias máquinas em diferentes redes de computador. Saber administrar e organizar estes sistemas é um ponto crucial para obter um melhor desempenho.

# data[].attributes.headline
Escalabilidade: Conceitos e boas práticas

# data[].attributes.subject
Escalabilidade: Conceitos e boas práticas

# data[].attributes.attachment_link.readable_text
Escalabilidade de aplicações requer um balanço entre dois domínios distintos. Por exemplo, apenas implementar um cluster com servidores de load-alance não quer dizer que a aplicação apresentará uma peformance melhor que aplicação que foi desenhada para ser executada em uma única máquina.
Quando abordamos o assunto de escalabilidade vamos além das aplicações tradicionais cliente-servidor e começamos a pensar em aplicações distribuídas. Aplicações distribuídas são desenhas com N camadas de aplicações que propõe o compartilhamento de recursos, tais como componentes de negócios e base de dados.

Escalabilidade vertical - (Scalling-up)

Scalling-Up ou escalabilidade vertical são termos geralmente utilizados para alcançarmos uma maior performance da nossa aplicação utilizando o melhor e mais rápido hardware. Isso inclui a adição de mais recursos para o nosso servidor, tais como:

* Memória
* Processador
* Disco

A escalabilidade vertical também nos permite utilizar a tecnologia de softwares de virtualização, uma vez que esse software fornece mais recursos para os módulos hospedados no SO (Sistema Operacional), esse recurso também pode ser chamado de ampliação, como a expansão de processos. A escalabilidade do aplicativo refere-se ao melhor desempenho das aplicações em execução.

Escalabilidade horizontal - (Scalling-out)

Scalling-out ou Escalabilidade horizontal significa adicionar mais recursos para um conjunto de servidores, com a queda dos preços de computadores e o crescimento contínuo de potência de processamento, as aplicações de alto desempenho, tais como:

* Análise de dados
* Análise biotecnológicas

Adotaram sistemas de commodities para tarefas que antigamente teriam a necessidade de possuir supercomputadores, ao dedicar várias máquinas para uma tarefa comum, a tolerância a falhas da aplicação aumenta. Do ponto de vista administrativo a escalabilidade vertical apresenta um desafio maior de gestão, devido ao aumento do número de máquinas.

Desenvolvedores e administradores da infraestrutura utilizam diversas técnicas de load-balance para escalar horizontalmente. O load-balance permite que uma aplicação escale em um cluster de servidores, fornecendo uma certa facilidade para adicionar mais servidores replicados. Também fornece a redundância dando os recursos de failover local, cada servidor adicional proporciona um aumento praticamente linear em termos de escalabilidade.
O ponto chave para escalar horizontalmente é a transparência da localização do servidor, se o código da aplicação precisa saber qual servidor está executando uma determinada tarefa, o nosso objetivo de transparência de localização não foi alcançado e o dimensionamento será difícil, a aplicação deve ser desenvolvida com o pensamento em escalabilidade de um servidor para muitos, que não é uma opção econômica, abaixo temos uma imagem que ilustra a escalabilidade horizontal.

Desenhando aplicações para escalabilidade

Como já vimos nos tópicos acima o design da aplicação dita muito o quão escalável a aplicação vai ser, um bom projeto é fundamental para escalar sua aplicação e em nenhum outro momento do ciclo de vida da aplicação podemos tomar uma decisão que impacte na escalabilidade da aplicação, por isso devemos ter muito cuidado ao desenhar as nossas aplicações.

Pirâmide da escalabilidade

Como podemos ver na imagem que ilustra a pirâmide da escalabilidade, o hardware tuning e o product tuning são uma pequena fatia nessa equação. A base da nossa aplicação é o design e a codificação, essa pirâmide nos mostra que com um design inteligente podemos adicionar mais escalabilidade para uma aplicação.
Quando estamos desenhando uma aplicação pensando na escalabilidade o objetivo principal é garantir o gerenciamento de recursos eficiente, pois com esse tipo de design não existe limites para qualquer camada ou componente de aplicação onde devemos considerar a escalabilidade em todos os níveis desde a interface com o usuário até a base de dados.

Os 5 mandamentos do design para escalabilidade

Não espere - (Do not wait)

Um processo nunca deve aguardar mais tempo que o necessário, cada pedaço de tempo que um processo utiliza um recurso, é a mesmo pedaço de tempo que um outro processo está aguardando para ser executado, devemos separar os nossos processos em duas categorias: síncrona e assíncrona.
Existem certos momentos onde a nossa aplicação deve executar processos de forma síncrona, por exemplo: Executamos um determinado método, onde precisamos aguardar o seu resultado para saber se a sua ação foi bem executada ou não. Assim todas as operações que estão relacionadas ao processo do exemplo dependem do resultado do mesmo.
Uma forma de conseguirmos escalar nossa aplicação é através de operações assíncronas, quando estamos manipulando operações assíncronas de longa duração, elas são adicionadas para uma fila para serem concluídas mais tarde por um processo separado.

Não lute por recursos - (Do not fight for resources)

A contenção de recursos é a principal causa dos problemas de escalabilidade. Independente do design, toda aplicação tem uma quantidade finita de recursos. Além de realizar o aceleramento das tarefas de longa duração, nós podemos tomar outras medidas para evitar a contenção de recursos.
Quando estamos executando operações de envolvem a utilização de recursos escassos e que estão sujeitos a contenção, devemos utilizar esses recursos o mais tarde possível e em seguida, liberar esses recursos o mais rápido possível. Quanto menor a quantidade de tempo que um processo fica utilizando esse tipo de recurso escasso, mais cedo esse recurso estará disponível para outro processo utiliza-lo.

Projete para a comutabilidade - (Design for Commutability)

Desenhar a nossa aplicação para comutabilidade é sem sombra de dúvidas a maneira mais negligente para diminuir a contenção de recursos. Por exemplo: Quando temos duas operações podemos chamá-las de comutativa quando elas podem ser aplicadas em qualquer ordem e ainda sim ter o mesmo resultado final.

Projete para a intercambialidade - (Desigin for interchangeability)

Sempre que generalizamos um recurso estamos tornando o recurso intercambiável, e toda vez que adicionamos um estado detalhado de um recurso, estamos tornando esse recurso menos intercambiável.
Existem grupamentos de recursos que conseguem tirar proveito dos recursos intercambiáveis, tais como:

Exigir componentes para manter o estado entre chamadas de métodos destrói toda a permutabilidade e a escalabilidade é impactada de forma negativa. Cada chamada de método deve ser autosuficiente e armazenar o estado fora do componente.

Recursos de partição e atividades - (Partition resources and activities)

Devemos particionar os recursos e as atividades, assim minimizando essas relações entre esses dois itens nós minimizamos o risco de criarmos gargalos.
Quando realizamos o particionamento das atividades aliviamos a carga que inserimos sobre um determinado recurso de alto custo. Quando utilizamos SSL é sensato utiliza-lo somente para as páginas que realmente precisam de uma maior segurança.
Porém tome muito cuidado porque o particionamento nem sempre é a melhor escolha, isso pode tornar o sistema mais complexo, dividindo recursos que exigem dependências pode adicionar uma grande sobrecarga para uma operação.

Boas práticas de escalabilidade

Como todo assunto em desenvolvimento de software nós temos as boas e as más práticas quando estamos desenvolvendo uma aplicação. Pensando em escalabilidade, abaixo são apresentados itens que são considerado como boas práticas. Elas não seguem uma ordem, porém são recomendadas quando estamos tentando atingir o máximo de uma aplicação escalável.

* Use tecnologias de clustering
* Considere camadas lógicas contra camadas físicas
* Isole métodos transacionais
* Elimine o estado da camada de negócios quando possível
*Reveja as melhores práticas para performance

Referências:

* High Scalability
* Google Cloud Plataform

# data[].attributes.attachment_link.title
Escalabilidade: Conceitos e boas práticas

# data[].attributes.attachment_link.description
Escalabilidade de aplicações requer um balanço entre dois domínios distintos. Por exemplo, apenas implementar um cluster com servidores de load-alance não quer dizer que a aplicação apresentará uma peformance melhor que aplicação que foi desenhada para ser executada em uma única máquina.

# data[].attributes.attachment_link.title
O que é Middleware – Definição e exemplos | Microsoft Azure

# data[].attributes.attachment_link.description
Middleware é o software que se encontra entre o sistema operacional e os aplicativos nele executados, possibilitando o gerenciamento de dados e a comunicação.

# data[].attributes.attachment_link.readable_text
Nos primórdios da computação os sistemas eram todos centralizados. Todo o processamento era feito no mainframe. Os terminais eram usados apenas para entrada/saída de dados. Com o tempo, surgiram novas arquiteturas de computação que buscavam descentralizar o processamento. Foi quando surgiram os primeiros sistemas distribuídos. A ideia, como o próprio termo sugere, era de distribuir o processamento ao invés de adotar uma arquitetura centralizada no mainframe.
Conceito de Sistema Distribuído
O conceito de sistema distribuído é de um sistema que possui componentes localizados em computadores interligados em rede e que se comunicam e coordenam suas ações através da troca de mensagens entre os componentes. É comum pensarmos em componentes como sendo apenas servidores e máquinas conectadas em rede, mas quando falamos de componentes podem ser componentes de hardware ( servidores ) ou de software ( aplicações e serviços ).

Os componentes interligados em rede podem estar separados por qualquer distância. No mesmo edifício de uma empresa, na mesma cidade, mesmo estado, no mesmo país ou até em continentes diferentes.
Exemplos de Sistemas Distribuídos
Em nossos dias todas as aplicações são baseadas em redes de computadores. Nenhuma aplicação ou serviço funciona de forma isolada. As redes são projetadas de forma a suportar uma ampla gama de serviços e aplicações.

São alguns exemplos de sistemas distribuídos:

A internet é o maior exemplo de sistema distribuído

Qualquer aplicação intranet

Qualquer aplicação mobile

Aplicações e serviços baseados na Computação em Nuvem

A Internet em particular é um sistema distribuído muito grande. Ela conecta usuários através de sites e serviços, e-mail, transferência de arquivos, chat, etc. Os serviços estão localizados em máquinas dispersas que são interligadas por algum tipo de rede. Diferentes aplicações e serviços se comunicam através da rede, ele trocam mensagens através de um meio de comunicação comum. Estes meios de comunicação permitem que aplicações e serviços em plataformas diferentes consigam se comunicar e cooperar. Eles são chamados de protocolos.

A Intranet é uma parte da Internet administrada separadamente por uma empresa. Uma intranet é composta de várias redes locais ( LANs ) interligadas por conexões de backbone. A configuração de rede de uma Intranet pode variar desde uma LAN em um único site até um conjunto de LANs interconectadas pertencentes às filiais de uma grande empresa, localizadas inclusive em países diferentes.

Uma Intranet pode ser conectada à Internet através de um roteador que permite aos usuários da Intranet terem acesso a serviços da Internet, serviços que são providos de fora da empresa. Também é possível que os usuários de outras Intranets tenham acesso aos serviços que a Intranet oferece. A segurança é crucial pois não deve ser permitido que um usuário de uma empresa concorrente tenha acesso aos projetos e clientes de uma empresa, da mesma forma que um hospital pode não querer que informações dos seus pacientes sejam acessadas por empresas farmacêuticas.

Desta forma vemos que os sistemas distribuídos já são uma realidade, sendo importante conhecer os conceitos e arquiteturas de sistemas distribuídos.

A Computação móvel também é um tipo de sistema distribuído que conecta diversos dispositivos tais como notebooks, PDA, smartphone, Tablet além de outros dispositivos que são incorporados em carros, geladeiras, máquinas de lavar, smartwatch, etc. Estes dispositivos acessam serviços através da Internet. Com o avanço das redes sem fio e da miniaturização do hardware temos componentes interligados por redes sem fio com alta portabilidade e capacidade de se conectar com redes em lugares diferentes.

A computação móvel também é chamada computação nômade e permite a execução de tarefas de computação com alta mobilidade. Os recursos são acessados através da internet de qualquer lugar.

Daqui pra frente vamos nos referir aos sistemas distribuídos como SD.
Por que Sistemas Distribuídos?
O compartilhamento de recursos é um bom motivo para os SD. Recursos podem ser compartilhados por diferentes servidores e consumidos por clientes. Serviços podem ser compartilhados através da internet, sendo encapsulados em objetos que podem ser acessados por outros objetos ou por aplicações cliente.

O compartilhamento de recursos é a principal motivação para se construir sistemas distribuídos. O recurso pode ser um componente de hardware, um disco ou impressora, um software, um serviço, um arquivo e objetos de dados de todos os tipos, áudio, vídeo, etc.
Os Desafios dos Sistemas Distribuídos.

Os componentes de um sistema distribuídos são um grande desafio. Em sistemas centralizados isso não existe pois há um único componente que é o próprio sistema centralizado. Em SD é um pouco diferente pois temos diversos componentes espalhados, ou distribuídos por diferentes servidores, que podem ser heterogêneos, com diferentes sistemas operacionais, de diferentes fabricantes, com diferentes capacidades de processamento.

Daí surgem diversos desafios na computação distribuída, entre os quais podemos citar:

Segurança

Escalabilidade

Desempenho

Comunicação entre os componentes

Tolerância a falhas

Todos estes aspectos devem ser considerados quando trabalhamos com sistemas distribuídos. Em outras palavras:

Como podemos nos assegurar que somente os clientes válidos podem ter acesso aos serviços/componentes do sistema? ( Segurança )

Como podemos garantir que o sistema distribuído suportará aumento no número de usuários ou requisições? ( Escalabilidade )

Como podemos garantir um desempenho aceitável em um sistema distribuído, onde os componentes estão interligados por redes que nem sempre possuem a mesma velocidade e onde os componentes nem sempre tem a mesma capacidade de processamento, sem que surjam gargalos que comprometam o desempenho. ( Desempenho )

Como podemos garantir que todos os componentes possam se comunicar, considerando ambientes heterogêneos de rede, servidores, diferentes padrões de arquitetura e protocolos de comunicação? ( CORBA, .net, RMI, SOAP, REST, etc. )

Como podemos garantir a tolerância a falhas em um sistema com componentes distribuídos em servidores conectados a redes e ambientes? ( Tolerância a falhas )
A solução envolve não apenas projeto e arquitetura do software mas também infraestrutura na qual o software será executado.

Consequencias do uso de Sistemas Distribuidos
Como em um SD os componentes estão dispersos geograficamente surgem consequências a respeito dessa característica:

Concorrência - Como os processos são distribuídos pela rede a execução concorrente de programas é a norma. Um servidor executa um processo enquanto outro processo é executado em outra máquina sendo que ambos compartilham recursos como banco de dados, largura de banda de rede, discos, etc. A disputa por estes recursos compartilhados pelos processos que são executados concorrentemente é uma consequência dos SD e também um desafio a ser superado. A coordenação de processos em execução concorrente é uma das formas de tratar a concorrência.

Inexistência de relógio global - Em um SD, os processos precisam cooperar de forma coordenada através da troca de mensagens. A coordenação considera compartilhamento do tempo em que os processos são executados. O problema é que existem limites para a precisão com a qual os servidores sincronizam os relógios em uma rede. O fuso horário é um fator complicador na sincronização dos processos.

Falhas independentes - Em qualquer sistema existem falhas e nos SD não é diferente. Os projetistas devem considerar as consequencias de cada falha. Falhas de rede, falhas de banco de dados, falhas de comunicação, falhas de todos os tipos acontecem.

As falhas na rede são problemáticas pois elas resultam no isolamento dos componentes do SD que não podem mais se comunicar e trabalhar juntos. Lentidão na rede também pode afetar os processos em execução.

A falha de um componente ou termino de um processo em um componente nem sempre é percebida imediatamente pelos demais componentes.

# data[].attributes.attachment_link.title
1 - Caracterização de Sistemas Distribuidos - Prof. Fernando De Siqueira - Sistemas Distribuidos

# data[].attributes.attachment_link.description
Nos primórdios da computação os sistemas eram todos centralizados. Todo o processamento era feito no mainframe. Os terminais eram usados apenas para entrada/saída de dados. Com o tempo, surgiram novas arquiteturas de computação que buscavam descentralizar o processamento. Foi quando surgiram os primeiros sistemas distribuídos.