Arquitetura de microserviços ou monolítica?

Dentro da Caelum, temos a experiência de termos criado várias aplicações web, seja para nós mesmos, para clientes ou para iniciativas nossas. Uma dessas aplicações de vital importância para nós é o nosso ERP. É um sistema desenvolvido internamente e que cuida basicamente de toda a empresa, desde o financeiro, RH, pagamento, até as matrículas e contratos dos alunos, contatos com clientes, alocação de instrutores e várias outras funcionalidades. Todas essas funcionalidades estão agrupadas dentro desse grande sistema, fazendo dela uma aplicação monolítica, ou seja, uma aplicação feita em uma só unidade.

Sistema monolítico

Um único sistema, com todos os módulos dentro dele

 

Como tudo em desenvolvimento de software, existem vantagens e desvantagens nos sistemas monolíticos. Um dos principais pontos negativos é que você tem um grande ponto único de falha, que significa que se houver algum erro no cadastro de funcionários que deixe o sistema fora do ar, isso vai levar junto todo o sistema, incluindo funcionalidades que não possuem nenhuma relação com essa funcionalidade, como por exemplo a geração de contrato para alunos. Outro ponto negativo é a base de código, que se torna muito extensa, podendo deixar novos membros do projeto menos produtivos por algum tempo, já que a complexidade do código é bem maior.

Por outro lado, temos um sistema cujo o deploy é fácil de ser feito, já que o banco de dados facilmente evoluirá junto para todas as funcionalidades e há apenas um ponto onde o deploy precisa ser feito. Além disso, não há duplicidade de código e classes necessárias entre os diferentes módulos, já que todas elas fazem parte da mesma unidade.

O cenário da Casa do Código

Ao criarmos a Editora Casa do Código, decidimos seguir outro caminho para o e-commerce. Lá não podemos correr o risco de ficar com a loja fora do ar caso alguma funcionalidade periférica falhe, então quebramos nossa arquitetura em serviços menores. Dessa forma, há um sistema principal, que é a loja e está hospedada no Shopify, e vários outros sistemas que gravitam em torno dela. Temos uma aplicação que faz a liberação dos e-books para os clientes, outro que contabiliza os royalties para autores, outro para cuidar da logística de envio dos livros impressos para o cliente, um painel de visualização dos livros comprados, um para fazer a liberação de vale presentes e outro para promoções.

Arquitetura em microserviços

Vários sistemas que são notificados por outro via HTTP quando um determinado evento ocorre. Cada sistema decide o que fazer com o JSON que é enviado para ele

 

Dessa forma, quando um evento acontece na nossa loja online, os diferentes sistemas precisam ser notificados. Para essas notificações usamos requisições HTTP, assim, quando uma compra é confirmada na loja online, todos os sistemas recebem em um Endpoint essa requisição HTTP, contendo um JSON com todos os dados da compra. Cada sistema decide o que fazer com as informações recebidas, de acordo com a necessidade. Por exemplo, o sistema de liberação dos e-books verifica se a compra possuía e-books e gera os links de download para o comprador, enquanto que o sistema de logística já dá baixa no estoque quando a compra é de um impresso, além de notificar as pessoas quando algum livro está ficando com estoque crítico. Essa característica importante para o maior desacoplamento dos serviços é conhecida como Smart endpoints, dumb pipes, que em uma tradução livre pode ser entendida como Endpoints inteligentes e fluxos simples.

Essa independência entre os diferentes serviços também traz consigo algumas vantagens e também desvantagens. Pelo lado positivo, minimizamos a existência daquele ponto único de falha. Caso algo dê errado no sistema que contabiliza os royalties, a loja continua no ar, os clientes continuam conseguindo baixar seus e-books, ou seja, não compromete a execução de outros servidos. Além disso temos sistemas com base de código menor, facilitando a barreira inicial na compreensão do projeto para um novo membro do time. Outro fator de suma importância é que conseguimos facilmente trabalhar com diferentes tecnologias. Temos serviços desenvolvidos em Java com VRaptor, Java com Play Framework, Rails e novos serviços sendo criados em PHP.

Por outro lado, há uma intersecção de código entre todos os sistemas, gerando uma repetição de código. Por exemplo, o código que recebe a requisição, transforma o JSON vindo do Shopify nos objetos que queremos trabalhar é o mesmo para todos os projetos, assim como classes de modelo. Minimizamos esse impacto com a criação de bibliotecas, que são compartilhadas entre os projetos. Além disso, temos uma pequena duplicidade de informações que raramente sofrem alterações entre os serviços, já que cada um possui sua própria instância de banco de dados.

