Conselhos para quem quer empreender full-time

Palestrando no TDC 2016
Palestrando no TDC 2016

Esse post é focado em organizar em um só lugar algumas dicas de minha autoria para quem quer empreender full-time. Basicamente parte das minhas experiências pessoais com alguns toques do que eu faria de diferente hoje. Saí do meu emprego em 2012 para empreender e durante três anos toquei meu próprio negócio até que decidi voltar ao mercado de trabalho pois minha startup, apesar de ter faturamento, não decolou. Apesar disso, consegui viver bem durante este tempo, sem luxos ou firulas, mas bem, sem dívida alguma, sem precisar vender carro, etc.

Vou falar nesse post sobre:

  1. Planejamento
  2. Validação
  3. Migração
  4. Organização

Qualquer dúvida ou sugestão que tiver, deixe nos comentários no final do post!

Passo 1: Planejamento

Antes de sair xingando o chefe e dando tchau pra galera, pare e pense o motivo pelo qual está querendo empreender. Empreender é dureza e você nunca está 100% preparado psicologicamente para não ter seu salário caindo na conta todo dia 5. Você já sabe em qual área vai empreender? O quanto pretende faturar? Onde será seu escritório?

Um bom planejamento envolve:

  1. ter economias no banco que você possa queimar enquanto seu negócio não dá certo;
  2. encerrar suas atividades na empresa atual dignamente, pois você pode precisar voltar para lá ou ter referências deles algum dia;
  3. reduzir todos os custos supérfluos que podem existir no seu orçamento doméstico, pois a grana vai encurtar;
  4. conversar com sua família da sua ideia de empreender, pois você vai precisar de apoio moral e provavelmente financeiro;
  5. conseguir um mentor mais experiente ou um sócio para te ajudar no negócio, pois você vai ter muitas dúvidas e é sempre bom ter alguém pra conversar sobre elas ou até pra dividir a carga da responsabilidade de ter uma empresa;
  6. botar todas tudo no Excel pra manter o controle;

O que eu faria diferente? Na época minha esposa também estava empreendendo. Dois empreendedores em casa é algo um tanto problemático financeiramente. O ideal é que se você é casado e quer empreender, converse com sua esposa para que ela continue com um emprego fixo, só por precaução.

Além disso, eu deveria ter me planejado com mais antecedência. Lancei minha startup em julho e saí da empresa em setembro. Só que alguns meses antes de lançar minha startup eu troquei de carro, o que me gerou uma conta pesada que não era realmente necessária.

Passo 2: Validação

Não largue tudo para depois descobrir se a sua ideia tem potencial. Crie um MVP dela primeiro e só depois dele estar provado pense em largar seu emprego. Criar MVPs como side projects do seu emprego atual é uma ótima oportunidade de aprender mais e dependendo do quão avançado você conseguir, até gerar uma renda extra durante o processo, como um lifestyle business.

A regra é clara: só saia do seu emprego fixo se o seu empreendimento estiver gerando grana. Eu mesmo segui essa regra, embora se fosse fazer isso de novo hoje, sairia quando ele estivesse gerando grana suficiente para pagar todas minhas contas, o que não foi o caso na época.

Uma boa validação envolve (praticamente o ciclo do Lean Startup aqui):

  1. criar um MVP;
  2. tentar vender o seu MVP e conseguir 5 vendas;
  3. se não der certo, melhore seu MVP até conseguir as 5 vendas;
  4. continue tentando vender enquanto os primeiros compradores usam ele e lhe dão feedback de como melhorá-lo;
  5. implemente as melhorias sugeridas e continue trabalhando com as vendas até que você ganhe o suficiente para pagar as suas contas ou até que isso comece a trabalhar o seu emprego atual. Em ambos os casos, ou você terá de sair do emprego ou encerrar seu projeto de empreender.

O que eu faria diferente? Só sairia do meu emprego após o meu MVP estivesse faturando no mínimo o que eu precisar para pagar todas minhas contas fixas mensais. Além disso, escolheria melhor as minhas métricas de sucesso, uma vez que eu perdia muito tempo com métricas de vaidade.

Passo 3: Migração

Se você conseguiu fazer seu MVP lhe gerar tanta grana que pague todas as suas contas, ótimo, mas não foi assim comigo. Eu passei por um processo em que fui me desvencilhando aos poucos do “chapéu” de empregado e assumindo o de empreendedor. Basicamente mesmo após cortar todos os meus custos fixos e variáveis supérfluos, o que reduziu meu orçamento doméstico mensal de R$2.700 para R$1.800, eu não faturava R$1.800 com meu MVP e tinha de completar essa renda de alguma forma, a menos que eu me desfizesse do meu carro, que custava R$690 de prestação à época. Mas eu não queria. 🙂

Algumas coisas foram fáceis de cortar como Netflix, celular pós-pago para pré-pago, shopping todo final de semana. Outras foram mais difíceis com o curso e Inglês, que eu tive de fazer permuta com o dono da escola para pagar o curso com freelas de desenvolvimento pra ele. Além disso, fiz muitos apps mobile.

Eu fiz migração de empregado para empreendedor da seguinte forma:

  1. primeiro, saí do meu emprego atual que era de 8h/dia;
  2. peguei um contrato PJ (eu abri um CNPJ na época) de 4h/dia durante 6 meses em uma empresa de um amigo meu. Nas demais 4h eu trabalhava na minha empresa;
  3. depois dos 6 meses de contrato, passei a pegar freelas em que trabalhava 2h por dia neles e as demais 6h em minha empresa (como apps Android);
  4. depois de mais uns 6 meses consegui investimento para minha startup e passei a me dedicar 8h por dia à ela, podendo trazer inclusive meus sócios para vir trabalhar full-time comigo pois tinha grana em caixa pra isso;

Obviamente falar que eu trabalhei apenas 8h por dia em meu negócio é mentira, eu trabalhava no mínimo umas 12h por dia. Só nos finais de semana que eu costumava trabalhar menos, aí sim, provavelmente umas 8h.

O que eu faria diferente? Meus sócios só saíram de seus empregos depois que não havia mais risco. Isso não foi certo, pois eles estavam agindo como empregados. Exija tanto comprometimento de seus sócios quanto você está comprometido.

Outra coisa que eu faria diferente é trabalhar à noite em um serviço para queimar menos grana da empresa. Eu comecei a fazer isso depois de um ano empreendendo, trabalhando como professor em uma faculdade após o expediente na minha empresa. Com isso minha grana aumentou e diminuiu bastante minhas preocupações com as contas.

Passo 4: Organização

Trabalhar por conta própria é ser livre. E ser livre é muita responsabilidade, afinal, ninguém vai te dizer o que precisa ser feito e muito menos vai te pagar todo mês por apenas “estar trabalhando”. Ou você descobre o que precisa ser feito, o que é mais importante, ou seu negócio não gera grana e você vai quebrar logo, logo.

Se organizar é uma etapa fundamental do processo de ser um empreendedor. Você precisa ter muita disciplina e muitas vezes terá de fazer coisas que não gosta para que sua empresa dê certo, simplesmente porque elas são importantes para o crescimento do negócio. Se não definir prioridades bem claras e não executar todas as tarefas importantes, não tem milagre, você vai quebrar.

Uma maneira de organizar o seu dia-a-dia como empreendedor é:

  1. comece seu dia definindo as prioridades para o mesmo. Liste as coisas que devem ser feitas em uma planilha e coloque a prioridade de cada uma. Para definir a prioridade, pense a respeito de quanta receita aquela tarefa irá gerar ou economizar. Para ajustar a prioridade, pense no quão urgente é essa tarefa, se algo é urgente e vai gerar grana, deve ser mais prioritário de algo que apenas gera grana.
  2. pegue duas tarefas do topo da lista, que são mais prioritárias e urgentes que todas. Execute essas duas tarefas logo na manhã, isso garante que seu dia foi produtivo.
  3. no decorrer do dia, execute as demais tarefas da lista não necessariamente na ordem de prioridade, mas conforme o seu bom senso, apenas priorizando emergências que possam aparecer.

Pode soar um pouco estranho, mas é isso mesmo. Aprendi com um coach essa técnica muito simples há muito tempo atrás, e nesse meu post sobre produtividade tem mais algumas dicas adicionais.

O que eu faria diferente? Me organizaria dessa maneira desde o primeiro dia. Demorei um bom tempo até aprender que não dá pra fazer tudo que você precisa fazer em um dia só e que se você não botar regras e limites para o quanto é saudável trabalhar na empresa, você enlouquece. Eu perdi vários kgs no primeiro ano de empresa até organizar meu trabalho, pois não tinha tempo nem de me alimentar.

O que achou das dicas? Tem algo a acrescentar? Deixe aí nos comentários!

Microservices vs SOA: entenda as diferenças

Palestra na FAPA
Palestra na FAPA

SOA ou Arquitetura Orientada a Serviços, na tradução literal, é um padrão que já existe tem algum tempo, usado principalmente por grandes corporações. Mais recentemente o mercado voltou a falar de outra arquitetura igualmente distribuída: microservices. Também não há nada de exatamente inovador em microservices, que estão aí desde a década de 60, mas que recentemente voltou a ganhar força como padrão a ser adotado em diversos sistemas, principalmente aqueles que usam de persistência poliglota. Então porque eu venho escrever hoje sobra microservices vs SOA?

Durante meus estudos recentes sobre micro serviços me deparei com a seguinte pergunta: qual a diferença entre microservices e SOA? Não estaríamos todos falando mais do mesmo? Não vou entrar no mérito de CORBA, uma vez que este é um conceito mais consolidado e que acredito tenha caído em desuso na última década, principalmente a versão “Microsoftniana” DCOM/COM+.

Para entender melhor as diferenças, vamos relembrar alguns conceitos importantes e esclarecer algumas coisas.

O que é SOA?

Uma arquitetura orientada à serviços não é algo exatamente difícil de entender quando você lê sua definição na Wikipedia: “funcionalidades implementadas pelas aplicações devem ser disponibilizadas através de serviços”. Esses serviços podem ser consumidos por outros serviços para que o todo forme um sistema complexo. É o clássico “dividir para conquistar”. No entanto, SOA não é tão simples assim, e foi nós desenvolvedores que o tornamos complicado demais.

Para algumas empresas, usar SOA é apenas expor software através de webservices. Dentro dessa concepção, há grupos mais conservadores que acreditam que isso inclui apenas os vários padrões WS-* e outros mais liberais que aceitam qualquer tipo de dado sobre HTTP (não necessariamente apenas XML). O que você acha, isso é SOA?

Para outras empresas, SOA implica em uma arquitetura em que não há UMA aplicação única que consome alguns serviços, mas sim que TUDO são serviços que fornecem desde dados a regras de negócio e que são agregados através de uma UI que consome todos eles. O que você acha, isso é SOA?

Não obstante, outras empresas acreditam que SOA é um jeito de permitir que diferentes sistemas se comuniquem através uma estrutura padrão com outras aplicações, assim como CORBA, mas usando XML. Isso geralmente inclui um barramento central de comunicação e dados que todos serviços usam para se organizar e centralizar a informação. Não necessariamente sobre HTTP, inclusive. O que você acha, isso é SOA?

Muitas empresas e desenvolvedores dizem coisas diferentes a respeito do que é SOA. Dizem que serve para separar dados de processos, dizem que é bom para combinar dados e processos, dizem que deve usar web standards, dizem que é independente de web standards, que síncrono, que é assíncrono, que sincronicidade não importa…muitas coisas diferentes e conflitantes!

Isto não é um problema exclusivo de SOA, temos esse mesmo problema de definição entre as diferentes tribos que usam POO. Você deve conhecer as velhas discussões sobre classes apenas com atributos ou apenas com métodos, serem ou não orientadas à objetos, só para citar um exemplo.

