Microsserviços – Parte IV

Este texto é de James Lewis e Martin Fowler, disponível em: http://martinfowler.com/articles/microservices.html.

Sugiro começar por aqui: Microsserviços – Parte I


Endpoints Inteligentes e Vias Ignorantes

Ao construir estruturas de comunicação entre os processos, vimos vários produtos e abordagens que enfatizam colocar uma quantidade significativa de inteligência no próprio mecanismo de comunicação. Um bom exemplo disso é o Barramento de Serviço Corporativo (Enterprise Service Bus – ESB), onde os ESBs incluem facilidades sofisticadas para roteamento de mensagem, coreografia, transformação e aplicação de regras de negócio.

A comunidade dos microsserviços favorece uma abordagem alternativa: endpoints inteligentes e vias ignorantes. As aplicações construídas com microsserviços buscam ser tão desacoplados e coesos quanto possível – eles são donos do próprio domínio e agem mais como filtros no sentido clássico do Unix – recebendo uma requisição, aplicando lógica como apropriado e produzindo uma resposta. Isso é coreografado usando protocolos simples tipo REST em vez de protocolos complexos como WS-Choreography, BPEL ou outra orquestração por uma ferramenta central.

Os dois protocolos mais comuns são requisição-resposta HTTP com APIs de recursos e mensagens leve [6]. A melhor expressão do primeiro é

Seja da web, não por trás da web
— Ian Robinson

Os times de microsserviços usam os princípios e protocolos que constroem a rede mundial de computadores (e, até certo ponto, o Unix). Comumente os recursos podem ser colocados em cache com pouco esforço por parte dos desenvolvedores e do pessoal de operações.

A segunda abordagem comum é usar um barramento de mensagens leve. A infraestrutura escolhida é tipicamente ignorante (age apenas como roteador das mensagens) – implementações simples como RabbitMQ ou ZeroMQ não fazem mais que prover uma estrutura confiável e assíncrona – a inteligência está nas pontas que estão produzindo e consumindo as mensagens, nos serviços.

Em um monolito, os componentes estão executando dentro do mesmo processo e a comunicação entre eles é por invocação de método ou chamada de função. O maior problema em transformar um monolito em microsserviços é mudar o padrão de comunicação. Uma conversão ingênua de métodos em memória para chamadas de procedimentos remotos leva a muita comunicação e pouca performance. Em vez disso, você precisa trocar a comunicação afinada por uma abordagem menos granulada.

Governança Decentralizada

Uma das consequências da governança centralizada é a tendência de padronizar em uma única plataforma tecnológica. A experiência mostra que essa abordagem é constringente – nem todo problema é um prego e nem toda solução é um martelo. Preferimos usar a ferramenta certa para a tarefa, e, enquanto aplicações monolíticas podem se aproveitar de linguagens diferentes até certo ponto, isso não é comum.

Ao dividir os componentes de um monolito em serviços, temos uma escolha na hora de construir cada um deles. Você quer usar Node.js para uma página simples de relatório? Vá em frente. C++ para um componente particular que precisa de tempo-real? Ótimo. Você quer trocar para um banco de dados diferente que se encaixa no comportamento de leitura de um componente? Temos a tecnologia para reconstruí-lo.

É claro, só porque você pode fazer algo, não quer dizer que você deveria – mas ao partir um sistema dessa forma você tem essa opção.

Equipes construindo microsserviços preferem uma abordagem diferente aos padrões também. Em vez de usar um conjunto definido de padrões escritos em algum papel, eles preferem a ideia de produzir ferramentas úteis que outros desenvolvedores podem usar para resolver problemas parecidos. Essas ferramentas são colhidas de implementações e compartilhadas com um grupo mais amplo, às vezes, usando um modelo interno de código aberto. Agora que o git e o github se tornaram sistemas de controle de versão bastante comuns, práticas de código aberto estão cada vez mais comuns internamente.

Netflix é um bom exemplo de uma empresa que segue essa filosofia. Compartilhando como bibliotecas os códigos úteis, e acima de tudo testados em batalha, encoraja outros desenvolvedores a resolverem problemas parecidos de formas parecidas. E ao mesmo tempo deixa a porta aberta para escolher abordagens diferentes se necessário. Bibliotecas compartilhadas tendem a ser focadas em problemas comuns de armazenamento de dados, comunicação entre processos e, como discutiremos à frente, automatização da infraestrutura.

Para a comunidade de microsserviços, overheads não são atraentes. Não quer dizer que a comunidade não dá valor a contratos de serviços. Pelo contrário, há mais deles. É só que eles estão buscando por formas diferentes de gerenciá-los. Padrões como Leitor Tolerante e Contrato Orientado ao Consumidor são tipicamente aplicados aos microsserviços. Isso ajuda os contratos de serviço a evoluírem independentemente. Executando contratos orientados ao consumidor como parte da sua construção aumenta a confiança e trás um feedback rápido de se os serviços estão funcionando. Conhecemos uma equipe na Austrália que orienta a construção de novos serviços com contratos orientados ao consumidor. Eles usam ferramentas simples que permitem definir o contrato para um serviço. Isso se torna parte de uma build antes que o código para o novo serviço seja escrito. O serviço é então construído somente até o ponto em que satisfaz o contrato – uma abordagem elegante para evitar o dilema “YAGNI” [9] ao construir um novo software. Essas técnicas e ferramentas crescendo em torno delas limitam a necessidade de gerenciamento de contrato central ao reduzir o acoplamento temporal entre os serviços.

