Desenvolvimento

26 out, 2016

Escalabilidade de aplicações web

Publicidade

Desenvolver um sistema web preparado para o futuro é uma tarefa árdua. Na maioria dos casos, a escalabilidade não é pensada no início, e só percebemos sua importância quando o projeto está em produção e com milhares de usuários e acessos simultâneos. Para ilustrar, vamos imaginar o seguinte cenário:

Você tem uma ideia inovadora e deseja colocá-la em prática como um aplicativo web. Para isso, escolhe a linguagem de programação com a qual já possui contato há muito tempo, pois não quer perder tempo pesquisando quais são as ferramentas disponíveis no mercado. Feito isso, o desenvolvimento é rápido.

Esse projeto possui controle de acesso de usuários, e isso é feito na forma padrão da maioria das linguagens: cookie de sessão armazenado em disco. Além disso, o sistema dispara e-mails para os usuários e possui API RESTful para acessos externos.

Em algum momento da vida útil do sistema, ele começa a crescer. Mais e mais usuários começam a perceber que sua ideia inovadora atende às suas necessidades e começam a utilizá-la com frequência. Porém, com mais usuários, vem também mais acesso, leitura, escrita e consumo de recursos da máquina. Problemas como lentidão e timeouts começam a irritar os usuários.

Nesse ponto, você se vê obrigado a gastar mais dinheiro com o servidor onde o código está hospedado na expectativa de que os problemas acabem, mas sem sucesso. A única alternativa que resta, então, é repensar o projeto e começá-lo do zero.

Ao projetar um sistema, temos que ter em mente algumas perguntas importantes:

  • Quais são as expectativas de acesso e armazenamento para o futuro?
  • O sistema escala de forma satisfatória? Ou seja, se eu expandir os recursos físicos da máquina, ele será mais rápido?
  • Meu sistema pode ser distribuído em várias máquinas e continuar funcionando da mesma forma?

Vamos enumerar alguns dos problemas do aplicativo acima:

O projeto é a base da aplicação

Esta é a primeira e mais difícil etapa de todo sistema: o projeto. O sistema acima passou muito rápido desta etapa e não foi capaz de prever os problemas que viria a sofrer. É nesta etapa que temos que olhar para as perguntas levantadas anteriormente (e muitas outras) e pensar em como fazer tudo se tornar realidade. Para o projeto ser um sucesso, devemos gastar todo tempo necessário nesta etapa para não termos surpresas no futuro.

Escolher qual tecnologia usar na aplicação também faz parte desta etapa. Essa escolha não deve se resumir apenas a selecionar aquela com a qual você se sente mais confortável em utilizar. A pesquisa e o aprendizado também devem fazer parte do planejamento do projeto. Toda tecnologia tem prós e contras, então devemos olhar com cautela para cada uma e decidir qual executará melhor a tarefa dada.

Armazenamento de informações

O armazenamento em disco da sessão é comum, porém a tarefa de deixar o sistema escalável fica mais difícil. Com a sessão gravada no servidor, é necessário que cada requisição do mesmo usuário seja redirecionada sempre para o mesmo servidor físico. Uma maneira fácil de evitar esse trabalho é armazená-la em um banco de dados. Um recurso muito utilizado para esse fim é o Redis.

Dividir e conquistar

Este é um dos conceitos mais antigos da sociedade. Antigamente, era utilizado apenas na política e na sociologia, mas também pode ser aplicado na computação.

O aplicativo exemplificado anteriormente possui diversas tarefas:

  • Tarefas básicas da própria aplicação
  • Controle de usuários
  • Envio de e-mails
  • Serviços na forma de API

Cada uma dessas tarefas pode existir sem a outra. Sendo assim, podemos separá-las fisicamente, criando projetos diferentes em servidores distintos. Dividir as responsabilidades torna o sistema mais rápido, mais escalável e de fácil manutenção.

Além da divisão por responsabilidades, podemos dividir a carga que cada tarefa executa. Isso consiste em ter múltiplas instâncias de cada uma, tanto no nível da aplicação quanto no de servidores.

Tecnologias recentes, como NodeJS em conjunto com PM2, permitem iniciar várias instâncias de uma aplicação no mesmo servidor sem ter que realizar muitas configurações. Além disso, se adicionarmos um web server, como o Nginx, podemos balancear a carga entre vários servidores, o que permite ter uma aplicação que divide o trabalho e escale muito bem com mais recursos.

Desenvolver sistemas escaláveis não é fácil, mas com bom planejamento conseguimos encontrar boas soluções e evitar dores de cabeça. Devemos ter em mente que os sistemas crescem e, quando isso acontece, temos que estar preparados para lidar com a situação sem precisar gastar rios de dinheiro.