E os microservices?

Quando estamos construindo arquitetura de software focadas na comunicação entre diferentes serviços é comum acabarmos colocando muita responsabilidade e inteligência no mecanismo de comunicação propriamente dito. Um bom exemplo disso é o Enterprise Service Bus (ESB ou Barramento de Serviço Corporativo). Esse tipo de “produto” geralmente inclui recursos sofisticados como roteamento de mensagens, coreografia, transformação e aplicação de regras de negócio. E olha que ele deveria ser apenas um barramento de comunicação…

Mas e os microservices? O que eles propõem de diferente que valha a pena entender?

Microservices focam em endpoints inteligentes (os serviços) e canais de comunicação burros (protocolos simples, como REST). Aplicações construídas a partir de microservices possuem o objetivo (e a regra) de serem tão desacopladas e coesas quanto for possível. A “coreografia” entre elas se dá através de simples protocolos como REST ao invés de protocolos complicados como WS-Choreography ou BPEL ou ainda sendo orquestrado por uma ferramenta para isso.

Times trabalhando com microservices usam princípios e protocolos que a própria web usa, simplificando muito a curva de aprendizado e a arquitetura como um todo. Mesmo que se queira (ou se necessite) de um barramento de comunicação, ao invés de se adotar um ESB, usam-se barramentos leves de mensageria como RabbitMQ ou ZeroMQ, servindo apenas como filas confiáveis assíncronas para não se perder mensagens. Toda a inteligência fica no serviço, não no barramento.

O grande desafio dos times que querem trocar de padrão de arquitetura: monolítica para microservices é que o “normal” na indústria é que os componentes se comuniquem através de invocação de métodos ou chamadas de funções e é mudar esse padrão de comunicação que mora o grande desafio.

Microservices vs SOA

Não seriam os microservices a mesma coisa que SOA, mas algumas décadas atrás quando o padrão nasceu? Inclusive algumas empresas que dizem usar SOA programam-na da mesma forma que hoje chamamos de microservices e isso não é ruim. O grande problema de usar o termo SOA é o que mencionei no início desse artigo, onde SOA significa muitas coisas diferentes e até contraditórias para diferentes pessoas. Via de regra, geralmente o que se vê é SOA sendo usado para integrar diferentes aplicações monolíticas através de um ESB. Pronto, falei.

Sem julgamentos aqui, mas não dá pra comparar isso com microservices, principalmente considerando a complexidade do canal de comunicação. E não julgo principalmente porque quem advoga das melhores práticas de microservices são pessoas que trabalharam muitos anos em empresas com sistemas SOA e sabem do que estão falando, principalmente sobre a complexidade que isso se tornou.

Sendo assim, dizer que você usa microservices não é o mesmo que dizer que você usa SOA e vice-versa, para a maioria das pessoas. Sinceramente não me importo com o rótulo, e considerando a definição mais abstrata e geral de SOA, eu afirmaria que microservices é uma forma de SOA. Outros mais extremistas diriam que microservices é SOA feita do jeito certo, mas não sou tão arrogante assim.

Governança descentralizada

Tanto em microservices quanto em SOA temos algum nível de governança dos serviços. No entanto, em SOA, ela é mais centralizada.

Uma das consequências de governança centralizada é a tendência a se criar padrões em torno de uma única plataforma de tecnologia. A experiência mostra que esta abordagem é restritiva em demasia, uma vez que “nem todo problema é um prego e nem toda solução é um martelo”, como diria o ditado. Grandes empresas como ThoughtWorks acreditam que devemos sempre utilizar a ferramenta certa para cada trabalho, mas os grandes problemas são:

  • que as aplicações monolíticas não nos dão toda a liberdade que queremos para fazer isso;
  • e que o SOA tem padrões demais a serem seguidos, o que acaba engessando os serviços;