Talvez o apogeu da governança descentralizada é o “você construiu, você roda” popularizado pela Amazon. Times são responsáveis por todos os aspectos do software que construíram, incluindo operar o software 24/7. A devolução desse nível de responsabilidade não é a norma, mas vemos cada vez mais empresas empurrando responsabilidade para os times de desenvolvimento. A Netflix é outra empresa que adotou esse etos [11]. Acordar às 3h da manhã todas as noites é um poderoso incentivo para focar na qualidade ao escrever o código. Essas ideias estão bem longe da governança centralizada tradicional.

Microsserviços e Arquitetura Orientada a Serviços

Quando falamos de microsserviços, uma pergunta comum é se isso é só Arquitetura Orientada a Serviços (SOA) que vimos uma década atrás. Faz sentido, porque o estilo de microsserviços é bem parecido com o que alguns defensores do SOA dizem. O problema, porém, é que SOA significa muitas coisas diferentes, e que na maioria das vezes que temos algo chamado de “SOA”, ele é significativamente diferente do estilo que descrevemos aqui, normalmente devido ao foco em ESBs usados para integrar aplicações monolíticas.

Particularmente, vimos tantas implementações de orientação a serviços estragadas que é difícil olhar através desses problemas – desde a tendência a esconder a complexidade dentro de ESBs [7], até as iniciativas que duram muitos anos, custam milhões e entregam nenhum valor, ou até os modelos de governança centralizada que inibem ativamente mudanças.

Certamente, várias técnicas usadas na comunidade de microsserviços cresceram de experiências de desenvolvedores integrando serviços em grandes empresas. O padrão Leitor Tolerante é um exemplo disso. Esforços em usar a web contribuíram, usar protocolos simples é outra abordagem derivada dessas experiências – uma reação longe dos principais padrões que alcançaram uma complexidade que é francamente, de tirar o fôlego. (Se em algum momento você precisar de uma ontologia para gerenciar suas ontologias, você saberá que está em apuros.)

Essa manifestação comum de SOA levou os defensores de microsserviços a rejeitar completamente o rótulo SOA, apesar de que alguns consideram microsserviços como uma forma de SOA[8], talvez orientação a serviços feito corretamente. De qualquer forma, o fato de que SOA significa coisas tão diferentes quer dizer que é valioso ter um termo que defina melhor esse estilo arquitetural.

Muitas linguagens, muitas opções

O crescimento da Máquina Virtual Java (JVM) como uma plataforma é só um exemplo recente da mistura de linguagens em uma plataforma comum. É uma prática comum para por uma linguagem de alto nível para obter as vantagens de abstrações de alto nível por décadas. Assim como cair para a máquina e escrever código de performance em uma linguagem de baixo nível. No entanto, muitos monolitos não precisam desse nível de otimização de performance nem são linguagens de domínio específico (DSL) ou de níveis de abstração mais altos. Em vez disso, monolitos são normalmente de uma linguagem só, e a tendência é limitar o número de tecnologias em uso [10].

Padrões testados em batalha e padrões forçados

É uma dicotomia que equipes de microsserviços tendem a evitar os tipos de padrões rígidos forçados pelos grupos de arquitetura da empresa, mas vão usar e até evangelizar alegremente os padrões abertos como HTTP, ATOM e outros micro formatos.

A diferença é como os padrões são desenvolvidos e como são forçados. Padrões gerenciados por grupos como o IETF só se tornam padrões quando há muitas implementações deles rodando no mundo e que cresceram de projetos de código aberto.

Esses padrões estão a um mundo de distância de muitos no mundo corporativo, que são desenvolvidos por grupos que têm menos experiência com programação ou é influenciada pelos fornecedores.


[6] Nos extremos da escala, as empresas optam por protocolos binários – protobufs, por exemplo. Os sistemas que usam isso ainda exibem a característica de pontas inteligentes, barramentos ignorantes – e trocam a transparência pela escalabilidade. A maioria das propriedades web e certamente a maioria das empresas não precisam fazer essa troca – a transparência pode ser uma vitória.

[7] É irresistível mencionar a afirmação de Jum Webber de que ESB significa “Egregious Spaguetti Box” (“Caixa Escandalosa de Espaguete”).

[8] Netflix deixa a ligação explícita – até recentemente se referiam ao estilo arquitetural como Arquitetura Orientada a Serviços refinada.

[9] “YAGNI” ou “You Aren’t Going to Need It” (“você não vai precisar disso”) é um princípio do XP e promove não adicionar funcionalidades até que você saiba que vai precisar delas.

[10] É um pouco de ingenuidade nossa afirmar que monolitos são feitos de uma linguagem – para construir sistemas na rede de hoje, você provavelmente precisa saber javascript, XHTML, CSS, a linguagem do servidor, e SQL ou algum dialeto ORM. Dificilmente é só uma linguagem, mas você sabe o que queremos dizer.

[11] Adrian Cocroft menciona especificamente “entrega do desenvolvedor” e “desenvolvedores rodam o que escreveram” nessa excelente apresentação em Flowcon, em novembro de 2013.

Anúncios
Marcado com: , , ,
Publicado em Microsserviços

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: