Essa é a pergunta mais importante que você precisa saber responder em uma entrevista de System Design. Ela é perguntada em Uber, Netflix, Red Hat, Google, quase todas as Big Techs fazem essa pergunta no comecinho ou no meio da entrevista. E hoje eu vou explorar as grafias, como responder essa pergunta e as principais dicas para conseguir demonstrar conhecimento e conseguir aquela vaga internacional.
A grafia dessa pergunta pode vir de formas muito diferentes. Vou dar as três que eu costumo ver com mais frequência. E depois nós vamos explorar como respondê-la e as principais pegadinhas que podem acontecer ali durante a explicação.
Então, a primeira forma de encontrar essa pergunta é, durante o processo de entrevista de System Design, o entrevistador pode chegar para o... você está com o seu desenho montado na tela, estruturado. Ele pode fazer a seguinte pergunta.
Como eu consigo garantir consistência da informação se eu mudar de monolito para microserviço? Então, essa pergunta tem diversas camadas ali, mas o mais importante é, estamos preocupados aqui com consistência, que é um ponto muito importante. Quando trabalhamos com System Design, a consistência da informação tem que ser explorada.
E outro ponto muito importante é a mudança de monolito para microserviço. Então nós estamos distribuindo o processo. Outra grafia bastante comum é qual a principal mudança no processo de transação quando se vai de monolito para microserviço.
Aqui ela já deu uma dica muito boa, a questão de transação. Está perguntando qual a principal diferença no processo de transação. E a terceira grafia é como controlar a transação no ecossistema de microserviços. Também é uma grafia muito parecida, traz transação e traz aqui ecossistema.
Então, antes de entrarmos efetivamente no conteúdo dessa pergunta, vamos entender o processo de transformação de um monolito para um microserviço. Então, o monolito é estruturado de uma forma que nós temos uma única aplicação e a chamada entre as diversas etapas de monolito acontece via chamadas de métodos, function calls. Então, eu tenho um controller, eu exponho uma API, recebo um payload e faço uma sequência de chamadas de métodos dentro da minha mesma aplicação.
Por exemplo, se eu tenho um processo de checkout aqui, tenho o meu usuário, ele vai, por exemplo, dar um place order, vai criar um pedido, então vou criar um pedido. Vamos supor que nós tenhamos aqui uma sequência de passos. Primeiro ele checa se tem estoque, então chama o pedacinho do sistema que trata de inventário. Se tem estoque, ele vai...
Travar o carrinho, depois vai solicitar o pagamento, vai gerar efetivamente o pedido, salva esse pedido na base, limpa o carrinho na base, adiciona o processo de pagamento na base e deduz estoque na base. Então esse seria o processo dentro de um fluxo de checkout no monolito. A grande sacada da Monolith, na minha visão, é que...
Principalmente se estivermos usando, por exemplo, Spring ou qualquer framework. Normalmente, a gente controla todo esse processo dentro de uma transação. Então, eu vou ter aqui um início da minha transação e eu vou ter um final dentro da minha transação. E as transações, normalmente, elas são o que a gente chama de ACID, ou ácida.
Primeiro conceito, ela é atômica, então ela vai executar de forma independente. Ela é consistente, uma vez que eu começo a transação e eu termino, ela vai deixar minha base de dados num estado consistente, ao término. Ela é independente, então eu posso ter diversas transações ocorrendo ao mesmo tempo e elas não vão conflitar entre si.
E aí a base de dados controla, com locking, com organização, serialização de transações. E por fim, ela é durável, uma vez que termina minha transação, a informação está na minha base de dados. Então... No monolito, é muito fácil de nós controlarmos o sequenciamento dessas etapas, porque eu tenho uma transação no começo e no fim. Então, eu posso...
Como é que isso ficaria dentro de um Spring, por exemplo? A gente pode ter lá um método. Vai ter, por exemplo, public void place order. Eu vou ter aqui meu método.
E, normalmente, no Spring, a gente vai ter transactional, a anotação. dizendo que eu quero começar uma transação dentro desse método. Então, se eu pegar esse...
e colocar todas as minhas etapas aqui dentro posso ter por exemplo um inventório e service por exemplo e eu posso colocar reduce Stock coloco a quantidade que eu quero eu vou colocar em seguida o o meu payment e vou colocar por exemplo process payment e coloca aqui qual é o ID do meu pagamento então tudo que acontecer dentro desse processo transacional, se eu tiver uma falha no começo, toda a transação é desfeita. O rollback acontece de forma independente para a transação inteira. Então, vamos supor, por exemplo, que tenhamos aqui...
Deixa eu puxar isso aqui para cá. Vamos supor que tenhamos aqui um processo. Eu deduzo o meu estoque. Então, eu dou uma instrução na base de dados para deduzir o estoque.
congela o meu carrinho para não ter mais alteração, outra instrução na base de dados. Na hora que eu vou processar o pagamento, eu tenho uma falha nessa etapa. Se acontece uma falha nessa etapa, vai dar uma exception. Essa exception vai ser capturada naquele método com a anotação. E o rollback acontece de forma automática.
O próprio framework controla isso. Ele vai dar um rollback e vai desfazer todas as transações que estavam abertas. Então ele desfaz essa transação e desfaz essa transação.
Ele simplesmente não dá commit, ele dá rollback e a base de dados controla e desfaça. Então a probabilidade de termos inconsistência de informação é muito menor, porque no monolito tudo acontece de forma independente. Ou seja, dentro do monolito eu tenho as transações de forma atômica, esse é o conceito.
Todas as etapas ou todas as instruções SQL que são feitas por base de dados. elas são feitas de forma conjunta. Eu começo, dou begin transaction, executo uma série de transações e ao final eu decido se eu comito aquela transação ou se eu dou rollback.
Se eu tenho qualquer problema, eu dou rollback e aquela transação inteira, todas as transformações de estado que eu fiz na minha base, elas são revertidas. Isso funciona muito bem no monolito. Aí, por algum motivo, decidimos ir para microserviço.
No microserviço, nós temos uma característica importante, que é cada microserviço vai ter sua própria base de dados. Então, o serviço de inventário vai ter sua base, o serviço de carrinho vai ter a sua, payment e order. Nesse cenário, eu não posso contar com a transação da base de dados para garantir consistência. E é exatamente esse o começo da resposta da pergunta. Qual a principal diferença?
quando eu passo de monolito para microserviços. Do ponto de vista de transação, eu passo a ter o conceito de transação distribuída, ou distributed transaction. A minha transação não é mais autocontida dentro da transação da base de dados. Eu não tenho mais o meu framework controlando aquela transação do início ao fim. Não é mais um único método que faz tudo.
E se acontece um erro, eu pego a exception do rollback e está tudo ok. Num processo de microserviços, cada microserviço vai ter um pedacinho da responsabilidade. E quando ele vai executar, ele pode ter sucesso ou falha. E se ele tem uma falha, essa falha precisa ser identificada e propagada para os outros microserviços para que eles possam desfazer o que eles fizeram. É exatamente esse o conceito de transação distribuída.
Nós vamos explorar agora as duas principais formas mais comuns de se trabalhar com transação distribuída. Então, o que é importante? É garantir consistência.
Então, o que nós queremos aqui? Garantir que se eu tenho uma etapa que foi feita com sucesso, no processo de inventário eu consegui deduzir estoque, eu consegui congelar meu carrinho para ele não ser mais modificado, no momento de fazer o pagamento, se eu tenho uma falha, porque, por exemplo, o cartão de crédito foi negado, ou eu tenho alguma condição de pagamento que não é mais aceita, eu preciso desfazer essas duas etapas. E isso não acontece a nível de método.
Isso acontece a nível transacional ao longo do ecossistema de microserviços. Nós temos duas formas principais de controlarmos isso. As duas estão embutidas dentro do conceito de saga.
Elas têm uma particularidade, uma é orquestrada e a outra é independente. Nós vamos explorar no detalhe os dois agora. A primeira forma, a mais simples, por assim dizer, de controlar essa transação é através da orquestração.
Então, ao invés de eu fazer chamadas independentes, né, pra... mutar o estado das minhas bases aqui, eu coloco um orquestrador, vamos por exemplo chamar de Checkout Service, que vai ser o responsável por executar as transações e controlar o resultado de cada uma delas. Então eu recebo por exemplo aqui um post para fazer o Place Order, não é mais um único método, é uma sequência de chamadas HTTP que vão acontecer. Ele faz a primeira chamada para o essa chamada vem com sucesso, ele faz a segunda chamada por inventory, essa chamada vem com sucesso, ele faz a chamada por payment e ela falha.
E aí a falha aqui é bem no processo de HTTP. Eu faço uma chamada, um HTTP, eu recebo aqui um HTTP 200, eu vou chamar o meu payment e vou receber, por exemplo, um erro 500, teve um erro interno no processo de pagamento. Ou eu recebi um 400, um bad request, ou eu recebi mesmo um 200, só que com um processo de pagamento que foi negado. Então, o HTTP Code foi sucesso, eu consegui processar aquele request, mas o resultado desse processamento de pagamento foi um resultado de falha. Nesse caso, cabe ao orquestrador fazer o rollback daquelas transações.
Então, nesse caso, o que ele vai fazer? Ele vai pegar e vai solicitar agora para o inventory. Então, ele desfaz na ordem inversa.
É como se fosse uma pilha. Eu vou empilhando as etapas. Se eu tenho sucesso, eu concluo. Se eu tenho um processo de falha, eu solicito o cancelamento de todas as etapas.
Então, vamos supor que tivemos aqui uma falha no processo de pagamento. O orquestrador fala, bom, então eu preciso agora cancelar. o que eu fiz em todos os outros serviços.
Ele vai chamar o serviço de inventory, falando, ó, descongela ou devolve para o estoque aquele produto, não vai mais ser vendido, e ele vai para o serviço de carrinho e desfaz o processo de congelamento do carrinho ou ele devolve aquele produto para o carrinho. Então, ele tinha removido aquele produto do carrinho para ser constituído na order, ele devolve para o carrinho e devolve para o estoque. Então, O orquestrador é o responsável por garantir a consistência da informação.
Ele tem o estado de todas as transações feitas em cada um dos microserviços e ele vai solicitando ao longo de todas as etapas e ele pode confirmar ou cancelar. Tem um conceito um pouquinho mais complexo, que é o conceito de commit em duas fases, o two-phase commit. Não acho que precisamos entrar nesse cenário agora. Mas o que...
Esse corriqueiro também temos no processo de orquestração. A primeira chamada HTTP, ela não é uma chamada que efetivamente muta o estado do meu microserviço. Ele vai simplesmente informar o meu microserviço, congela para o carrinho, fica preparado para tirar esse produto do carrinho.
Então, a primeira etapa, a primeira chamada é uma chamada de preparação. se todas as chamadas de preparação vieram com sucesso, ou seja, todos os serviços conseguem executar aquela... O carrinho consegue ser congelado e remover o produto. O inventário consegue congelar o estoque.
O pagamento consegue processar, fazer uma pré-autorização. E o order gerar order. Se o orquestrador ver que todos são feitos com sucesso, ele vai lá e faz uma segunda chamada, dando commit. Executa efetivamente essa transação.
E aí ele se encerra. Ou, se no começo ele tem uma falha, Ele não vai comitar as transações, ele vai solicitar o rollback. Então, ele faz uma segunda chamada solicitando o rollback. Então, na orquestração, nós temos dois tipos de orquestração. O tipo 1, que é o mais simples, é a orquestração em que eu faço a chamada final, uma única chamada.
E se eu tenho algum problema, eu faço uma segunda chamada solicitando a reversão. Ou eu posso usar, no processo de orquestração, o conceito de two-phase commit, em que eu faço uma primeira chamada para preparar e uma segunda para comitar. Os principais problemas, então essa vai ser a primeira parte da resposta, eu posso usar a orquestração, provavelmente o entrevistador vai fazer um segundo conjunto de perguntas, que é, legal, mas e se eu tenho, num processo de resiliência, e se eu tenho um erro dentro da orquestração?
Ou seja, e se durante essa orquestração eu faço a primeira chamada para o cart e tenho sucesso, faço a segunda chamada para o inventory e tenho sucesso, Sucesso! E aí o orquestrador cai. Ou seja, quais são os cenários de falha durante o processo de execução ou de compensação? Quando eu tive uma falha e estou recuperando.
Aí, a resposta mais direta para esse cenário é o orquestrador vai passar a ter estado. Então, a gente pode adicionar aqui uma base de dados. Vou colocar aqui uma base de dados SQL para ele. Ela passa a ser a base responsável por...
acompanhar todo o processo de transação então o orquestrador vai ter como se fosse uma máquina de estado em que ele vai colocar aqui na base de dados dele dizendo ó eu preciso fazer cart inventory payment e order então ele já salva no banco todas as transações que ele precisa fazer com o status de pending então ele coloca aqui pendent pendente de execução o cart pendente de execução o inventory, pendente de execução o pagamento e a order. Então ele já salva os registros do que precisa ser feito e aí ele vai executando de forma independente. Então antes de começar efetivamente a executar a transação, ele já registra na sua base de dados que ele precisa fazer aquilo, comita e ele passa a executar cada um dos cenários.
Ele vai no cart, tenta solicitar para o cart fazer o congelamento, se teve sucesso... Ele vem aqui e troca de pending para, por exemplo, completed. Se ele teve sucesso, ele vai para o próximo. Ele vai para o inventory, troca de pending para completed.
Ele dá um update naquele registro. Vamos supor que depois que ele faz o inventory com sucesso, o inventário, ele tem uma falha. O pod, por exemplo, no Kubernetes aqui, ele quebra. Ou a VM dá shutdown, ou simplesmente ele quebra por algum motivo.
O que vai acontecer é que a base de dados vai estar com dois registros para aquela transação, para aquele ID de transação completado, completado e dois pendentes. A hora que o orquestrador se reinicia, seja porque a VM subiu de novo ou o pod foi restartado, ele precisa ter um processo de monitoramento em que ele vai passar, escanear o banco de dados inteiro verificando quais são as transações que foram interrompidas no meio. Então o orquestrador ele consegue se auto recuperar, self healing, no momento de ser iniciado. Então essa é a forma mais simples de garantir que no processo de falha, durante a orquestração, o próprio orquestrador consiga se recuperar. Tem outras formas, a gente pode, por exemplo, usar um message broker, colocando aqui knowledge no final de todas as transações, a gente pode colocar monitoramento, podemos até usar o processo de mensageria para controlar.
Mas não é necessário entrar nesse nível de detalhe, eu acho. Vai depender muito de como a entrevista se decorrer com o entrevistador. Mas simplesmente garantindo que o orchestrator tenha uma máquina de estado já é suficiente para ele conseguir se recuperar se ele tiver uma falha durante o processo de transação distribuída. Essa é uma forma, o principal problema no processo de orquestração com o orchestrator.
é que ele passa a ser o que a gente chama de single point of failure, que o pessoal chama de SPOF, SPOF, Single Point of Failure, ou seja, único ponto de falha. Então, se o orquestrador cai, a gente fica sem conseguir fazer check-out, enquanto ele não se recupera. Esse é o processo, é o principal problema de termos uma orquestração.
Ela é mais simples, no Saga, mas o ponto negativo é que você tem o single point of failure. Então, qualquer queda, na transação, ou qualquer queda naquele pote, a transação inteira fica comprometida. Uma alternativa do Saga, um pouco mais complexa, a orquestração, ou o segundo padrão Saga, é o padrão da coreografia.
A coreografia, ela tira o conceito de single point of failure, porque eu não vou ter mais um único serviço fazendo as chamadas para ter o processo distribuído. Agora a gente vai confiar num message broker. Então, ao invés de eu ter um único serviço, fazendo HTTP requests, faz um request, faz outro, faz outro, faz o sequenciamento, deu tudo certo, completa a transação, ou deu errado, eu faço chamadas para recuperar. Na coreografia, o processo é mais distribuído. Ele usa um message broker, pode ser um Kafka, pode ser um MQP, pode ser qualquer message bus.
Mas o grande trunfo aqui... da coreografia, é que agora cada serviço sabe de forma independente o que precisa ser feito para aquela transação. evoluir ao longo do tempo.
Então, lembrando, como é que é o sequenciamento que nós estamos fazendo? Primeiro eu chamo o cart, depois eu chamo o inventory, depois eu chamo o payment, e por fim eu chamo o order. Então, o que eu preciso fazer quando eu saio de orquestração para coreografia é falar para o inventory que ele precisa fazer alguma coisa depois que o carrinho é completado.
Eu preciso falar para o payment que ele precisa fazer alguma coisa. depois que o inventório é completado e para o order, que ele precisa fazer alguma coisa depois que o pagamento é completado. E tudo isso é disparado por meio de mensageria, por meio de mensagens dentro de um tópico.
Então, como é que funciona? O checkout faz uma chamada HTTP normal para o carrinho, para iniciar o processo, ele fala, carrinho, fecha esse pedido, fecha esse carrinho. Então, o cart tem uma única transação, um único processo que ele precisa fazer, que é dar o fechamento. do carrinho. Então ele congela o carrinho e tira aquele produto do carrinho.
Assim que ele conseguiu fazer aquilo com sucesso, ele vai postar uma mensagem, por exemplo, cart success. Uma mensagem bem simples, vou deixar a mais simples possível aqui. Então ele conseguiu completar o seu processo com sucesso, ele postou o cart success num tópico específico, por exemplo, de cart. O único serviço ouvindo esse tópico é o de inventory, porque só ele que se preocupa com o cart success, porque ele que é o que vai executar o próximo.
Então, o inventory está olhando aquele tópico, está ouvindo, ele tem um pub sub, ele assinou aquele tópico. Essa mensagem chegou no broker, foi lida pelo inventory. Setinha verde aqui, essa setinha. O inventory fala, bom, o carrinho foi feito com sucesso, eu posso iniciar o meu processamento agora. Então, o inventory vai lá e reduz do estoque.
aquela quantidade ele conseguiu fazer aquilo com sucesso né então foi uma ele completou com sucesso aquele processo ele ele vai postar agora uma mensagem inventório sucesso ele postou essa mensagem na fila é no tópico falando ó consegui completar a minha etapa aí o broker chegou aqui o próximo da fila lembrando o próximo nada no sequenciamento aqui do evento é o o payment então setinha azul o payment estava ouvindo aquele tópico recebeu aquela mensagem então a mensagem de inventório sucesso veio para cá chegou no payment o payment falou pô legal o inventário conseguiu reduzir estoque então agora é minha vez de tentar solicitar o pagamento ele solicita o pagamento conseguiu fazer o pagamento com sucesso ele vai postar aqui payment sucesso e ele vai pegar essa mensagem, postar na fila. O próximo serviço dentro do nosso sequenciamento da transação é o de order. Então, o Payment Success vem para cá, o order está ouvindo aquela mensagem, ele viu que o pagamento foi feito com sucesso e ele executa o seu processo.
Ele simplesmente pode postar alguma outra mensagem ou completar. Está tudo feito. Então, toda a transação distribuída aconteceu de forma coreografada. E aí eu gosto bastante de usar o conceito de coreografia e orquestração, porque eu acho que exemplifica bem o cenário do dia a dia.
No dia a dia, na orquestração, eu tenho um maestro numa orquestra. Então o maestro é quem vai ditar como as coisas vão acontecer, que no caso é o orchestrator, se ele poderia ser o maestro. E na coreografia, pensando numa dança, eu não tenho alguém... fazendo ali, dizendo como a pessoa tem que dançar.
Basicamente, todos os dançarinos estão juntos dançando de forma colaborativa e coreografada. Então, eles sabem exatamente o que precisa ser feito com base no que o outro está fazendo. Então, é como se fosse uma dança dentro de um palco.
Todo mundo sabe o que precisa ser feito com base no que todos os outros estão fazendo. O cenário de falha na coreografia. Então, vamos supor que... Vamos tirar as mensagens aqui. Vamos supor que o checkout solicitou, eu tive o inventory, foi tentar deduzir, ele conseguiu, ele postou o inventory success, veio aqui para o Kafka, aí o payment tentou fazer o pagamento e não conseguiu.
Então o payment, o que ele vai fazer agora, em vez de ele postar um payment success, ele vai postar um payment failure. E a grande diferença agora é que os tópicos de falha, eles são... ouvidos, ou seja, eles são assinados, subscritos por todos os serviços então, diferentemente no cenário de sucesso, em que somente o próximo serviço na transação ele ficava ouvindo aquela mensagem no processo de coreografia pra conseguir fazer a compensação de um cenário de falha eu preciso que todos os meus serviços fiquem ouvindo o tópico de falha, então o broadcast da falha, ele acontece para todo mundo. Então, o Payment Failure ele chama o Message Broker e o Message Broker vai postar a falha para todos.
Ele vai postar para o Inventory, vai postar para o Cart. Então, todos estão ouvindo os tópicos de falha. E aí, cada serviço vai fazer a sua própria compensação. O Order vai receber o Payment Failure, ele não precisa fazer nada, porque ele seria o próximo a executar alguma coisa.
Como ele não fez nada? Ele não tem nada para fazer, então ele não tem nenhuma compensação a ser feita, ele já está ok. O inventory recebe a mensagem e vai falar, putz, eu preciso fazer alguma coisa, teve falha no pagamento, eu preciso devolver o estoque.
Então ele vai fazer uma compensação no estoque. E o carrinho vai ver, putz, eu tive um pagamento de falha, uma falha naquele pagamento, eu preciso, com base naquele ID da transação, eu preciso devolver para o carrinho e descongelar o carrinho. Então, o carrinho vai lá e vai ouvir. Então, a grande diferença no cenário de falha é que agora a mensagem é via broadcast. Ela vai para todos os serviços e todos os serviços precisam fazer alguma coisa com aquela mensagem.
Às vezes, ele simplesmente vai ler e descartar, como é o caso do order, porque ele não fez nada ainda. Ou ele vai ler aquela mensagem e vai fazer um processo compensatório, que é o caso, por exemplo, do inventário e do carrinho. Ele precisa...
Devolver para o estoque e devolver para o carrinho aquele produto. Essa é a coreografia, é o processo de coreografia. Ele é muito baseado em mensageria. E aí, o que é importante citar, acho que a frase essencial no processo de entrevista ali, é dizer que tanto no saga orquestração quanto no saga coreografia, o que nós temos aqui é consistência eventual.
Essa é a palavra importante. No processo de saga, nós temos consistência eventual. O que significa que por alguns milissegundos ou até alguns segundos, eu vou ter os meus serviços dessincronizados. Então, por exemplo, enquanto o orchestrator está fazendo as chamadas, o meu carrinho pode ser que ele já congelou enquanto que o meu inventário ainda não deduziu o estoque.
Ou eu deduzi o estoque enquanto eu não cobrei. Então eu tenho, durante algum pedaço na minha linha do tempo, mesmo que seja muito curto, eu vou ter inconsistência. E tudo bem. A transação distribuída, ela ganha throughput, ela ganha a capacidade de ter mais requests acontecendo ao mesmo tempo, só que por consequência disso, eu não tenho mais a consistência, eu vou ter uma consistência eventual. Então, por alguns segundos ou milissegundos, meus serviços vão estar desincronizados, depois, ao longo do tempo, eles se sincronizam.
É a mesma coisa na coreografia. Enquanto os meus sistemas estão aqui lendo o meu tópico, eles podem estar dessincronizados. Mas, ao longo do tempo, eles passam a ficar consistentes. E aí, a próxima pergunta que pode acontecer dentro da entrevista, nós não temos agora mais single point of failure, porque agora tudo está sendo comunicado por mensageria.
Obviamente que se eu falho o checkout, eu falho o carrinho, o processo não acontece. mas ele não é mais um processo de orquestração. O que o entrevistador pode perguntar agora é, legal, mas o que pode dar errado no processo de coreografia? Se eu não tenho mais single point of failure, eu posso ter algum problema no envio das mensagens.
E sim, o que pode acontecer normalmente no processo de coreografia é um cenário de escrita dupla, o problema de escrita dupla. Porque aqui nós estamos fazendo... duas escritas, embora eu não tenha deixado muito claro aqui, quando nós fazemos, por exemplo, a dedução do estoque, nós estamos escrevendo na nossa base de dados, que é aquele estoque, eu estou dando um update na linha de estoque, então aqui, por exemplo, eu dei um update, estoque, set, estoque igual a 1, where, eu dei um update aqui, alterando o meu nível de estoque.
E, além disso, eu escrevi no broker, eu postei uma mensagem. Então, quando eu dou, por exemplo, aqui um inventory success, eu estou escrevendo na minha fila. Então, eu estou fazendo uma escrita dupla.
Eu estou escrevendo na minha base de dados, é a minha escrita número 1, e eu estou escrevendo na mensageria, é a escrita número 2. Quando eu tenho duas escritas... feitas pelo mesmo micro serviço para representar a mesma coisa, que eu estou atualizando o estoque, informando que eu atualizei o estoque, eu posso ter o conceito de dual write problem, que eu vou deixar para o próximo vídeo, para não ficar muito longo esse daqui. Mas esse é um cenário que pode acontecer, é importante citar. E aí para resolver o conceito de do or write problem, a gente pode usar snapshots ou usar a nossa base de dados para controlar a transação. Mas eu entrarei com mais detalhes e até falando os termos e as semânticas no próximo vídeo.
Eu acho que é isso. Em resumo, o que eu queria trazer para a pergunta mais comum que eu vejo em entrevistas é Como que eu garanto a consistência da informação em uma mudança de monolito para microserviço? A resposta tem que ser, quando eu vou para o microserviço, eu tenho transação distribuída. Por consequência, eu preciso ter algum processo de saga, padrão saga, para garantir consistência.
Eu posso ter orquestração, em que eu tenho um único serviço, ou posso ter coreografia. Se eu faço orquestração, eu vou ter um orchestrator, eu vou ter um único serviço controlando, ele é mais simples. Mas eu acabo adicionando um single point of failure. E aí para isso eu preciso ter uma state machine dentro do meu orchestrator. Para que se no processo de falha eu tenha self-healing.
Ele consiga pelo menos completar as transações que estavam pendentes. Se eu não quero ter o single point of failure. Eu posso ir para coreografia. Mas no processo de coreografia ele é um pouco mais complexo. Porque eu trabalho com mensageria.
Vou ter consistência eventual. Mas eu preciso me preocupar que eu posso ter o dual write problem. Nesse caso. Eu preciso controlar isso usando a minha base de dados para fazer os snapshots que vão ser postados na minha fila.
Então essa seria a resposta mais direta, quanto mais detalhes nós trouxermos a resposta melhor. Mas é isso. Boa sorte na sua entrevista.