Ao quebrar os componentes de uma aplicação monolítica em serviços nós permitimos que cada um deles seja implementado em tecnologias diferentes e use persistências diferentes e talvez essa seja o maior atrativo de microservices. Claro, não é porque podemos fazer um sistema cheio de serviços poliglotas que você deve fazê-lo, mas você tem essa opção, quando necessário.

Times trabalhando com microservices preferem uma abordagem diferente para padrões: ao invés de definir um documento com padrões (como no caso do SOA), eles descobrem uma maneira de resolver um problema e o transformam em um componente ou serviço, que pode inclusive ser compartilhado com o mundo, como o rápido crescimento do repositório do NPM pode confirmar. Esta colaboração cria padrões emergentes como o uso de determinado ORM ou framework web, por exemplo. Com a transformação do Git em padrão de facto para controle de versão, práticas open-source tem se tornado mais e mais comuns nas empresas.

O Netflix é um bom exemplo de organização que segue esta filosofia (e que o faz com Node.js). Compartilhando componentes úteis e testados na “linha de frente” eles encorajam outros desenvolvedores a usarem os mesmos padrões ao mesmo tempo em que deixam a porta aberta para outras possibilidades.

O mindset de microservices não aceita overheads, como por exemplo, os contratos de serviço exigidos no SOA. Padrões como Tolerant ReaderConsumer-Driven Contracts são comuns de serem aplicados a microservices e muitas ferramentas foram criadas para automatizar o processo de testes dos serviços para se certificar que tudo está funcionando mesmo sem contratos – uma abordagem elegante para resolver o dilema YAGNI.

Talvez o apogeu da governança descentralizada seja o éto popularizado pela Amazon de “você cria, você mantém” (tradução livre de “you build it/you run it”). Os times são responsáveis por todos os aspectos do software que eles constroem incluindo mantê-lo no ar 24/7. Este nível de responsabilidade é definitivamente a norma que mais e mais empresas estão aplicando sobre seus times como o Netflix tem feito também. Afinal, nada pode ser mais motivador para fazer você focar na qualidade do projeto do que ser acordado às 03h da manhã por causa de bugs em produção, certo?

Gerenciamento descentralizado de dados

Novamente, é muito comum vermos implementações de SOA onde temos uma única base de dados centralizadora de tudo. Uma grande premissa é a de que todos os dados são da mesma empresa, logo são os mesmos em todos serviços. No entanto, isso não é 100% verdade.

A descentralização do gerenciamento de dados apresenta-se de diferentes maneiras e, em um nível mais abstrato, significa que o modelo conceitual de mundo é diferente entre os sistemas, logo não há porque juntá-los em um único banco. Quer um exemplo? Os dados de um cliente que um vendedor precisa saber são completamente diferentes do que alguém do suporte precisa enxergar, além disso, até mesmo o nome ‘cliente’ não faz sentido ser o mesmo em ambas visões do sistema.

Este problema é comum entre aplicações diferentes mas pode ocorrer mesmo dentro de uma única aplicação, principalmente quando ela é dividida em componentes separados. Um jeito útil de se pensar sobre isso é a noção de Bounded Context do DDD, que eu não vou entrar em detalhes aqui.

Assim como pensar sobre os modelos conceituais de dados nos leva a pensar que eles deveriam ser separados, usar microservices reforça, e muito, esse mindset. Enquanto aplicações monolíticas preferem bases únicas e centralizadoras por padrão, microservices preferem deixar que cada serviço escolha a melhor maneira de persistir os seus dados, seja com a mesma base de dados, a mesma tecnologia mas bases diferentes ou tecnologias completamente diferentes. Claro, você pode usar persistência poliglota em aplicações monolíticas (Abstract Factory está aí para isso), mas ela é mais comum em projetos com microservices.

A descentralização da responsabilidade pelos dados através dos micro serviços tem seus reveses, como gerenciar atualizações. A abordagem mais comum é criar transações, assim como em aplicações monolíticas, embora isso gere uma complexidade significativamente.