Essa arquitetura onde temos um grande sistema quebrado em serviços menores e mais leves, por critério de funcionalidades de negócio, integrados via HTTP (ou alguma arquitetura de mensageria) é o que forma a famosa arquitetura de microserviços. Evidentemente, existem outros casos de arquiteturas de microserviços que podem usar diferentes tecnologias, bancos de dados compartilhados entre serviços, serviços que se comunicam com outros serviços e assim por diante.

Faz parte do papel do arquiteto de software tomar decisões baseadas em trade-offs. Nunca teremos uma solução perfeita. Sempre precisamos escolher entre vantagens e desvantagens, como foi o caso da Caelum com seu ERP monolítico e da Casa do Código com a utilização de microserviços. O importante é analisar calmamente qual é a melhor abordagem para cada situação. E você, já trabalhou em algum projeto com arquitetura de microserviços? O que achou? E se quiser saber mais sobre mobile, microserviços, APIs e vários outros assuntos, não deixe de visitar a Mobile Conf, dia 30/05 no Rio de Janeiro!

73 Comentários

  1. André Faria 17/03/2015 at 08:25 #

    Muito bem explicado Adriano, Parabéns!

    Abraços.

  2. Ismael Soares 17/03/2015 at 08:40 #

    Adriano, parabéns pela explicação! Até um leigo entenderia.
    É bom mostrar vantagens e desvantagens para que fique claro que é uma questão de melhor abordagem e que uma não é melhor ou pior que a outra. Digo isto, porque é comum a galera seguir a “moda” e acaba tomando decisões erradas.

  3. jonathan Lameira 17/03/2015 at 09:38 #

    Excelente Artigo me forneceu uma visão mais prática de microserviços.
    Bom ainda não trabalhei com implementação de microserviços, estou começando a estudar sobre, mas já estudei sobre ESB(Enterprise Service Bus) e não seria possível a aplicação do mesmo para um cenário igual ou parecido com o que vc nos apresentou? pois assim como o ESB acho que o microserviços devem fazer também (message routing, choreography, transformation, and applying business rules.) ou estou enganado?
    abraços e Parabéns!

  4. Richard Santana 17/03/2015 at 11:53 #

    Adriano,
    E no caso de alguma queda, vocês possuem algum padrão de recuperação das requisições que não encontraram o serviço up ? ( No caso de chamadas a serviços que não estão no ar e não usando mensageria, que deixaria a mensagem até o consumidor voltar)

  5. Maurício Aniche 17/03/2015 at 11:55 #

    Oi Adriano,

    Parabéns pelo post. Acho muito boa a ideia de microserviços, as vantagens são várias, mas ainda tenho algumas ressalvas:

    – Fazer a comunicação entre servidores não é fácil. Você começa a se preocupar com um monte de problemas que antes não existiam, quando “apenas precisávamos invocar um método”, como “servidor não tá lá”, “auto retry”, blá blá.

    – Repetição de código e dados entre eles. Querendo ou não, há dados duplicados, e geralmente é mais do que apenas IDs pra lá e pra cá. Evoluir algo significa evoluir esses vários sistemas ao mesmo tempo.

    O que vc acha?

  6. Adriano Almeida 17/03/2015 at 14:47 #

    @andre @ismael que bom que gostaram.

  7. Adriano Almeida 17/03/2015 at 14:59 #

    @jonathan não está enganado não. no caso da casa do código nosso fluxo é relativamente simples. no máximo temos dois passos de chamadas (um sistema que chama outro que chama outro). para casos mais complexos, com fluxos mais interdependentes e onde uma chamada dependa de que algo aconteça em outro sistema, aí na minha opinião os ESBs valem mais a pena, já que ele vai abstrair e simplificar muito do trabalho que você teria em fazer com os microserviços.

  8. Adriano Almeida 17/03/2015 at 15:03 #

    @richard no nosso caso, a loja tenta notificar os sistemas até que eles devolvam 200. se na primeira tentativa isso não acontecer, ele tenta de novo daqui a 2 minutos, se de novo acontecer, ele espera mais 5, depois ele espera mais 10, depois mais 30 minutos, depois mais 1 hora até que ele tenta no dia seguinte. o que até hoje pra nós foi tempo suficiente para percebermos que há algo errado e corrigir.

    Claro, se a loja cair, não há muito o que fazer, já que nem a compra será efetuada.

  9. Adriano Almeida 17/03/2015 at 15:11 #

    @aniche realmente, todos esses pontos fazem parte do trade-off.

    Na casa do código, que é algo que lida diretamente com vendas e precisa de disponibilidade o mais alta possível, o acreditamos que o era importante ter a maior disponibilidade possível, mesmo pagando o preço do código duplicado, um pouquinho de regra duplicada, deploy mais complexo e o trabalho do auto retry.

    Definitivamente não é a solução para qualquer sistema. Evidentemente existem aplicações que são mais sensíveis ao uptime e aplicações que são menos sensíveis. Para essas menos sensíveis, como é o caso do nosso ERP até então, acredito ser possível sim pagar o preço da menor disponibilidade, para ter os outros benefícios.

    Enfim, é questão de escolher o que você aceita abrir mão, como qualquer decisão arquitetural, mas sempre avaliando o contexto como um todo, não apenas nossos gostos pessoais.

  10. Bruno Palaoro 18/03/2015 at 08:38 #

    Uma dúvida sobre esse cenário de microserviços. Digamos que um dos serviços precise fazer uma pesquisa onde um dos critérios está na base de dados de outro. Por exemplo, o serviço Promoções precisa fazer uma pesquisa com todos os clientes de nome João que não participaram de nenhuma promoção ainda, ou seja para essa consulta é necessário informações tanto da base de Promoções como da base de Clientes, que está me outro serviço.
    Como vocês solucionam isso? Replicam algumas informações na base (nome do cliente também está na base de Promoções), ou acabam quebrando em vários serviços, deixando a consulta mais lenta e complexa? Ou outra alternativa?

  11. Carlos 18/03/2015 at 09:39 #

    Com o crescimento do Uso de Apps e multi devices de diferente tamanhos é bem melhor usar a arquitetura de microserviços.

    Parabéns pelo artigo.

  12. Rafael 18/03/2015 at 11:01 #

    Adriano,caso haja necessidade de orquestração dessas chamadas HTTP,por exemplo onde um serviço só possa ser executado ao término de outro,como isso poderia ser gerenciado?

  13. Adriano Almeida 18/03/2015 at 13:24 #

    @bruno boa pergunta. no nosso caso temos algumas informações duplicadas sim. o ideal é que seja o mínimo possível. por exemplo, para promoções, não preciso ter todas as informações do cliente, como endereço completo do cliente, histórico de compras nem nada, apenas o email. então é só isso que eu vou ter e isso realmente é replicado em diferentes sistemas. se um dia eu precisar dessas outras informações, talvez seja a necessidade de eu aumentar isso, mas só vou me preocupar com isso quando precisar.

  14. Adriano Almeida 18/03/2015 at 13:29 #

    @rafael existem algumas saídas. nesse exemplo, eu dei uma simplificada no nosso cenário para mostrar de forma mais didática, mas há um corner case nos nossos sistemas onde precisamos de uma espécie de orquestração. como tratamos isso? resumindo, com consistência eventual. explicando melhor:

    quando uma compra acontece, o sistema de liberação do ebook e o sistema do painel com as compras e link de download do cliente são notificados. só que o ebook pode ainda não ter sido liberado (e assim, o link de download não existe) e o painel com a compra e links de download já pode ter sido chamado. nesse caso, tratamos essa situação direto no código. caso o link de download ainda não exista, o painel mostra apenas um botão “disponível em breve”. quando o sistema de ebooks termina a liberação (é um processo que pode demorar alguns segundinhos), ele avisa o sistema do painel do cliente quais são os links de download e aí sim o link de download vai aparecer.

    Deu pra entender?

    Evidentemente, é uma situação que também poderíamos resolver com um ESB ou algo do gênero, mas preferimos seguir essa abordagem.

  15. Wendy Krepsky 18/03/2015 at 16:16 #

    Eu adicionaria duas questões:

    1- Toda integração adiciona complexidade. Quando não posso contar com uma transação de banco tenho que fazer uma série de controles para garantir que tudo fique consistente. Isso também ocorre em operações assíncronas em uma solução monolítica.
    2- Uma solução monolítica pode chegar a um ponto onde é muito difícil escalar.

  16. Bruno Borges 18/03/2015 at 18:07 #

    Há anos empresas desenvolvem soluções sobre a plataforma Java EE utilizando uma arquitetura com deployments granulados. Não entendo como que isso pode ser agora chamado de “Arquitetura de Microserviços”.

  17. Adriano Almeida 18/03/2015 at 18:17 #

    Oi @bruno, perfeito! A arquitetura não tem nada de novo, o nome é o de menos nisso tudo. O importante é se serve ou não para resolver o seu problema. Isso é o que deveria ser levado em consideração para se usar ou não determinada abordagem, não o nome bonito ou quem advoga a favor ou contra a abordagem.

  18. Daniel 23/03/2015 at 12:58 #

    Eu não sei se não foi mencionado por ser uma questão bem óbvia, mas uma desvantagem de microserviços é troca de informações entre serviços, que pode consumir um tempo que não pode ser desperdiçado em um certo tipo de situação.Ainda que sejam milisegundos.

    Já trabalhei em um sistema em C++ que era dividido em 5 outros sistemas que se comunicavam através de recursos de SO, o que diminuia bastante o tempo perdido na comunicação entre eles.Só não sei se isto pode ser considera um microserviço, ou era somente um deploy granular como foi citado aqui.

    Parabéns pelo artigo.

  19. Adriano Almeida 23/03/2015 at 14:10 #

    oi @daniel, é um tanto óbvia sim, mas acredite, muitas vezes é deixada de lado. Já passei por uma situação muito parecida com a que você descreveu e aí, realmente, integração via HTTP, REST ou SOAP são inviáveis.

  20. Stélio Moiane 25/03/2015 at 16:52 #

    Oi pessoal,

    Mais uma vez voltamos a famosa citação “Não existe bala de prata”. Na verdade as duas abordagens dependendo da situação são bem válidas. Eu particularmenente apoio muito a ideia de micro-serviços. Tirando os deploys, codigo aparentemente repetido e chamadas as serviços que não respondem. Valem boas horas de sono quando se trata de manter o produto bem como envolver novos membros.

    Parabens Adriano.

  21. Macedo 26/03/2015 at 17:44 #

    Como resolver a situação, tenho uma unica base.

    Tenho um modulo produto, bem intuitivo, tenho um jar com tudo relacionado e depois um war com a parte web, tudo funcionando. porém adiciono o modulo reserva, porem reserva precisa conhecer a entidade Produto, como gerenciar isto no hibernate?

    Eu duplico informações e crio uma entidade produto simplificada no modulo de reserva?
    Vou ter dois jar (produto.jar e reserva.jar) cada um com um hibernate.cfg.xml ?
    Vou ter duas conexões com o banco?

  22. Macedo 26/03/2015 at 19:25 #

    Como resolver a situação, tenho uma unica base .

    Tenho um modulo produto, bem intuitivo, tenho um jar com tudo relacionado e depois um war com a parte web, tudo funcionando. porém adiciono o modulo reserva, porem reserva precisa conhecer a entidade Produto, como gerenciar isto no hibernate?

    Eu duplico informações e crio uma entidade produto simplificada no modulo de reserva?
    Vou ter dois jar (produto.jar e reserva.jar) cada um com um hibernate.cfg.xml ?
    Vou ter duas conexões com o banco?

  23. Fernando 27/03/2015 at 10:25 #

    Excelente post, traz uma visão legal de alto nível sobre a aplicação das diferentes abordagens. Seria possível descrever sobre a infra-estrutura para suportar as demais aplicações. ex: estão distribuídas em diferentes servidores, ou VMs e banco de dados
    Se entendi bem, o fluxo é mapeado dentro da propria aplicação, certo? caso não, usam algo ex, apache camel? que decide o que vai chamar.

    Parabens pelo artigo

  24. Rodrigo 27/03/2015 at 12:56 #

    Ótimo post! Eu pensei que vcs haviam desenvolvido a loja virtual tb, pq a opcao por Shopify? Abs

  25. Paulo Silveira 31/03/2015 at 22:30 #

    oi Rodrigo.

    Foi uma decisão complicada. Mas a nossa preferência é sempre comprar software pronto em vez de criar um novo. Muitas vezes é mais barato e sempre mais rápido. Claro que deve ser muito bem estudado. Criar um e-commerce era algo fora do nosso foco. Queríamos criar uma editora. Qualquer coisa que não envolvesse livros, edição e conteúdo seria um entrave. Focar no negócio era total prioridade. Quando apareceu um sistema cheio de hooks e microsserviços, abraçamos.

  26. Adriano Almeida 01/04/2015 at 10:28 #

    @Fernando, o fluxo todo está dentro da aplicação. Como é um fluxo mais simples (não há mais do que dois níveis nesse fluxo), preferimos não adicionar nada para tratar a orquestração e fazermos nós mesmos.

  27. M. França 09/04/2015 at 14:47 #

    Olá, Adriano.
    Pegando carona no que o Bruno falou, o que me trouxe até aqui foi o título de “Microserviços” – que é uma nova trend, mas que não me parece ter relação com essa comparação “SOA” x Aplicação Monolítica. Se bem que, pra mim, ficou esquisito cada aplicação ter sua própria base dados (diagramas) … Se estamos falando de serviços, entendo que o mais usual é o uso de barramentos, e serviços consumidos por todas as aplicações: core e satélites – numa camada “acima” do SGBD.
    Também não entendi onde se justifica ter duplicidade de código, já que um projeto pode referenciar bibliotecas externas, ou de outros projetos. E também não vejo como negativo o fato de deploys separados, ao contrário – ainda mais considerando tecnologias na linha do DevOps.
    Abraço,
    França.

  28. Marcelo 17/04/2015 at 09:56 #

    Excelente post.
    Estou estudando sobre microservices, acho bem massa para alguns sistemas.
    Poderia abordar em um post com algum exemplo de segurança, autenticação para microservices.
    vlw.

  29. Luiz E. 26/05/2015 at 08:30 #

    @França

    Também não vi nada de micro-serviços no vídeo/post. Um pouco oportunista demais.

    Luiz

  30. Adriano Almeida 26/05/2015 at 11:27 #

    oi @franca e @luiz, microserviços nada mais é do que uma forma de fazer arquitetura orientada a serviços. isso que é o bom, não existe uma forma de fazer, não existe certo ou errado. o importante é enxergar que existem situações que uma abordagem ou uma decisão pode fazer mais sentido que outra decisão. isso faz com que evitemos empurrar soluções de caixinha para os clientes como uma verdade absoluta, sendo que uma pequena adaptação ou modificação no processo pode fazer com que tudo faça mais sentido para o negócio dele.

    um exemplo disso que eu digo é o caso dos bancos de dados que você citou. a nossa decisão foi de separar cada micro aplicação com seu próprio banco para minimizar o quanto fosse possível o risco de ponto único de falha. se tivesse um banco só, uma migração feito errada, uma aplicação com pool de conexões mal configurado, uma sobrecarga em alguma das aplicações faria com que todos os outros sistemas parassem de responder, pq não iriam conseguir acessar o banco.

    sobre duplicidade de código, isolar em bibliotecas no fundo não deixa de ser eu ter uma duplicidade de código. a única diferença é que ela está num .jar (e lá dentro o .class) e não num .java (e consequentemente o .class). tanto é verdade que se eu precisar de uma mudança, dependendo da alteração eu tenho que mudar em todos os meus serviços. Por exemplo, se eu precisar de uma informação a mais do cliente (para os serviços em que o cliente é relevante), vou precisar modificar o .jar de todo mundo. E isso é um efeito colateral da duplicidade.

  31. Luiz E. 08/06/2015 at 14:13 #

    Uncle Bob escreveu um ótimo post em seu blog e me deixou com a impressão de que estamos reinventando o pneu furado.

    http://blog.cleancoder.com/uncle-bob/2015/05/28/TheFirstMicroserviceArchitecture.html

  32. Felipe Boso 03/07/2015 at 21:11 #

    Adriano como voces tratam a parte de front end da aplicacao? cada microservice tem sua parte front end?
    Como fica a questao de css e duplicacao de codigo na parte do front end?

  33. Filipe Torres 04/01/2016 at 18:17 #

    Parabéns pelo artigo, foi muito esclarecedor.
    Outro texto interessante sobre este assunto é este: https://dzone.com/refcardz/getting-started-with-microservices

  34. Marideni 06/01/2016 at 17:28 #

    Oi Adriano,

    Sou arquiteta de dados. Já vivenciei os dois cenários. Relacionado aos bancos de dados, me agrada a separação dos mesmos respeitando seus papéis e responsabilidades, como mostra o exemplo que você mencionou. Porém minha preocupação é relacionada as bases de referência, os MDMs ou MDRs. Exemplo: Caso eu tenha um MDM de pessoas, significa que o melhor dado cadastral de uma pessoa estará nele e somente nele. Devido a isso, se o meu sistema é baseado na arquitetura de microserviços como ficaria a questão da utilização dos dados de pessoas pelo sistema de Nota Fiscal e de Pedidos? Os dados seriam duplicados ou teríamos serviços únicos e comuns que sempre consultariam os dados das pessoas no MDM e as bases dos sistemas de Pedidos e Notas Fiscais teriam somente as chaves (fks) do MDM de pessoas?

  35. Adriano Almeida 12/01/2016 at 09:16 #

    @FelipeBoso: No nosso caso, cada serviço tem seu front-end sim. Usamos um CSS comum para a grande maioria deles, onde o acesso é apenas interno. Os que possuem acesso externo possuem CSS similar ao do site, pra manter a identidade. Então reaproveitamos muita coisa.

    Então temos um CSS base, que é comum pra todo mundo e uma ou outra customização específica apenas que entra em cada um dos serviços.

  36. Adriano Almeida 12/01/2016 at 09:28 #

    @Marideni Ambas as abordagens são válidas. Na minha opinião, o que vai influenciar qual decisão tomar aí é o quanto de independência você quer entre os serviços e quanto de alteração nas informação vai haver. No nosso caso, optamos por independência total, então há a duplicidade de informação por diferentes sistemas. Todas as informações do cliente ficam na loja online que é o centralizador de tudo e algumas ficam no sistema de notas fiscais (como por exemplo endereço), outras no sistema que libera os e-books (como o e-mail) e assim por diante.

    No nosso caso, também é um pouco mais fácil essa abordagem de duplicar a informação, pois praticamente não temos alteração nos dados. Não temos que nos preocupar em manter uma sincronia. Por outro lado, se houvessem muitas alterações nos dados, a abordagem das FKs me parece boa, mas também causaria uma dor de cabeça por ter que fazer queries em dois bancos distintos, apesar de não ser o fim do mundo :).

    As duas abordagens tem tradeoffs. A questão é ver qual delas o preço é mais barato para sua situação.

  37. Vinícius Carvalho 10/04/2016 at 21:13 #

    Uma questão que não foi abordada mas que eu acho muito interessante com relação aos Microserviços é o reaproveitamento dos módulos. Se um módulo é criado pensando em sua reutilização futura será fácil aproveita-lo em um outro projeto o que acaba viabilizando os Microservices em um projeto onde o Monolítico parece ser o mais viável. O que acha com relação a isso?

  38. Gustavo Bitencourt 15/04/2016 at 02:06 #

    Primeiramente parabéns pelo artigo.
    Fiquei com uma dúvida que você levantou como vantagem numa arquitetura de microservices.
    Você comentou que a ‘base de código’ fica menor em uma sistema que utilizar arquitetura de microserviços.
    Porém, posteriormente, você comenta que em alguns cenários pode haver duplicidade.

    Sendo assim.. Se há duplicidade, e, se levarmos em conta que toda regra e implementação que seria feita num sistema monolítico, foi transferido para partes menores, que são microserviços.. Logo.. Se juntarmos todos esses microserviços (que pode ter duplicidade), teríamos uma base de código muito mais extensa que numa arquitetura monolítica, concorda?

    Por fim.. Chegaríamos a uma conclusão então, que um arquitetura de microserviços pode gerar uma ‘base de código’ mais enxuta se levarmos em conta a análise de cada ‘micro-projeto’.
    Porém, o projeto num todo, a base de código, ficaria menor num sistema monolítico.

    O que você acha?

    Desde já, obrigado! =D

  39. Adriano Almeida 15/04/2016 at 10:58 #

    Oi Gustavo, nem toda regra precisa ser replicada em todos os sistemas. Por exemplo, em um sistema temos o modelo de autores com os cálculos dos royalties, impostos etc. Essas regras só fazem sentido nesse sistema, então não replicamos essa regra nos outros.

    O que é replicado são regras que acabam sendo comuns a todos os sistemas. Geralmente, o que vai cair nesse caso são lógicas mais de infraestrutura do que regra de negócio, como a autenticação, ou o código para receber a chamada de outros sistemas e parsear o JSON/XML corretamente.

    Se as responsabilidades entre os diferentes serviços estiver bem definido, vai haver um mínimo (e bem mínimo mesmo) de regras comuns aos serviços replicados.

  40. Adriano Almeida 15/04/2016 at 11:15 #

    Opa Vinícius, acho isso fundamental. Só um cuidado que gosto de advertir é que de princípio dificilmente você saberá tudo o que precisa ser generalizado para reaproveitar em diferentes módulos. Então minha sugestão é começar específico e conforme a necessidade for aparecendo, você vai refatorando e isolando esses módulos.

    Mas claro, se já de antemão você tiver mapeado o que precisará ser reaproveitado em diferentes módulos, manda bala 🙂

  41. Gabriel Cardelli 20/05/2016 at 14:20 #

    Ótimo artigo.

    Fiquei com algumas dúvidas em relação aos dados do Livro. Existe um cadastro de livro em todos os sistemas? Quando vocês editam alguma informação do livro como é feita esta alteração? Cada aplicação expõe um serviço rest de alteração que é chamado sempre quando o livro é alterado?

    Abraços,
    Gabriel Cardelli

  42. Matheus 23/06/2016 at 16:41 #

    Primeiro: acho que que essa caixa de comentários deveria está la em cima, muitos comentários ate chegar aqui [risos]
    Segundo: Adriano, você explica muito bem tudo!
    Terceiro: a questão da modelagem do BD é singular para cada microservice correto? Ou existe alguma forma de ajustar isso? Acho muito complexo.! Abraços

  43. Adriano Almeida 28/06/2016 at 10:21 #

    Opa @Gabriel, na verdade existe um cadastro único dos livros que alimenta todos os sistemas. Chamamos ele de “publicador” e quando o livro é “publicado”, o cadastro é propagado para todos os sistemas só com a informação necessária para cada um deles.

    É muito raro termos edição no cadastro dos livros, já que as únicas informações que precisamos nos sistemas são o nome e o SKU (uma espécie de id do produto para o nosso estoque).

    Isso foi um cuidado que tomamos ao mapear os sistemas, tentando deixar apenas as informações mais rígidas espalhadas. Ou seja, apesar do livro ter várias informações que podem sofrer mais alterações (descrição, por exemplo), essa informação vive em só um sistema, onde ela faz sentido (no caso, a loja online) e provavelmente se vários serviços precisassem da mesma informação, provavelmente seria um sinal de que poderia ficar no mesmo serviço (mas aí precisaria analisar caso a caso para ver se faz mesmo sentido ou não).

  44. Adriano Almeida 28/06/2016 at 10:27 #

    @Matheus legal que gostou 🙂

    No nosso caso, cada DB possui sua própria modelagem mesmo. Mas a parte comum aos sistemas geralmente é igual, mesmo nome de campos/atributos, mesmos relacionamentos.

    Você poderia usar um único DB e ter uma única modelagem para todos. Também acho uma solução possível. A desvantagem que vejo é trazer o ponto único de falha para esse banco. Se caiu, caiu todos os sistemas. E acredito que migrações e atualizações de schema também precisam ser feitas sincronizadas com deploys das aplicações para não haver falhas.

    Confesso que entre esses tradeoffs, prefiro cuidar de vários bancos menores.

  45. Lucas Antonelli 08/08/2016 at 12:38 #

    Parabéns pela explicação. Ficou bem mais clara a diferenças entre os dois tipos de arquitetura.

  46. Carol 14/08/2016 at 19:00 #

    Oi, gostei muito da explicação, mas não ficou clara a diferença entre serviços web e microsserviços.

    Obrigada, Carol.

  47. Eduardo Alcantara 06/09/2016 at 10:40 #

    @brunoBorges, não há mudança de nomes. Você está falando de Java. Microserviços não se restringem ao Java. Você pode ter uma plataforma de microserviços compostos por vários servidores, onde cada um roda com soluções feitas em diversos tipos de linguagens, frameworks, OSs, bancos de dados etc.

  48. Eduardo Alcantara 06/09/2016 at 10:43 #

    @carol, os serviços web podem ser feitos de forma monolitica ou podem ser feitos como microserviços. a diferença é a transparência ao usuário. um serviço web pode ser um microserviço em uma cadeia de outros microserviços de uma plataforma bem maior, onde você pode ter a acesso a nenhum, um ou todos os serviços disponíveis. Eles podem estar presentes como serviço web via http, ou apenas através de portas, com uso de TCP ou UDP pela intranet ou Internet.

Deixe uma resposta