O que é um microservice?
Esse post é uma tradução literal da explicação do meu amigo Javi Moreno, @ciberado em twitter, direto do seu blog programar.cloud.
Porque NÃO iria escrever este post
Porque você já sabe o que é um microservice! Ok, o termo é relativamente recente (2013 ou 2014) mas nessa altura do campeonato certeza que já esteve exposto ou exposta a isso. Além do que não vou ser eu quem melhore a descrição que faz disso Martin Fowler, que é um cara que precisamos escutar a pesar de que escreva livros técnicos.
Então, o que me fez mudar de ideia? Exato: o SEO do Google, principalmente. Bom, e também saber que existe uma remota possibilidade de que, mesmo que tenha noção sobre a terminologia, você não tenha ainda claro o que entra dentro da definição e o que não. Assim que vamos lá e concretemos um pouco.
O que não é um microservice
Um microservice não é uma API web. Ou melhor, que o seu sistema se comunique com o exterior por meio de uma API não garante que estará desenhando microservice. Se o 30% da funcionalidade do seu produto é proporcionada por um componente único, existem muitas possibilidades de que seja um monolítico clássico disfarçado de microservice. E também existe um 90% de probabilidades de que tenha inventado a porcentagem anterior… mas da para entender o que estou dizendo. E olha que estou falando de funcionalidades de negócio, não de linhas de código. Essa é a unidade de medida e complexidade que você está procurando.
Um microservice não conversa com um Enterprise Bus. É um padrão que se fez popular há um tempo. Basicamente, consiste em criar uma fila de mensagens centralizada num middleware (o bus) no que as aplicações escrevem petições. Essas petições (mensagens) são analisadas e a fila decide os destinatários das mesmas e se responsabiliza da entrega segundo um sistema de subscrições, possivelmente transformando o formato pelo caminho e retentando se a primeira tentativa fracassa. Sobre o papel, isso aporta gerenciamento ao sistema (você tem uma pista central onde aplicar os controles), mas na prática o time responsável de faze-la evoluir vira um gargalo que atrapalha o resto e a complexidade do sistema acaba sendo intratável.
Dispor de um único esquema de banco de dados também não aporta tanto valor
Um microservice NÃO escreve num banco de dados centralizado. Na verdade, na maior parte dos casos, tem o seu próprio mecanismo de persistência. Outro componente quer acessar os dados do serviço? Então pergunta pra ele, não para o banco! E sim, isso acrescenta um certo grau de complexidade ao sistema pois a consistência global do estado (a informação guardada pelo seu produto) é eventual. Mas assuma isso: nem sempre pode ter o que você quer, as vezes simplesmente obtém o que precisa. E o que precisa e disponibilidade e resiliência ao particionamento e um esquema que possa evolucionar de forma ágil. Além disso, no fim das contas, quando você for fazer data warehousing iria transformar as tabelas de todas formas, assim que dispor de um único esquema de banco de dados também não aporta tanto valor.
Um microservice NÃO usa Data Transfer Objects nem Value Objects para comunicar informação entre as camadas lógicas que implementam-o. Ou seja, o objeto sobre o que aplica as regras de negócio é o mesmo objeto que finalmente é persistido e provavelmente também seja o mesmo que usa para retornar a resposta quando perguntem por ele, usando decorators e annotations para decidir o que se transfere para outras camadas físicas da aplicação e o que caia na memória. E falando nisso, se a complexidade do serviço não necessite, também não empolgue demais com o número de camadas do mesmo.
Um microservice NÃO se comunica com outros por referências remotas à objetos, faz por documentos. Nada de RMI, nada de CORBA, nada que adicione acoplamento entre as tecnologias usadas entre eles e aumente a complexidade. Só old good documents.
Um microservice NÃO usa SOAP, porque ninguém gozando de plenas faculdades mentais usaria algo tão complicado para solucionar um problema já difícil por si só, como interconectar sistema. REST é muito mais prático e semanticamente rico. E isso não significa que deva eliminar o XML mas provavelmente será mais feliz com alternativas como JSON ou Protobuffers. Ou jpeg, se a tarefa precisar. Idealmente, deixe que o consumidor escolha o formato preferido. Mas não SOAP.
Um microservice NÃO faz o trabalho todo de forma assíncrona. Se um componente precisa contatar com outros três para completar a tarefa, todas as requisições são iniciadas em paralelo e posteriormente o resultado é sincronizado. Ao contrário impõe uma serialização da latência totalmente inaceitável. E calma, nos dias de hoje (com promises, futures, async/await. reactive e similares) a programação assíncrona é simples. Verá, dedicaremos um tempo pra brincar com ela.
Um microservice NÃO espera ninguém para passar para produção. Se o teu processo fala que as novas versões dos componentes que implementam o teu produto entram as terças-feiras após do almoço é que não está fazendo microservice. Uma parte da brincadeira é acelerar o ciclo de desenvolvimento.
Um microservice NÃO muda o contrato gerando incompatibilidades. Pode aceitar informação adicional das requisições e responder com mais dados, mas deve continuar compatível com os outros componentes que já o usem.
Um microservice NÃO leva a configuração embutida como parte do código. É injetada desde fora e existem múltiplas formas de fazer, mas um arquivo xml numa pasta do projeto não é uma delas porque para começar faz que seja necessária uma recompilação para substituir a configuração usada durante o desenvolvimento quando passa para produção e assim o artefato sobre o que você faz os testes não é o mesmo que você tem em produção. Leia essa última frase outra vez até que fique completamente clara.
Os deuses do Tomcat vão te amaldiçoar duplicando as entradas do log.
Um microservice NÃO compartilha processos com outros. Se está deployando vinte aplicações dentro do seu Websphere isso não é microservice: não vai poder escalar independentemente dos outros 19 componentes, vai concorrer com os outros para os demais recursos, vai trombar com incompatibilidades entre bibliotecas que usa, etc. E os deuses do Tomcat vão te amaldiçoar duplicando as entradas do log.
Um microservice NÃO obriga a galera de operações a copiar vários arquivos para iniciá-lo. Se gera mais de um arquivo, usa a estratégia que prefira para agrupá-los de forma atômica: zip, war, jar, deb, msi, imagem docker ou que achar melhor. Mas só um artefato por componente.
Um microservice NÃO se entrega em produção na mão. Nunca. Pra nada. Porque quando são as três da madruga você não quer acordar para ter que restartar sua aplicação. E porque se temos que aplicar um hotfix de emergência enquanto o escritório está pegando fogo e o CEO ameaça em transferir o departamento para Sibéria, nós humanos temos tendência a ficar nevosos e errar. As automações (bem feitas) não falham. Mas que foi? não somos devops?
Um microservice NÃO é incompressível para um humano. Se no time que mantém o seu software há uma pessoa que não seja capaz de entender as diferentes responsabilidades dos arquivos que formam o código, é que o seu componente é complexo demais para ser considerado um microservice. Não significa que todos devam ser iguais de competentes lidando com Hibernate ou com CSS, mas todos deveriam ter a capacidade de identificar onde estão os arquivos relacionados, compreender seus roles e aplicar alterações simples. E sobre tudo, todos os membros do time deveriam ter a capacidade de entender os aspectos de negócio que implementa o componente.
Um microservice NÃO se apoia num framework corporativo de camada de negócio. Se um do seus componentes usam a mesma biblioteca que inclui um cara para descrever o conceito de Cliente, isso não é um microservice. Porque no fundo, não todo o seu produto tem a mesma visão de um cliente e porque no time responsável de manter esse framework tem outro gargalo.
Um microservice NÃO se cria a partir de um processo Waterfall. Sério, o que você quer conseguir não é tão complexo: não precisa dedicar varias semanas para planificar perfeitamente como vai implementar essa perfeita toma de requisitos. Se o que queremos é aportar valor o mais rápido possível, antes devemos manter a qualidade principalmente mas também deve abraçar um cultura de agilidade.
Um microservice NÃO deixa que outro fale pra ele quem é. É ele que sabe e por isso se registra ele mesmo nas páginas amarelas que escolher: DNS, Eureka, MarathonLB ou o veneno que decida usar.
Se você não implementou mecanismos para dar alta disponibilidade ao seu componente, não é um microservice.
Um microservice NÃO morre do nada quando a máquina onde roda tem um problema. Se você não implementou mecanismos para dar alta disponibilidade ao seu componente (IP virtual flutuante, placa de rede flutuante, load balance, o que precisar), não é um microservice.
Um microservice NÃO sofre no silencio. Se o seu componente não é capaz de emitir métricas, logs, KPIs e companhia isso não um microservice. Vai ter um incremento da complexidade para operar nesses cenários porque simplesmente tem mais peças, então melhor facilita a vida de quem tenha que monitorar o sistema. Porque eles sabem onde você mora e são bravos.
O que é um microservice
Ufa, são já mais de 1500 palavras. E também não é tão interessante o que me falta pra te contar. Então conversaremos em outro momento. Mas repasse os pontos anteriores para saber se está fazendo microservice. E lembre-se: É possível que isso seja o que realmente precisa. Não esqueça de aplicar sempre pensamento crítico e porque todos estejam te dizendo que deve ir numa direção, no final é você quem tem que decidir se é a direção que te leva onde você quer chegar.
Javi Moreno
@ciberado
Artigo original