BLOG | NGINX

Adotando microsserviços na Netflix: Lições para Design Arquitetônico

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Tony Mauro Miniatura
Tony Mauro
Publicado em 19 de fevereiro de 2015

Em algumas postagens de blog recentes, explicamos por que acreditamos ser crucial adotar uma arquitetura de aplicativo de quatro camadas , na qual os aplicativos são desenvolvidos e implantados como conjuntos de microsserviços . Está ficando cada vez mais claro que, se você continuar usando processos de desenvolvimento e arquiteturas de aplicativos que funcionavam bem há dez anos, você simplesmente não conseguirá agir rápido o suficiente para capturar e manter o interesse dos usuários móveis, que podem escolher entre um número cada vez maior de aplicativos.

A mudança para uma arquitetura de microsserviços cria oportunidades interessantes no mercado para as empresas. Para arquitetos e desenvolvedores de sistemas, ele promete um nível sem precedentes de controle e velocidade à medida que eles oferecem novas experiências web inovadoras aos clientes. Mas em um ritmo tão acelerado, pode parecer que não há muito espaço para erros. No mundo real, você não pode parar de desenvolver e implantar seus aplicativos enquanto reformula os processos para isso. Você sabe que seu sucesso futuro depende da transição para uma arquitetura de microsserviços, mas como fazer isso de fato?

Felizmente para nós, vários dos primeiros adeptos dos microsserviços agora estão generosamente compartilhando sua experiência no espírito do código aberto, não apenas na forma de código publicado, mas em apresentações em conferências e postagens em blogs. A Netflix é um exemplo importante. Como Diretor de Engenharia Web e depois Arquiteto de Nuvem, Adrian Cockcroft supervisionou a transição da empresa de um modelo de desenvolvimento tradicional com 100 engenheiros produzindo um aplicativo monolítico de aluguel de DVD para uma arquitetura de microsserviços com muitas equipes pequenas responsáveis pelo desenvolvimento de ponta a ponta de centenas de microsserviços que trabalham juntos para transmitir entretenimento digital para milhões de clientes da Netflix todos os dias. Atualmente membro de tecnologia da Battery Ventures, Cockcroft é um importante evangelista de microsserviços e arquiteturas nativas da nuvem e atua no Conselho Consultivo Técnico da NGINX.

Em uma série de postagens de blog em duas partes, apresentaremos os principais aprendizados de duas palestras que Cockcroft fez no ano passado, na primeira conferência anual da NGINX em outubro e em um Meetup de microsserviços do Vale do Silício alguns meses antes. (Também vale a pena assistir às gravações completas do vídeo .)

O que é uma arquitetura de microsserviços?

Cockcroft define uma arquitetura de microsserviços como uma arquitetura orientada a serviços composta de elementos fracamente acoplados que têm contextos limitados .

Fracamente acoplado significa que você pode atualizar os serviços de forma independente; atualizar um serviço não exige alteração de nenhum outro serviço. Se você tem vários serviços pequenos e especializados, mas ainda precisa atualizá-los juntos, eles não são microsserviços porque não são fracamente acoplados. Um tipo de acoplamento que as pessoas tendem a ignorar ao fazer a transição para uma arquitetura de microsserviços é o acoplamento de banco de dados, onde todos os serviços se comunicam com o mesmo banco de dados e atualizar um serviço significa alterar o esquema. Você precisa dividir o banco de dados e desnormalizá-lo.

O conceito de contextos limitados vem do livro Domain Driven Design, de Eric Evans. Um microsserviço com contexto corretamente delimitado é autocontido para fins de desenvolvimento de software. Você pode entender e atualizar o código do microsserviço sem saber nada sobre os componentes internos de seus pares, porque o microsserviço e seus pares interagem estritamente por meio de APIs e, portanto, não compartilham estruturas de dados, esquemas de banco de dados ou outras representações internas de objetos.

Se você desenvolveu aplicativos para a Internet, já está familiarizado com esses conceitos, na prática, se não pelo nome. A maioria dos aplicativos móveis conversa com vários serviços de backend, para permitir que seus usuários façam coisas como compartilhar no Facebook, obter direções do Google Maps e encontrar restaurantes no Foursquare, tudo dentro do contexto do aplicativo. Se seu aplicativo móvel estivesse fortemente acoplado a esses serviços, antes de poder lançar uma atualização, você teria que conversar com todas as equipes de desenvolvimento para ter certeza de que suas alterações não quebrariam nada.

Ao trabalhar com uma arquitetura de microsserviços, você pensa em outras equipes internas de desenvolvimento, como os backends da Internet: como serviços externos com os quais seu microsserviço interage por meio de APIs. O “contrato” comumente entendido entre microsserviços é que suas APIs sejam estáveis e compatíveis com versões futuras. Assim como é inaceitável que a API do Google Maps mude sem aviso e de uma forma que prejudique seus usuários, sua API pode evoluir, mas deve permanecer compatível com versões anteriores.

Melhores práticas para projetar uma arquitetura de microsserviços

Cockcroft descreve seu papel como Arquiteto de Nuvem na Netflix não em termos de controle da arquitetura, mas como descoberta e formalização da arquitetura que surgiu conforme os engenheiros da Netflix a construíram. A equipe de desenvolvimento da Netflix estabeleceu diversas práticas recomendadas para projetar e implementar uma arquitetura de microsserviços.

Crie um armazenamento de dados separado para cada microsserviço

