Hoje em dia, dimensionar aplicativos e APIs não significa escolher o algoritmo de balanceamento de carga correto. Nas mais de duas décadas de evolução da entrega de aplicativos, a única coisa que permaneceu bastante constante foram os algoritmos de balanceamento de carga. Seu principal benefício é manter a disponibilidade. Seu impacto no desempenho é, na melhor das hipóteses, mínimo.
Isso não quer dizer que escolher um algoritmo seja irrelevante. Afinal, o round robin raramente é a melhor escolha para uma API ou aplicativo, mas a escolha entre menos conexões e resposta mais rápida tem menos probabilidade de ter impacto no desempenho geral e na disponibilidade de um serviço digital do que sua arquitetura.
O que será uma perspectiva arquitetônica sobre a entrega de aplicativos em resposta à elevação da entrega de aplicativos como um dos seis principais recursos necessários para projetar e operar serviços digitais.
Um algoritmo de balanceamento de carga é uma abordagem programática para distribuir carga em um conjunto de recursos para garantir a disponibilidade e melhorar o desempenho.
Um algoritmo de balanceamento de carga especifica como recursos específicos são escolhidos e quais variáveis são consideradas.
Round Robin é o algoritmo mais simples e simplesmente itera sobre um conjunto conhecido de recursos em ordem sequencial. Se houver três recursos – A, B e C – então o round robin encaminha a primeira solicitação para A, a segunda para B e a terceira para C. O processo de seleção então começa novamente.
Least Connections é um algoritmo baseado no segundo axioma operacional que afirma que "à medida que a carga aumenta, o desempenho diminui". Assim, o algoritmo de menos conexões escolherá o recurso com menos conexões (carga). Existem variações desse algoritmo, principalmente a de conexões menos ponderadas , que permite diferenças de capacidade entre os recursos.
O tempo de resposta mais rápido é usado quando o desempenho é uma prioridade máxima. O balanceador de carga determinará, passiva ou ativamente, o tempo de resposta de cada recurso e, para cada solicitação, escolherá o mais rápido. Este algoritmo não garante o tempo de resposta do usuário , pois não tem efeito na última milha ou nas condições da rede do usuário.
O IP de origem é um algoritmo remanescente do balanceamento de carga de rede que usa um valor de hash simples para o IP de origem (cliente) para escolher um recurso. Este algoritmo sempre selecionará o mesmo recurso para um determinado IP de origem. Esse algoritmo caiu em desuso porque está sujeito ao problema do "mega proxy", em que todos os usuários originários de um único proxy/endereço IP são direcionados para o mesmo recurso. Isso tende a sobrecarregar o recurso alvo, resultando em baixo desempenho e, por fim, falha.
Algoritmos de balanceamento de carga são uma parte importante da arquitetura de entrega de aplicativos, mas têm menos impacto no desempenho e na escala de um aplicativo ou serviço digital do que a abordagem arquitetônica geral.
Entrega de aplicativos é a disciplina de projetar uma arquitetura escalável e de alto desempenho para aplicativos, APIs e serviços digitais. Ele depende muito do balanceamento de carga como um componente principal, mas incorpora recursos modernos, como roteamento de camada 7, e aproveita padrões arquitetônicos comuns para otimizar o desempenho e a utilização eficiente de recursos.
Usamos o termo entrega de aplicativo para traçar deliberadamente uma linha entre balanceamento de carga, que é um detalhe de implementação, e arquitetura, que é um processo de design.
Escala é uma resposta técnica a um resultado comercial. Ou seja, a necessidade de manter a disponibilidade e o desempenho das cargas de trabalho que compõem um serviço digital para melhorar os índices de satisfação do cliente, as taxas de conversão e a geração de receita. Essa última parte é particularmente importante, pois nossa pesquisa nos diz que a maioria (58%) das empresas hoje obtém pelo menos metade de sua receita de serviços digitais.
Considere também, por exemplo, o uso da nuvem pública para continuidade de negócios (BC). O BC é um dos principais usos da nuvem pública e, em sua essência, é uma implementação de escala global, ou seja, balanceamento de carga global. O failover é um recurso essencial da entrega de aplicativos que, quando aplicado a um site inteiro, permite redirecionar rapidamente solicitações de um local para outro. A disponibilidade contínua da presença digital de uma empresa é um resultado comercial, possibilitado por uma resposta técnica.
Responder a essa pergunta dá início à nossa jornada técnica na arquitetura de entrega de aplicativos. Existem dois modelos de escala: vertical (para cima) e horizontal (para fora).
A escala vertical é baseada no princípio de que adicionar mais poder de processamento a um sistema aumentará a capacidade. Esse método de escala beneficia principalmente aplicações monolíticas e sistemas autocontidos. Além da infraestrutura, a maioria das organizações não depende mais da escala vertical porque isso exige a mudança do ambiente físico – adicionando CPUs ou RAM ou expandindo a capacidade da rede. Embora a escala vertical seja muito mais rápida pela virtualização, especialmente em ambientes de nuvem pública, a necessidade de migrar software e sistemas — mesmo para uma nova máquina virtual — pode ser prejudicial.
A escala horizontal é uma abordagem arquitetônica para adicionar mais poder de processamento aumentando o total de recursos disponíveis. Isso é obtido distribuindo o poder de processamento entre diversas instâncias de um aplicativo, serviço ou sistema. Esse é o método de dimensionamento mais comum atualmente, pois depende da duplicação de recursos em vez de migrá-los. Além disso, a escala horizontal oferece uma variedade maior de opções arquitetônicas do que a escala vertical , tornando-a mais adequada para todos os aplicativos e APIs.
Não é nenhuma surpresa que os padrões modernos de entrega de aplicativos sejam baseados no princípio da escala horizontal.
A simples escolha da escala horizontal não é o fim da discussão.
Uma vez tomada a decisão (geralmente é a decisão padrão), considerações adicionais devem orientar uma decisão arquitetônica em relação à implementação. A maneira mais simples de abordar essa decisão é através da lente do cubo de escala , conforme descrito no livro A Arte da Escalabilidade .
Simplificando, há três eixos no cubo de escala: x, y e z. Cada um deles é mapeado para um padrão arquitetônico de balanceamento de carga. Cada um desses padrões é apropriado para atender a resultados específicos relacionados ao desempenho e à disponibilidade, dados diferentes tipos de aplicativos e APIs.
Um serviço digital provavelmente usará uma arquitetura que incorpora vários padrões para otimizar o desempenho e o consumo de recursos ao mesmo tempo. Essa abordagem requer pensamento sistêmico, pois deve considerar todos os componentes, como eles irão interagir e como as solicitações fluirão do usuário para o aplicativo e vice-versa.
O padrão do eixo X é o padrão mais básico. Ele é baseado na duplicação horizontal e a maior parte do trabalho é realizada por meio de um algoritmo de balanceamento de carga. É o padrão mais simples e resulta no que chamo de Plain Old Load Balancing (POLB).
Chamamos isso assim por causa da simplicidade da arquitetura, que não aproveita os recursos avançados dos balanceadores de carga modernos para interagir com solicitações e respostas na camada de aplicação.
Nesse padrão, os aplicativos são duplicados e as solicitações são encaminhadas para uma instância com base na decisão do algoritmo de balanceamento de carga configurado.
Como esse padrão é frequentemente usado em conjunto com o TCP (camada 4), ele tem vantagens de desempenho em relação a outros padrões que dependem da inspeção do HTTP (camada 7). Principalmente, as conexões podem ser costuradas em vez de proxy, o que efetivamente transforma o balanceador de carga em um salto de rede após a conexão inicial. Isso resulta em maior desempenho geral, mas elimina a capacidade do balanceador de carga de inspecionar ou agir em solicitações e respostas após a conexão inicial. Como as arquiteturas do eixo X são excelentes para garantir disponibilidade e podem ter alto desempenho, elas são frequentemente usadas para dimensionar serviços de infraestrutura e segurança, como firewalls e gateways de aplicativos.
Uma variedade de aplicativos tradicionais (monólitos, web de três camadas e cliente-servidor) tendem a ser dimensionados usando esse padrão, pois raramente esses aplicativos são decompostos em componentes mais discretos que podem ser aproveitados para arquiteturas modernas de entrega de aplicativos.
Esse padrão é baseado na decomposição funcional e aproveita os recursos da camada de aplicação (camada 7) de entrega de aplicativos para dimensionar com base em funções em vez de sistemas inteiros. O padrão do eixo y é o primeiro padrão no qual o roteamento da camada 7 se torna uma ferramenta essencial na caixa de ferramentas da arquitetura de entrega de aplicativos.
Em geral, os padrões baseados em y e z aproveitam o roteamento da camada 7 para escolher um pool e, então, um algoritmo de balanceamento de carga é usado para selecionar um recurso específico. Isso diverge do padrão x básico, no qual nenhum roteamento de camada 7 é usado.
Esse padrão pressupõe operação na camada 7, normalmente HTTP, e usa alguma variável para distribuir tráfego para instâncias específicas de um aplicativo ou serviço. Por exemplo, se o padrão /login for encontrado no URI, o balanceador de carga escolherá uma instância, com base no algoritmo de balanceamento de carga configurado, em um pool de instâncias de aplicativo que lidam apenas com solicitações de login. A variável pode ser qualquer coisa no cabeçalho da solicitação ou na carga útil da solicitação. Isso permite roteamento baseado em agente, roteamento de API e roteamento baseado em conteúdo (imagens, scripts, etc.).
Instâncias de aplicativos podem ser clones. Isso geralmente acontece quando há disparidade no uso de um aplicativo que pode ser identificada por uma variável na solicitação. Por exemplo, funções de login versus checkout pode ser discernido em uma solicitação com base no URI, em um valor no cabeçalho HTTP ou por um valor na carga útil da solicitação. A aplicação de um padrão de eixo y permite que aplicativos tradicionais sejam dimensionados com base na função, o que resulta em maior eficiência na utilização de recursos porque mais recursos podem ser alocados para lidar com funções de alto volume, mantendo o desempenho esperado de outras funções.
O uso do padrão do eixo y para dimensionar funcionalmente aplicativos tradicionais teve origem antes da prevalência dos microsserviços, que hoje decompõem funcionalmente os aplicativos. O padrão do eixo y ainda é aplicável a microsserviços e, de fato, o padrão é implementado por controladores de entrada hoje. Leitores atentos notarão que esse padrão também é aplicável a APIs, já que elas dependem de construções HTTP (camada 7), o que não é surpresa que os gateways de API aproveitem esse padrão fundamental.
Esse padrão foi popularizado pelo eBay nos primeiros dias da Web 2.0. Sua arquitetura de escalabilidade incluía então a segmentação de funções em pools de aplicativos separados. A funcionalidade de venda era atendida por um conjunto de servidores de aplicativos, a de lances por outro e a de pesquisa por outro ainda. No total, eles organizaram cerca de 16.000 servidores de aplicativos em 220 pools diferentes. Isso permitiu que eles dimensionassem cada pool independentemente um do outro, de acordo com as demandas e o consumo de recursos de sua função. Além disso, isso permitiu que eles isolassem e racionalizassem as dependências de recursos — o pool de vendas só precisava se comunicar com um subconjunto relativamente pequeno de recursos de back-end, por exemplo.
O padrão do eixo y também pode ser usado para distribuir diferentes tipos de solicitações de conteúdo, como imagens, para um conjunto de recursos e outros tipos de conteúdo para outros.
Usar o eixo y para distribuir a carga permite que os componentes de um serviço digital sejam dimensionados individualmente, o que é muito mais eficiente em termos de utilização de recursos do que um padrão de eixo x. Ele permite a otimização da configuração na camada de serviço ou aplicativo, o que pode melhorar seu desempenho ajustando variáveis específicas no servidor da web ou de aplicativo para otimizar um determinado tipo de conteúdo.
O padrão do eixo Z se tornou popular por pura necessidade com o crescimento explosivo das mídias sociais e da Internet em geral. É, essencialmente, um padrão de escala do eixo Y com segmentação adicional aplicada, normalmente com base em uma variável específica, como nome de usuário ou identificador de dispositivo.
Esse padrão permite diferenciação arquitetônica usando uma técnica derivada de fragmentação de dados.
Este padrão aplica os princípios usados em bancos de dados para distribuir solicitações com base em algum dado na solicitação. Ele pode ser usado para ajudar a resolver gargalos na camada de dados, bem como um meio de garantir a conformidade com as regras de soberania de dados. Ele usa uma variável identificável – e normalmente única – para rotear solicitações em um conjunto de recursos dimensionado horizontalmente. Esse padrão geralmente é usado quando é necessário alto rendimento, como volumes significativos de solicitações para um serviço ou aplicativo específico.
O padrão do eixo Z é particularmente útil para gerenciar dispositivos de ponta e IoT, que podem chegar a milhões. Ao usar identificadores de dispositivo como padrão base para solicitações de fragmentação, a velocidade com que os dados podem ser transferidos pode ser significativamente melhorada. Isso pode ser particularmente útil para dispositivos que armazenam suas configurações em um local remoto (nuvem ou data center), pois esses dados são exclusivos do dispositivo e podem ser fragmentados com segurança.
Esse padrão tende a melhorar o desempenho porque o acesso a dados com alta carga pode degradar significativamente o desempenho. Assim, ao dividir o acesso aos dados entre mais instâncias, a carga diminui e, com ela, o desempenho melhora. Isso requer atenção especial à integridade dos dados e pode resultar em problemas de consistência quando usado para fragmentar dados compartilhados. A Meta elevou o tópico de fragmentação quando desenvolveu a fragmentação de serviço como parte de sua arquitetura geral. Sua atenção cuidadosa ao desenvolvimento de uma arquitetura de entrega de aplicativos de alto desempenho e escalável é um excelente exemplo de como reconhecer a entrega de aplicativos como uma camada formal dentro de uma arquitetura maior pode gerar benefícios significativos.
Para serviços que acessam fontes de dados não primárias, um padrão de eixo z pode melhorar o rendimento sem impactar significativamente a qualidade dos dados em todo o sistema. Essa abordagem alivia a necessidade de adicionar código para vincular uma instância específica de um aplicativo ou API a uma fonte de dados, confiando, em vez disso, na combinação da configuração dos conectores de dados no nível da instância e no roteamento de entrega do aplicativo para garantir que a fonte de dados correta seja usada.
Hoje em dia, em um mundo onde serviços digitais são entregues, é raro usar apenas um único padrão de entrega de aplicativo para arquitetar um serviço digital confiável e de alto desempenho. Isso ocorre devido à complexidade inerente dos serviços digitais e à crescente diversidade de "usuários" - que pode abranger dispositivos, humanos e software.
Assim, uma abordagem arquitetônica considera o melhor uso dos padrões de entrega de aplicativos em um serviço digital para oferecer uma experiência ideal aos usuários.
Não existe uma solução arquitetônica "certa" ou "errada" porque ela é altamente dependente dos serviços e aplicativos que compõem um serviço digital, exceto que tal solução não deve ser baseada apenas em algoritmos de balanceamento de carga.
De fato, é importante observar que não houve menção à seleção de algoritmo, pois a escolha de como a carga é distribuída dentro de um padrão de balanceamento de carga não é tão relevante quanto fazer a escolha arquitetônica correta para um aplicativo ou API específica.
Este é um dos fatores que impulsionam a entrega de aplicativos como disciplina . A maneira como a entrega e a segurança de aplicativos são usadas e implementadas hoje vai muito além da simples escala de um servidor web. Sua implementação pode impactar o desempenho, a disponibilidade e, por fim, determinar o sucesso ou o fracasso dos resultados comerciais. Portanto, é importante que as organizações abordem a entrega de aplicativos como uma ferramenta estratégica e arquitetônica em seu conjunto de ferramentas de design.
O balanceamento de carga continua sendo o principal requisito técnico para escala. Entender os padrões de entrega de aplicativos e como eles aproveitam o balanceamento de carga fornecerá uma melhor perspectiva sobre a arquitetura de escala e desempenho de serviços digitais, especialmente quando esses serviços provavelmente serão híbridos e compreenderão uma mistura de APIs e aplicativos modernos e tradicionais.