Bom, o meu intuito nunca foi dizer como você deve programar suas aplicações, se com SOA ou com microservices, mas espero ter jogado alguma luz ao assunto e ajudá-lo a entender as diferenças.

Concorda? Discorda? Deixe nos comentários!

Até a próxima.

Referências: muitas referências foram retiradas do site oficial do Martin Fowler, o meu guru de programação favorito. Inclusive a única imagem do artigo é do site dele.

Introdução à Arquitetura de Micro Serviços

Workshop IFRS
Workshop IFRS

Tem uns 2 anos que passei a ouvir falar de micro serviços (microservices) mas faz poucos meses que passei a me interessar realmente pelo tema, uma vez que comecei a estudar Node.js para uso em meus projetos.

Micro serviços é uma maneira particular de desenvolver aplicações de maneira que cada módulo do software é um serviço standalone cujo deploy e escala acontecem de maneira independentes da “aplicação principal” (não confundir com SOA). Enquanto na arquitetura tradicional de software, chamada monolítica, quebramos uma grande aplicação em bibliotecas, cujos objetos são utilizados in-process, em uma aplicação modular como proposta na arquitetura de microservices cada módulo recebe requisições, as processa e devolve ao seu requerente o resultado, geralmente via HTTP.

A ideia não é exatamente nova, é usada em ambientes Unix desde a década de 60, mas recentemente se tornou o epicentro de uma grande revolução na forma como as empresas estão desenvolvendo software ágil baseado em equipes enxutas responsáveis por componentes auto-suficientes.

Neste post irei abordar os conceitos, detalhes, vantagens, desvantagens e principais dúvidas dessa arquitetura, bem como porque ela está sendo tão utilizada atualmente e como começar a organizar suas aplicações orientadas dessa maneira.

Veremos neste artigo:

A motivação por trás dos micro serviços

Muitas são as buzzwords do mundo de desenvolvimento de software e esta me pareceu mais uma quando a ouvi pela primeira vez. Apesar do seu nome ser auto-explicativo, é interessante estudarmos os reais impactos que uma arquitetura composta por diferentes módulos conversando via um canal lightweight como HTTP pode causar na forma como programamos e nos resultados que obtemos com software.

Resumidamente, o estilo de arquitetura em microservices é uma abordagem de desenvolver uma única aplicação como uma suíte de pequenos serviços, cada um rodando o seu próprio processo e se comunicando através de protocolos leves, geralmente com APIs HTTP. Estes serviços são construídos em torno de necessidades de negócio e são implantados de maneira independente geralmente através de deploy automatizado (pelo menos em um cenário ideal deveria ser assim). Existe um gerenciamento centralizado mínimo destes serviços e cada um deles pode ser escrito em uma linguagem diferente e utilizando persistências de dados diferentes também.

Para entender melhor a motivação por trás de microservices vale relembrar como os projetos são programados hoje, geralmente em três grandes partes: um client-side com a interface do usuário, uma base de dados com as informações do sistema, e uma camada server-side com a lógica da aplicação. A camada server-side lida com as requisições do usuário, executa a lógica de negócio, retornar e atualiza dados da base e disponibiliza informações prontas para o client-side exibir. Isto é um monólito ou aplicação monolítica, uma vez que gera uma única e grande aplicação com tudo junto. Qualquer mudança no sistema envolve em compilar tudo novamente e implantar uma nova versão do server-side inteiro no servidor.

Toda a aplicação roda em um único processo, usando uma única linguagem server-side e geralmente uma única tecnologia de persistência de dados. Para escalar esse tipo de aplicação você pode adicionar mais recursos no mesmo servidor (escala vertical) ou fazer cópias desse servidor e colocá-las atrás de um load balancer (escala horizontal).

Aplicações monolíticas não são ruins e podem ser muitíssimo bem sucedidas. No entanto, cada vez mais equipes estão frustradas com suas limitações, principalmente quando estão implantando projetos na nuvem. Nestes cenários, os ciclos de mudanças, geralmente rápidos e pontuais como os propostos no Lean Startup, acabam afetando toda a aplicação pois o deploy é monolítico, assim como a aplicação. A escala horizontal requer um custo alto, pois sempre deve ser duplicada a aplicação inteira, e não apenas a parte que necessita de mais desempenho.