Não use o mesmo armazenamento de dados de backend em todos os microsserviços. Você quer que a equipe de cada microsserviço escolha o banco de dados mais adequado ao serviço. Além disso, com um único armazenamento de dados, é muito fácil para microsserviços escritos por diferentes equipes compartilharem estruturas de banco de dados, talvez em nome da redução da duplicação de trabalho. Você acaba em uma situação em que, se uma equipe atualiza uma estrutura de banco de dados, outros serviços que também usam essa estrutura também precisam ser alterados.

Separar os dados pode tornar o gerenciamento de dados mais complicado, porque os sistemas de armazenamento separados podem facilmente ficar dessincronizados ou inconsistentes, e as chaves estrangeiras podem mudar inesperadamente. Você precisa adicionar uma ferramenta que execute o gerenciamento de dados mestres (MDM) operando em segundo plano para encontrar e corrigir inconsistências. Por exemplo, ele pode examinar todos os bancos de dados que armazenam IDs de assinantes para verificar se os mesmos IDs existem em todos eles (não há IDs faltantes ou extras em nenhum banco de dados). Você pode escrever sua própria ferramenta ou comprar uma. Muitos sistemas comerciais de gerenciamento de banco de dados relacional (RDBMSs) fazem esses tipos de verificações, mas geralmente impõem muitos requisitos de acoplamento e, portanto, não são escaláveis.

Mantenha o código em um nível de maturidade semelhante

Mantenha todo o código em um microsserviço em um nível semelhante de maturidade e estabilidade. Em outras palavras, se você precisa adicionar ou reescrever parte do código em um microsserviço implantado que está funcionando bem, a melhor abordagem geralmente é criar um novo microsserviço para o código novo ou alterado, deixando o microsserviço existente no lugar. [Editor – Isso às vezes é chamado de princípio de infraestrutura imutável .] Dessa forma, você pode implantar e testar iterativamente o novo código até que ele esteja livre de bugs e com eficiência máxima, sem correr o risco de falha ou degradação de desempenho no microsserviço existente. Quando o novo microsserviço estiver tão estável quanto o original, você poderá mesclá-los novamente se eles realmente executarem uma única função juntos ou se houver outras eficiências na combinação deles. No entanto, na experiência de Cockcroft, é muito mais comum perceber que você deve dividir um microsserviço porque ele ficou grande demais.

Faça uma compilação separada para cada microsserviço

Faça uma compilação separada para cada microsserviço, para que ele possa extrair arquivos de componentes do repositório nos níveis de revisão apropriados para ele. Isso às vezes leva à situação em que vários microsserviços extraem um conjunto semelhante de arquivos, mas em diferentes níveis de revisão. Isso pode dificultar a limpeza da sua base de código ao desativar versões antigas de arquivos (porque você precisa verificar com mais cuidado se uma revisão não está mais sendo usada), mas essa é uma troca aceitável pela facilidade de adicionar novos arquivos à medida que você cria novos microsserviços. A assimetria é intencional: você quer que a introdução de um novo microsserviço, arquivo ou função seja fácil, não perigosa.

Implantar em contêineres

Implantar microsserviços em contêineres é importante porque significa que você só precisa de uma ferramenta para implantar tudo. Enquanto o microsserviço estiver em um contêiner, a ferramenta saberá como implantá-lo. Não importa qual seja o recipiente. Dito isso, o Docker parece ter se tornado rapidamente o padrão de fato para contêineres.

Tratar servidores como sem estado

Trate os servidores, especialmente aqueles que executam código voltado para o cliente, como membros intercambiáveis de um grupo. Todos eles desempenham as mesmas funções, então você não precisa se preocupar com eles individualmente. Sua única preocupação é que haja números suficientes para produzir a quantidade de trabalho necessária, e você pode usar o dimensionamento automático para ajustar os números para cima ou para baixo. Se um parar de funcionar, ele será automaticamente substituído por outro. Evite sistemas “floco de neve” nos quais você depende de servidores individuais para executar funções especializadas.

A analogia de Cockcroft é que você deve pensar em servidores como gado, não como animais de estimação. Se você tem uma máquina em produção que executa uma função especializada, e você a conhece pelo nome, e todo mundo fica triste quando ela quebra, ela é um animal de estimação. Em vez disso, você deve pensar em seus servidores como um rebanho de vacas. O que importa é quantos galões de leite você obtém. Se um dia você perceber que está produzindo menos leite do que o normal, descubra quais vacas não estão produzindo bem e as substitua.

A arquitetura de entrega da Netflix é construída no NGINX

A Netflix é uma usuária de longa data do NGINX Open Source e se tornou a primeira cliente da NGINX, Inc. após sua incorporação em 2011. De fato, a Netflix escolheu o NGINX como o coração de sua infraestrutura de entrega, o Open Connect , uma das maiores redes de entrega de conteúdo (CDNs) do mundo. Com a capacidade de atender milhares, e às vezes milhões, de solicitações por segundo, o NGINX e o NGINX Plus são soluções ideais para entrega HTTP de alto desempenho e permitem que empresas como a Netflix ofereçam experiências digitais de alta qualidade a milhões de clientes todos os dias.

Gravações de vídeo

Entrega rápida
nginx.conf 2014, outubro de 2014

Migrando para microsserviços, parte 1
Silicon Valley Microservices Meetup, agosto de 2014

Migrando para microsserviços, parte 2
Silicon Valley Microservices Meetup, agosto de 2014


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."