O termo micro serviço tem me ocupado nos últimos meses. Vejo a Pivotal dando ênfase a este estilo arquitetural no lançamento do Spring 4, uma apresentação interessante de James Lewis a respeito e que mais tarde, junto com Martin Fowler irá escrever um maravilhoso artigo a respeito e até mesmo textos tolos como este. Após ter lido tantas fontes há momentos em que me sinto como Santo Agostinho ao ser questionado sobre o tempo:
“O que é, por conseguinte, o tempo? Se ninguém me perguntar, eu sei; se o quiser explicar a quem me fizer a pergunta, já não sei.” (Livro XI das Confissões de Santo Agostinho)
É interessante como na maior parte das fontes que citei o texto se inicia com algo do tipo “ainda não há uma decisão precisa do termo” (Fowler). Como verão neste post minha dúvida primária ainda se mantém: é de fato algo novo ou apenas um daqueles momentos nos quais a indústria renomeia algo que já conhecíamos e usávamos há anos apenas para nos vender alguma coisa?
Meu entendimento sobre a coisa
Resumindo: mais uma solução para o problema do alto acoplamento em aplicações corporativas. A diferença é que desta vez estamos atacando aplicações monolíticas. Bom: então primeiro é interessante pensarmos no que vêm a ser uma “aplicação monolítica”.
Uma aplicação monolítica é aquela na qual todos os componentes de negócio encontram-se dentro de uma mesma unidade de implantação. Se você é programador Java já sabe do que estou falando: os arquivos WAR ou EAR. Reparou que usei o termo “componentes de negócio”?
O que é um componente?
Vou usar a definição de Fowler e Lewis de componente: “é aquela unidade de software que pode ser aprimorada e substituida de forma independente”. Vamos pensar num exemplo simples: a biblioteca que você usa para compactar dados. Esta possívelmente foi feita por um terceiro. Caso este terceiro descubra uma maneira de compactar dados de forma mais eficiente, basta que você troque a biblioteca, se esta mantiver a mesma assinatura, seu sistema inteiro se beneficiará destas melhorias de forma transparente. E você apenas substituiu um pedaço do seu sistema.
Bom: qual o problema então com aplicações monolíticas? O fato destas conterem em si todos os componentes usados e todos serem executados dentro do mesmo processo. Precisou trocar um componente? Você irá fazer o deploy da unidade inteira. Já houve algumas soluções interessantes para este problema, como por exemplo o EJB e OSGi (OSGi na minha opinião é como o Java SEMPRE deveria ter sido, falo mais sobre ele no futuro).
O ideal seria que você não precisasse parar seu sistema para substituir um componente. Como no caso do bundle OSGi ou da implementação remota do EJB, mas nem sempre isto ocorre ou mesmo é necessário. Ok: você sabe o que é um componente. Um componente de negócio seria portanto aquele que encapsula um requisito funcional do seu sistema. O que é então um micro serviço? Um serviço pequeno?
O que é um serviço?
Seguindo a definição de Fowler e Lewis, um serviço seria na realidade um tipo especial de componente. Aquele componente que descrevi alguns parágrafos acima é o que chamaríamos de biblioteca. É código contra o qual ligamos aquele que escrevemos, e que consequentemente nos gera um sistema monolítico. O serviço é o oposto da biblioteca, ou seja, nós não ligamos nosso código diretamente a este: apenas o executamos a partir de chamadas remotas.
Sendo assim, um serviço seria um componente executado em um processo diferente do cliente que o usa. Esta é uma idéia bastante interessante: caso um serviço apresente problemas, basta que, em tempo de execução, eu substitua apenas aquele pedaço do sistema, mantendo todo o resto em execução como se “quase nada” houvesse ocorrido. Preciso de maior escalabilidade? Poderia pensar em diversas instâncias do mesmo serviço. As possibilidades são práticamente infinitas quando pensamos desta forma.
E o que é o tal do micro serviço então?
O prefixo “micro” é enganador. Em um primeiro momento podemos pensar que se trata de um programa bem pequeno, e na apresentação de Lewis é defendido que devem ser pequenos o suficiente para que sejam compreendidos por uma úncia pessoa.
Um micro serviço compreende um requisito funcional do seu sistema. É um componente de negócio executado em um processo externo portanto. Como requisitos funcionais podem ser complexos, nada impede que seu “micro” componente não seja tão pequeno assim (mas isto vai depender mais da sua modelagem do que desta abordagem). Sendo assim acredito que seja mais interessante pensar que o ideal seria serem micro serviços pequenos, porém o essencial é que determinem bem o que venha a ser os requisitos funcionais que implementam.
Um sistema que siga a arquitetura baseada em micro serviços portanto é aquela que é composta por micro serviços, cada um destes responsável por um conjunto finito de requisitos funcionais do projeto.
Consequências do micro serviço
A saída do modo monolítico muda bastante coisa no nosso modo de pensar. Para começar podemos pensar em dividir melhor a equipe. Este é inclusive um ponto apresentado por Fowler e Lewis. Agora podemos ter equipes especializadas naquele conjunto de funcionalidades de negócio, que passarão a tratar o serviço não como um mero componente, mas sim um produto, com ciclo de vida independente. Isto trás implicações profundas do ponto de vista gerencial.
Outro ponto importante: como estes micro serviços se comunicam? Faz-se necessário adotar uma estratégia que facilite a integração de todas estas pontas. Em todos os artigos são expostas duas estratégias fundamentais: REST (alguns mencionam HATEOAS) e mensageria através de algum broker como ActiveMQ, RabbitMQ, HornetQ ou tantos outros. É obrigatória a presença de um protocolo aberto comum a todos os serviços: imagine ter de usar protocolos proprietários neste tipo de arquitetura, sua vida se tornaria um inferno.
Um ESB se aplica? No artigo de Fowler e Lewis ele é mencionado por alto, mas não se mostra como algo obrigatório. Sinceramente também acho que seja desnecessário, apesar de que um serviço similar ao UDDI quebre troncos nesta abordagem. UDDI é a grosso modo um diretório de web services baseados em SOAP. Algo que me responda à pergunta “qual o endereço das implementações do serviço x?” tornaria tudo muito mais fácil.
Se todos os processos são isolados, também preciso que sejam monitorados, ou seja, todo serviço deve apresentar métricas sobre sua qualidade de serviço. É fundamental que eu saiba quem está ou não online para que cada micro serviço possa implementar sua própria estratégia no caso de indisponibilidade de algum serviço do qual dependa.
E olha outro ponto importante: você também precisa de uma estratégia de versionamento que seja consistente. Se os micro serviços são por definição componentes, estes devem poder evoluir isoladamente também.
Se a comunicação entre micro serviços sempre requer a invocação de código externo é necessário pensar em estratégias visando minimizar perda de performance. Uma coisa é chamar código diretamente ligado ao meu (bibliotecas), outra código remoto.
Há também um outro ponto bastante delicado: como pensar a questão da componentização? Se quero que meus micro serviços sejam completamente independentes como organizo meu código fonte? Na apresentação de Lewis é proposto que cada equipe tenha seu próprio repositório a fim de evitar a criação de componentes compartilhados que causem dependências profundas entre um ou mais micro serviços. Faz muito sentido, especialmente se eu quiser que alguns componentes sejam escritos em linguagens distintas. Imagine dois micro serviços dependentes de uma biblioteca compartilhada: alterando-a mudo o comportamento de dois componentes que deveriam ser em teoria completamente independentes.
E estes são apenas alguns dos pontos gerais que observei nesta abordagem. Vocês com certeza me mostrarão mais alguns nos comentários deste post, certo? :)
Consequências do lado Java
Pensando como desenvolvedor Java as coisas mudam de figura no modo como pensamos o deploy de nossos projetos. Até então pensamos em arquivos WAR e EAR que iremos instalar em nossos servidores de aplicação. No entanto os serviços são executados isoladamente, certo?
Logo devemos minimizar o uso de containers. Imagine que eu sobrecarregue um container com inúmeros micro serviços. Se este cai, diversos vão junto. A solução é embarcar o container e distribuir nossa aplicação como um jar único. Já há projetos que nos permitem fazer isto. Destes o que acho mais interessante atualmente (e que podemos usar HOJE) é o Spring B oot. Grails terá algo similar em breve (afinal de contas, é Pivotal né?), Vertx também nos permite fazer algo similar.
E ei: se você olhar com atenção, verá que toda a história por trás do Node.js gira em torno deste conceito também. ;)
Mas cadê a novidade?
Este é minha grande dúvida. Cadê a novidade? Decompor nossos projetos em micro serviços é algo que fazemos há muito tempo. Veja por exemplo EJB e seu modelo distribuído. Um único protocolo comum (RMI por baixo dos panos) e lógica de negócios encapsulada no bean.
Outro exemplo interessante: OSGi. Em que eu posso inclusive fazer o deploy de um serviço (representado como um bundle) no container em tempo de execução sem parar a aplicação. Neste caso não necessáriamente seria um micro serviço pois o bundle é executado na maior parte das vezes dentro de um mesmo processo, mas poderia ser externo também.
E tem também o SOA, que nos fornece exatamente isto com o uso de ESBs, certo? Isto sem mencionar as diversas vezes em que desenvolvemos sistemas usando esta mesma abordagem no passado sem fugir muito destes princípios que apresentei sem darmos este nome (aqui está um exemplo interessante no blog do Rafael Romão).
A novidade talvez esteja no fato de finalmente estarmos dando um nome a este boi. Gosto disto, quanto melhor o vocabulário, melhor.
Concluindo
Não acredito que a pergunta “será uma arquitetura baseada em micro serviços o futuro?” será respondida somente em um futuro distante. Na realidade, ela já foi resolvida: ela é o presente. A partir do momento em que isolamos os objetivos de negócio do nosso sistema em processos isolados que possuam as características a seguir:
- Cada serviço executado em um processo isolado.
- Padrão de comunicação entre os serviços.
- Pequenos o suficiente para que isolem bem requisitos funcionais do sistema.
- Cada serviço apresente métricas sobre si mesmo.
Ou pelo menos a maior parte destes pontos, já é uma arquitetura baseada em micro serviços (ou próxima).
O que realmente gosto nesta história toda é a quantidade de discussão que imagino surgir a partir destes conceitos. Que venha e que com isto tenhamos melhores termos para estes problemas!
PS: 31/3/2014 – 11:00 AM
Encontrei uma crítica bem interessante ao texto de Lewis e Fowler que você pode ler neste link. O autor tem um ponto bastante interessante: para ele “micro serviços” são na realidade um retrocesso pois ignoram os pontos aprendidos com SOA. Os comentários são particularmente interessantes. :)
PS: 6/4/2014
Uma semana depois postei algumas conclusões a que cheguei sobre o assunto neste post.
Ótimo artigo, Henrique. Concordo que seja mais um termo novo que uma metodologia nova, mas creio que a diferença esteja mais em o que compõe cada micro serviço numa Arquitetura de Micro Serviços do que no modo como esses serviços interagem entre si.
Oi Rafael, que bom que gostou, valeu!
Você levanta um ponto interessante. No modo como os servios se integram realmente não há novidade alguma: é usado o que sempre usamos, o REST padrão (na apresentação do Lewis é exposto inclusive o uso de atom, que achei bem interessante).
Bacana esse post, há tempos venho buscando mais informações sobre Microservices para entender melhor os benefícios e desvantagens que eles possuem. E entender se tal ideia é mais do mesmo ou não.
O ponto que eu achei interessante foi o de isolar as apps em container distintos, ou seja, embutindo um tomcat, jetty ou outro container/server, na aplicação. Com isso é possível monitorar as apps a nível de serviço num linux por exemplo. Desta forma as ferramentas já conhecidas hoje poderiam ser melhor trabalhadas ao invés da criação de inúmeras ferramentas que possuam a necessidade de se formar especialistas para usá-las. Claro que depende de cada caso, porém as ideias que REST e Microservices simplificam o modo de como olhamos para nossa arquitetura/plataforma e de certa forma permitem enxugar a complexidade.
Por exemplo, ferramentas do próprio Linux já proveriam muitas das informações necessárias para monitoramento dos serviços (consumo de memória, cpu, etc). No caso de escalabilidade, facilmente poderiam ser usados roteamentos (usando cisco e companhia) para servidores em regiões separadas para atender uma sobrecarga de requisições. A utilização de firewalls já existentes para prover segurança e o descobrimento dos endereços dos serviços caberia ao DNS. Talvez um catálogo de serviços ainda deva ser necessário ao invés do DNS, ainda não pude validar a viabilidade.
Enfim, são muitas ideias que já existiam por ai com um olhar sobre um aspecto ou em outro, mas …o fato de finalmente estarmos dando um nome a este boi” favorece discussões ricas e pragmáticas.
Oi Raphael, obrigado!
Por falar em ferramentas do linux, uma outra possibilidade que acho interessante diz respeito ao deploy.
Imagine poder usar repositórios do linux e arquivos rpm ou deb. Abre novas possibilidades para facilitar ainda mais a nossa vida.
Puts eu tb pensei nisso rsrs… Não sou sysadmin, então eu não sei todos os detalhes pra gerar os pacotes e disponibilizá-los com segurança. Mas com total certeza essa ideia é fantástica.
Eu também achei bacana a alternativa do netflix pra deploy, lá eles fazem deploy da máquina virtual e não de um war. Sei que a produtividade nesse ponto depende muito do tamanho do seu negócio, qtdade de usuários, ambiente de produção e etc. Ou seja, devemos lembrar sempre que é um problema em busca de uma solução e não o contrário.
Vc tem mais referências sobre Microservices? Mesmo se for em outras tecnologias serão bem-vindas.
Oi Raphael,
Um blog que tem chamado bastante minha atenção é este aqui: http://service-architecture.blogspot.co.uk/
O sujeito vai além do simples acordo com o Martin Fowler e o Lewis, na realidade, ele critica o conceito de micro serviços. Abre bastante a cabeça os comentários que são feitos comparando SOA com micro serviços.
Pessoalmente… bom: é tanta coisa para escrever em um comentário em post que vou acabar escrevendo um post em continuação a este com as conclusões que cheguei a respeito, mas resumindo a impressão final que tenho é a seguinte: assim como REST foi uma reação aos webservices baseados em SOAP, micro serviços são uma resposta para o SOA tradicional.
Imagino, esse assunto dá margem para muitas discussões… aguardarei o próximo post.
Valeu!
Kiko, excelente artigo.
Respondi vc no twitter outro dia sobre isso, e vc descreveu exatamente minha opinião. Um ponto importante que deve ser muito discutido é sobre como separar este componentes. Acho que desde a época do CDB até a SOA se fala muito nisto, mas agora de fato acho que Domain Driven Design começa a fazer uma diferença maior em termos de arquitetura.
Oi Luiz, que bom que gostou, valeu.
Eu acabei de incluir um PS no final do post com uma crítica *muito* interessante ao texto do Fowler, você chegou a dar uma olhada?
Oi Kico,
Acabei de ler. Interessante a crítica, mas ao mesmo tempo, quando ele fala de WSDL e IDL, eu entendo o argumento do Fowler. Ao meu ver o que o Fowler tenta mostrar é sobre formas mais “lights” de fazer a coisa.
O que mais me incomoda é a crença de que SOA é Bullshit, CDB é Bullshit, OO é Bullshit, etc e desconsiderar o trabalho feito durante anos. Lógico que existe um aproveitamento e uma confusão de “conceitos vs ferramentas” que os vendors (Oracle, IBM) se aproveitam . Acaba que o mercado fica cheio de técnicos que associam SOA ao SOA suíte da Oracle ou a um ESB, etc.
Mas eu tendo a concordar com o artigo, parece que micro serviços são uma maneira diferente de olhar SOA.
Minha dúvida com relação a isto: será que estamos falando de níveis de abstração diferentes quando falamos SOA vs Micro services?
Concordo demais com você Luiz. Na minha opinião todos os problemas que temos surgem do mau uso da linguagem. É por isto que valorizo tanto os momentos em que damos nome aos bois, como agora.
Sobre o desprezar do passado, também me incomoda demais. Hype é essencialmente isto e, numa boa? Considero este tipo de postura uma espécie de “imbecil detector”.
A propósito, depois da uma navegada no blog deste critico do Fowler: vi muita coisa boa por lá. :)
Luiz, tb concordo com vc.
Pelo que eu andei pesquisando, seria um nível de abstração de SOA. Mas dependendo da visão e da discussão, pode ser levado para outros caminhos que os rivalizam.
Penso que o termo SOA ficou tão ligado a ferramentas dos grandes vendors, não para nós especialista que vão à fundo no assunto, mas no geral. Para conseguir falar com um diretor sobre a necessidade de pensarmos em serviços, sempre esbarro nas questões do tipo “Humm.. teremos que comprar um ESB” e etc, quando na verdade estou querendo propor simplesmente mudar a forma de como pensamos a respeito do desenvolvimento dos sistemas. Dai uma ideia simplificada e sem tanto ruído, acaba de fato vindo a calhar.
E quanto ao Hype, de fato o hype de hoje poderá ser o legado do amanhã, temos que fazer escolhas conscientes para que as soluções perdurem e tenham valor.
Oi Raphael,
Com relação ao Hype, acho que meu ponto é, mesmo que seja um hype, tem muita gente estudando, escrevendo e publicando coisas que podem ser relevantes sobre o assunto. O que acontece é que depois de um tempo, isso passa a ser ignorado e quando o hype passa só ficam as críticas.
Eu sou bastante interessado em linguagens funcionais, e a pouco tempo começou a se falar muito sobre o assunto. Foi engraçado ver o calhamaço de críticas ao modelo OO. As críticas ao modelo não me incomodam, pq elas tem que existir mesmo. O ponto é que eu cheguei a ver profissionais dizendo OO era uma porcaria, etc. Como assim? Passamos anos desenvolvendo o paradigma, e isso agora é ignorado?
Foi só um exemplo e existem muitos outros por aí.
Atah… esse lado com certeza é ruim, principalmente pq mtos dos conceitos já existem por ai há um bom tempo.
Olá,
Eu estava acompanhando a série de artigos do Fowler e Lewis, e no final ainda não estava bem convencido que era realmente algo que merecia ganhar um novo nome próprio. Modularidade, componentização, divisão de reponsabilidades, a quanto tempo já estamos falando disso?
Depois que eu li a crítica do Steve Jones, fico mais tranquilo de não ser o único a achar que se trata de hype, e como tal, deve ser avaliado cuidadosamente para ver o que serve, e o que não serve.
Em tempo, na GReach da semana passada teve até uma apresentação a respeito de Micro Services, usando Grails, deixo o link:
http://beckje01.github.io/greach-2014-micro-service-talk/
Abs,
Uilian.
Oi Uilian,
bacana esta dica da apresentação, valeu!
Eu estou ficando cada vez mais dividido com relação a isto, e justamente por isto já estou pensando em um novo post sobre o assunto. :)
Acredito que micro-servicos são sim uma inovaçao, o fato de já existirem abordagens SOA, ou EJB RMI com você citou sao bem distintas de como micro services se aplicam no mercado hoje. Comecando que eles sao compostos de forma interdependente no tocante a tecnologia (diferente do EJB), você tem micro servicos se comunicando atraves de APIs entre si sem mediadores pré-definidos em alguma spec ou plataforma, é um mundo livre (ao contrário de SOA), vc tem servicos de diferentes plataformas e linguagens atuando na mesma solucao de software de forma muito mais comum
Jamais antes se pensava em colocar workers python, trabalhando com backend .net e frontends em java script para uma mesma solucao distribuida, isso eh fruto da inovacao com micro services.
.Assim como NoSQL pode ser considerado um relaxamento (não retrocesso) de regras em relacao aos SQL relacional, o micro-services seria um relaxamento do SOA, uma maneira menos burocrática e mais independente de compor servicos. O oposto de EJBs, e Web containers da era anterior. Mas é só minha opnião.
Oi Fabrício,
na realidade se pensava em fazer este tipo de integração sim. É o princípio básico por trás do SOA. A única diferença é que nos micro serviços você não tem o ESB, UDDI, etc.
http://blog.cleancoder.com/uncle-bob/2015/05/28/TheFirstMicroserviceArchitecture.html
Um post muito lúcido do Uncle Bob em seu blog e que nos faz refletir sobre a reinvenção da roda (ou seria do pneu furado?).
Belo texto Luiz, obrigado pela dica!
Pingback: MicroProfile 1.0 – Otávio Santana
Pingback: O que é uma arquitetura de microsserviços? - servidor arquitetura-de-software - Perguntas e Respostas