Vale lembrar também que aplicações monolíticas exigem que todo o codebase server-side seja escrito na mesma linguagem de programação, o que impede que você tire o máximo proveito de cada cenário usando a ferramenta mais apropriada à ele. Também impede que cada time desenvolva com a maior velocidade possível uma vez que a base de código é a mesma entre todos times.

Estas frustrações levam à arquitetura microservices de construir aplicações como um conjunto de serviços. Como os serviços são implantados de maneira independente, a escala se dá individualmente, tanto na vertical quanto na horizontal, para os serviços que estão precisando de mais desempenho. Usando protocolos comuns e contratos (interfaces) bem definidos, você consegue usar linguagens de programação diferentes de cada serviço, bem como mecanismos de persistência auxiliares que possam ser necessários para cada um deles, como mecanismos de cache, filas, índices, etc.

Para finalizar esta seção, a imagem abaixo do blog do Martin Fowler ilustra bem a diferença da escala entre as duas arquiteturas: monolítica e de micro serviços:

Vantagens e desvantagens de microservices

Não existe uma definição formal de como uma aplicação baseada em micro serviços deve ser construída, mas depois de muito ler a respeito e estudar o assunto notam-se algumas particuliaridades frequentes que podemos denominar como um padrão comum para microservices.

Sempre existiu o desejo dentro da indústria de software de construir programas apenas plugando componentes. Os primeiros esforços neste sentido foram as bibliotecas de funções, mais tarde as bibliotecas de classes e atualmente está em voga os serviços. Note que a componentização sempre existiu, mas o que propõe-se com microservices é que cada componente seja uma aplicação separada e especializada em apenas uma parte da aplicação “completa”. A principal razão por trás dessa escolha, de serviços ao invés de bibliotecas, é que serviços podem ser implantados de maneira separada. Você já tentou atualizar seu software apenas subindo para produção uma DLL ao invés de todas (ou ao menos todas as suas)? É um risco que não vale a pena correr, pois o acoplamento entre as DLLs é muito alto e o ideal é sempre a recompilação do sistema como um todo.

Claro, existe uma desvantagem clara no uso de serviços ao invés de bibliotecas: performance. Bibliotecas rodam no mesmo processo da aplicação, usam memória compartilhada, etc. Serviços dependem de canais de comunicação, como HTTP, para conseguirem tratar e responder as requisições. Exigem também uma coordenação entre os contratos de serviço para que os consumidores consigam “conversar” com os serviço da maneira que eles esperam, bem como receber as respostas que estão preparados.

Esse problema é especialmente preocupante conforme você tenha muitas chamadas síncronas entre seus serviços, pois o tempo de espera total para seu sistema responder será igual à soma de todos os tempos de espera das chamadas síncronas. Neste momento você tem duas opções: mudar para uma abordagem assíncrona ou reduzir o máximo que puder o tempo de espera (e a quantidade) das requisições síncronas. Node.js é uma tecnologia que tenho estudado bastante recentemente e trabalha muito forte com o conceito de chamada assíncronas, muito usado pelo Netflix para não bloquear a experiência do usuário. No entanto, quando isso não é possível, como foi o caso do site do jornal The Guardian, tente limitar o número de chamadas síncronas que você vai precisar, o que no caso deles é a regra de apenas uma chamada síncrona por requisição do usuário.

Apesar desses problemas citados, os benefícios parecem superar os downsides dessa abordagem, pois cada vez mais empresas estão adotando-na.

O que você deve ter em mente

Os serviços irão falhar. Talvez não todos juntos, talvez não rapidamente, mas vaia acontecer. Sendo assim, você deve estar sempre preparado para a falha de um ou mais serviços.

