Sessões Sticky com Apache APISIX - Teoria

Nicolas Fränkel

Nicolas Fränkel

July 27, 2023

Technology

Sessões aderentes, também conhecidas como afinidade de sessão, são um mecanismo pelo qual um componente de roteamento que atua como uma fachada sempre encaminha uma solicitação para o mesmo nó upstream subjacente. Neste post, vou descrever a razão por trás das sessões aderentes, as alternativas disponíveis e como implementá-las via Apache APISIX.

Por que Sessões Aderentes?

As sessões aderentes se tornaram populares quando armazenávamos o estado no nó upstream, e não no banco de dados. Vou usar o exemplo de uma loja de e-commerce simplificada para explicar melhor.

Os fundamentos básicos de um pequeno site de e-commerce podem consistir em uma aplicação web e um banco de dados.

Arquitetura básica de um aplicativo de e-commerce

Se o negócio for bem-sucedido, ele crescerá, e em algum momento você precisará escalar essa arquitetura. Quando não for mais possível escalar verticalmente (máquinas maiores), você terá que escalar horizontalmente (mais nós). Com nós adicionais de aplicação, você também precisará de um mecanismo de balanceamento de carga na frente dos nós da aplicação web para distribuir a carga entre eles.

Arquitetura de Balanceamento de Carga para nós adicionais

Acessar o banco de dados toda vez é uma operação cara. É aceitável para dados que são acessados com pouca frequência. No entanto, queremos exibir o conteúdo do carrinho para cada solicitação. Algumas alternativas estão disponíveis para acelerar as coisas. Se assumirmos que a aplicação web usa Renderização no Lado do Servidor (Server-Side Rendering), a solução clássica é manter os dados relacionados ao carrinho na memória no nó da aplicação web.

No entanto, se armazenarmos o carrinho do usuário X no nó 1, precisamos garantir que encaminhemos todas as solicitações do usuário X para o mesmo nó. Caso contrário, ele sentirá como se tivesse perdido o conteúdo do carrinho. Sessões aderentes, ou afinidade de sessão, é o mecanismo que encaminha consistentemente o mesmo usuário para o mesmo nó.

Limitação das Sessões Aderentes

Antes de prosseguir, preciso explicar uma limitação significativa das sessões aderentes. Se o nó da aplicação web que armazena os dados cair por qualquer motivo, os dados serão irremediavelmente perdidos. Para o cenário de e-commerce acima, isso significa que os usuários perderão ocasionalmente o carrinho, o que é inaceitável do ponto de vista do negócio.

Por essa razão, as sessões aderentes devem andar de mãos dadas com a replicação de sessão: os dados armazenados em um nó devem ser copiados e mantidos sincronizados com todos os outros nós.

Embora a replicação de sessão exista em todas as pilhas tecnológicas, não há uma especificação relacionada. Estou familiarizado com a JVM, então aqui estão algumas opções:

  • O Tomcat oferece replicação de sessão pronta para uso
  • Hazelcast oferece uma solução de memória em cluster que você pode integrar em diferentes níveis
  • Spring Session é uma camada de abstração sobre soluções específicas

Quando os dados são replicados em todos os nós (ou em um cluster remoto), você pode pensar que não precisa mais de sessões aderentes. Isso é verdade se considerarmos apenas a disponibilidade e não o desempenho. Trata-se de localidade de dados: buscar dados no nó atual é mais rápido do que buscá-los em outro lugar via rede.

Sessões Aderentes no Apache APISIX

Sessões aderentes são um recurso essencial para qualquer Balanceador de Carga, Proxy Reverso e Gateway de API que se preze. No entanto, devo admitir que a documentação do Apache APISIX precisa de um ponto de entrada fácil no assunto.

O Apache APISIX vincula uma rota a um upstream. Um upstream consiste em um ou mais nós. Quando uma solicitação corresponde à rota, o Apache APISIX deve escolher entre todos os nós disponíveis para encaminhar a solicitação. Por padrão, o algoritmo é o round-robin ponderado. O round-robin usa um nó após o outro e, após o último, volta ao primeiro. Com um round-robin ponderado, o peso afeta quantas solicitações o Apache APISIX encaminha para um nó antes de mudar para o próximo.

No entanto, outros algoritmos estão disponíveis:

O hash consistente permite encaminhar para o mesmo nó dependendo de algum valor: uma variável do NGINX, um cabeçalho HTTP, um cookie, etc.

Lembre-se de que o HTTP é um protocolo sem estado, então os servidores de aplicação definem um cookie na primeira resposta para rastrear o usuário entre as solicitações HTTP. É o que chamamos de "sessão". Precisamos saber o nome do cookie de sessão subjacente. Diferentes servidores de aplicação emitem cookies diferentes:

  • JSESSIONID para servidores baseados em JVM
  • PHPSESSID para PHP
  • ASPSESSIONID para ASP.Net
  • etc.

Vou usar um Tomcat regular, então o cookie de sessão é JSESSIONID. Portanto, a documentação do Apache APISIX para dois nós é a seguinte:

routes:
  - uri: /*
    upstream:
      nodes:
        "tomcat1:8080": 1            #1
        "tomcat2:8080": 1            #1
      type: chash                    #2
      hash_on: cookie                #3
      key: cookie_JSESSIONID         #4
  1. Define os nós upstream
  2. Escolhe o algoritmo de hash consistente
  3. Hash no cookie
  4. Define qual cookie usar para o hash

Conclusão

Neste post, detalhamos as sessões aderentes, que você deve sempre usar replicação de sessão com sessões aderentes, e como implementar sessões aderentes no Apache APISIX.

Para ir mais longe:

Tags: