sábado, 7 de março de 2015

Manutenção de estado e acoplamento











Volta e meia esse tipo de discussão vem à tona: P6 o REST não permite manter dados de sessão... não seria melhor usar SOAP?

Então, já que estamos preparando nossa série sobre Microsserviços, torna-se imperativo esclarecer os males da manutenção de estado de conversação, em aplicações servidoras.



Dois tipos de estado



Quando falamos de arquitetura Cliente/Servidor, temos que admitir dois tipos de estado:

  • Conversação: O estado da interação entre o Cliente e o Servidor, durane uma sessão de conversação

  • Recurso: O estado do recurso mantido pelo Servidor


Um Servidor é uma máquina de estados, quando se trata do estado permanente dos recursos. Porém, deveria se comportar assim com o estado transiente?

Estado de conversação são dados mantidos no Servidor, em função de uma "conversa" com um Cliente. São individualizados para cada Cliente, e, geralmente, são mantidos em memória.

Estado de recurso é manutenção de estado de recursos no Servidor, alterados de acordo com as solicitações feitas pelo Cliente. E são feitos em memória permanente. Por exemplo, os dados de um novo Produto.


Statefull vs Stateless



Quando um Servidor é obrigado a manter dados entre chamadas de um Cliente, dizemos que ele é "statefull". Ou seja, a cada chamada do mesmo Cliente, na mesma sessão, ele se "lembra" do Cliente e sabe em qual estado está a "conversa" com ele.

Um servidor "stateless" não guarda estado de conversação, logo, não sabe dizer se já falou com determinado Cliente.

Servidores "statefull" podem trazer algum conforto na programação, afinal, possuem total controle sobre a "sessão" do usuário.

Servidores "stateless" desconhecem o conceito de "sessão", o que significa que um maior esforço de programação deve ser feito, caso seja necessário controlar o estado de conversação.

O que você quer controlar?



Controlar o estado da conversação, embora seja uma técnica muito utilizada, é uma solução ruim.

Para começar, implica que todos os pedidos de um Cliente devem ser encaminhados à mesma instância de um Servidor. Isso atrapalha a escalabilidade de sua aplicação, tanto vertical como horizontal.

O Servidor consome mais memória para guardar o estado de cada Cliente, com o qual esteja "conversando", e você "amarra"os clientes às Instâncias dos servidores.

É claro que isso pode ser contornado, e existem duas técnicas muito usadas:

  1. Migração de sessão: Se o pedido de um Ciente cair em um Servidor diferente, este solicita ao Servidor original a "migração" do estado da conversação

  2. Manter estado no database: A "sessão" é gravada em um Banco de dados, e o identificador é passado a cada pedido


Ambas são soluções ruins. Migrar sessão pode acabar com os benefícios da escalabilidade, pois aumenta o tráfego entre Servidores e implica em consumir ciclos de CPU só em operações de transferência. E manter estado no database implica em acessos desnecessários.

Afinal, você quer controlar o quê? A sequência dos eventos ou a maneira como os outros programam?

Quando um módulo "controla" a maneira ou a ordem na qual o outro execua duas tarefas, existe um Acoplamento de Controle entre eles. Logo, a vantagem de Baixo acoplamento de qualquer solução baseada em Serviços, é perdida.

Outras maneiras de manter estado



Se é uma transação simples, envolvendo apenas um Cliente Web e um RESTful service, então é melhor que o Cliente Web mantenha o estado da conversação, guardando os dados em "SessionStorage".

Session Storage é um dos adventos do HTML 5 e é muito segura. Os dados nunca "viajam", como os Cookies, e são individualizados por usuário e por URL.

Agora, se você tem uma série de Serviços, que devem executar suas operações baseados em determinado estado de conversação, é melhor usar "Coreografia" baseada em Eventos.

Existem duas maneiras de controlar um barramento de serviços:

  • Orquestração: Um "maestro" controla a ordem da execução de vários Serviços

  • Coreografia: Cada Serviço monitora uma fila de Eventos, e, se determinado Evento ocorrer, ele sabe exatamente como deve agir


Coreografia é, de longe, o mais vantajoso mecanismo de coordenação entre múltiplos serviços. E existem várias soluções para implementar a fila de Eventos, desde Servidores de Fila até mecanismos de eventos associados ao Sistema Operacional.

Conclusão




  • Servidor "statefull": Ruim. Menino mau! Vai ficar de castigo!

  • Servidor "stateless": Bom. Bom garoto! Vai ganhar um brinquedo!