Essa é uma consequência de usar serviços como componentes e sua aplicação deve ser projetada de maneira que possa tolerar a falha de serviços. Qualquer chamado a um serviço pode falhar devido à indisponibilidade de um fornecedor e você tem de saber lidar com isso de maneira amigável com o restante do sistema. Esta talvez seja a maior desvantagem dessa arquitetura se comparada ao jeito monolítico tradicional, uma vez que adiciona uma complexidade adicional significativa. Times que trabalham com micro serviços devem constantemente refletir como a falha de cada serviço afetará a experiência do usuário. No Netflix por exemplo, partes da bateria de testes diária deles inclui derrubar servidores e até datacenters para ver como a aplicação se comporta nestas situações.

Uma aplicação em micro serviços deve ser monitorada em um nível muito superior ao de uma aplicação monolítica tradicional, uma vez que os serviços podem falhar a qualquer momento e se possível, restaurar o funcionamento completo automaticamente. Monitoramento em tempo real deve ser enfático no processo de desenvolvimento, implantação e operação dos serviços. Não que você não tenha de ter esse mesmo cuidado com aplicações monolíticas, mas apenas que com micro serviços isso não é uma opção.

O quão grande é/deve ser um micro serviço?

Uma pergunta bem comum e que cai como uma luva para o próprio nome da “arquitetura’ é: o quão grande deve ser um micro serviço?

Infelizmente o nome micro serviço nos leva a perder tempo demais pensando no que exatamente micro quer dizer. Diversas empresas, de Amazon a Netflix, usam micro serviços de variados tamanhos e não há um consenso sobre eles. Especificamente na Amazon, considerando que cada micro serviço é (e deve) ser tratado como um produto separado e tem seu próprio time (squad, na verdade), eles usam a regra Two Pizza Team: se o time precisa de mais de duas pizzas por refeição para se manter alimentado é porque está grande demais, o que significa não mais de que 12 pessoas. No outro extremo, os menores times recomendados pela Amazon possuem 6 pessoas, o que eu pessoalmente, em minhas experiências como Scrum Master, acredite ser o ideal (você ainda pode chamar meus times de Two Pizza Team considerando que todo mundo gosta de comer vários pedaços de pizza!).

Resumindo, embora não exista uma regra, podemos assumir que se você precisa de uma equipe de mais de 12 pessoas para desenvolver e manter um serviço (considerando tudo: programação, infra, testes, etc), ele está grande demais e você deveria quebrá-lo em serviços menores.

Como começar com micro serviços?

Projetos usando micro serviços geralmente não nascem assim do dia para a noite. O que nota-se na maioria das implementações bem sucedidas é que elas vieram de um design evolucionários, vendo a decomposição em serviços como uma ferramenta que vai aos poucos ajudando a quebrar uma aplicação monolítica que está com problemas de escala, qualidade, etc em diversos componentes menores.

Neste cenário, o maior desafio é saber como que o monólito irá ser quebrado em serviços. O quê deve ser agrupado em conjunto? O que deve estar separado? Quais bases de dados serão usadas por quais serviços?

Um dos princípios-chave por trás dessas decisões é o de deploy e escala independentes entre os serviços. Se dois serviços sempre tem de ser colocados em produção em conjunto, eles deveriam ser um serviço só. Agora se eu tenho um serviço cujas publicações acontecem sempre por causa de alterações pequenas em um dos seus módulos internos, esse módulo interno deveria ser transformado em um serviço per se.

O site do jornal britânico The Guardian é um bom exemplo de aplicação que foi projetada e construída como um monólito e que vem evoluindo na direção de micro serviços. O monólito ainda é o core do site, mas eles têm adicionado novas funcionalidades usando micro serviços que consomem a API do site principal. Esta abordagem é particularmente interessante pra eles principalmente nos casos de módulos temporários, como um hotsite para cobrir um evento esportivo.  Estes hotsites podem ser programados rapidamente na linguagem que for mais conveniente e jogados fora uma vez que não fazem mais sentido.

E aí, motivado para trabalhar com essa abordagem? Vamos trocar experiências nos comentários!