| Bellacosa Mainframe apresenta microsserviços para programador cobol |
☕ Um Café no Bellacosa Mainframe
Microsserviços sem Mistérios para Programadores COBOL
Quando um Programador Descobre que Dividir um Monólito em Cinquenta Pedaços Não o Transforma Automaticamente em Arquitetura
O jovem programador caminhava lentamente pelo corredor do data center.
À esquerda, enormes gabinetes de mainframe piscavam com a serenidade de quem processava milhões de transações sem precisar publicar frases motivacionais no LinkedIn. À direita, servidores modernos executavam containers, APIs, pipelines, gateways, brokers, sidecars e outros pequenos animais digitais que aparentemente se multiplicavam quando ninguém estava olhando.
Em suas mãos, o aprendiz carregava um diagrama colorido chamado:
“How to Design Microservices”
Ele encontrou o velho Mestre Bellacosa sentado diante de um terminal 3270, segurando uma pequena xícara de café.
— Mestre — perguntou o aprendiz — finalmente compreendi os microsserviços. Basta pegar um programa grande, separá-lo em vários programas pequenos e colocá-los em containers.
O mestre tomou um gole de café.
Olhou para o jovem.
Olhou para o terminal.
Olhou novamente para o jovem.
— Pequeno gafanhoto — respondeu — se você cortar um elefante em cinquenta pedaços, não terá cinquenta animais independentes. Terá apenas um grande problema distribuído pelo chão.
O aprendiz permaneceu em silêncio.
Ao longe, ouviu-se o som de um job terminando com RC=0000.
E assim começou mais uma aula no Bellacosa Mainframe.
1. O que são microsserviços, afinal?
Microsserviços não são simplesmente programas pequenos.
Também não são:
containers;
APIs REST;
funções Java;
pods Kubernetes;
repositórios Git;
filas de mensagens;
aplicações hospedadas na nuvem.
Essas tecnologias podem participar de uma arquitetura de microsserviços, mas nenhuma delas, isoladamente, cria um microsserviço.
Um microsserviço é uma unidade de software construída em torno de uma responsabilidade clara do negócio.
Ele deve possuir, tanto quanto possível:
objetivo bem definido;
regras próprias;
dados sob seu controle;
interface conhecida;
equipe responsável;
ciclo de vida independente;
capacidade de ser implantado sem obrigar todo o sistema a mudar;
capacidade de falhar sem destruir a empresa inteira.
Para um programador COBOL iniciante, podemos comparar um microsserviço a um programa bem delimitado, mas com uma diferença importante: ele não vive apenas como uma rotina interna chamada por CALL.
Ele vive em um mundo distribuído.
Nesse mundo, a comunicação pode atravessar:
redes;
balanceadores;
APIs;
filas;
certificados;
gateways;
firewalls;
serviços de autenticação;
bancos distintos;
ambientes diferentes.
Uma simples chamada deixa de ser algo como:
CALL 'CALCJURO' USING WS-VALOR WS-TAXA WS-RESULTADO
e passa a ser algo parecido com:
Programa solicitante
↓
API Gateway
↓
Autenticação
↓
Serviço de cálculo
↓
Banco de dados
↓
Resposta pela rede
No programa COBOL local, se CALCJURO estiver disponível, a chamada acontece dentro do mesmo ambiente de execução.
No ambiente distribuído, tudo pode acontecer:
a rede pode estar lenta;
o DNS pode falhar;
o serviço pode estar reiniciando;
o certificado pode ter expirado;
o banco pode estar bloqueado;
a resposta pode chegar depois do timeout;
a operação pode ter sido concluída, embora o cliente não tenha recebido confirmação.
O primeiro ensinamento é simples:
Microsserviços não reduzem a complexidade. Eles transferem parte da complexidade do código para a comunicação, a infraestrutura e a operação.
2. Comece pelo negócio, não pelo programa
O primeiro passo mostrado no diagrama é:
Definir capacidades de negócio.
Esse é o fundamento de tudo.
Imagine um banco.
O banco precisa realizar capacidades como:
cadastrar clientes;
abrir contas;
receber depósitos;
efetuar transferências;
administrar cartões;
calcular limites;
detectar fraudes;
emitir cobranças;
produzir extratos.
Essas são capacidades que fazem sentido para o negócio.
Agora compare com uma divisão puramente técnica:
serviço de leitura de tabela;
serviço de gravação de arquivo;
serviço de validação;
serviço de impressão;
serviço de conversão de data;
serviço de cálculo de dígito.
Essas funções podem existir no sistema, mas não representam necessariamente serviços independentes.
O erro clássico de modernização acontece quando alguém analisa um ambiente legado e conclui:
— Temos 900 programas COBOL. Logo, criaremos 900 microsserviços.
Nesse momento, em algum lugar do universo, um arquiteto experiente derruba lentamente sua caneca.
Um programa COBOL pode ser:
um módulo reutilizável;
uma etapa de um job;
uma rotina de validação;
um programa de acesso a dados;
um programa online CICS;
um módulo chamado por dezenas de outros;
uma pequena parte de uma capacidade muito maior.
Transformar cada programa em serviço remoto pode substituir chamadas locais extremamente rápidas por centenas de interações de rede.
Aquilo que antes era:
PERFORM VALIDAR-CLIENTE
pode acabar virando:
Aplicação chama serviço de cliente
Serviço de cliente chama serviço de endereço
Serviço de endereço chama serviço de CEP
Serviço de CEP chama serviço de região
Serviço de região chama serviço tributário
Tudo isso apenas para descobrir que o campo WS-CEP está vazio.
O verdadeiro ponto de partida é perguntar:
O que a empresa realmente faz?
Quais funções entregam valor?
Quais regras mudam de forma independente?
Quais áreas possuem responsabilidades próprias?
Quais capacidades precisam escalar separadamente?
Quais processos podem falhar sem interromper os demais?
Curiosidade do templo
No Domain-Driven Design, uma capacidade empresarial costuma ser estudada dentro de um domínio.
Por exemplo:
Domínio: Comércio eletrônico
Pode conter subdomínios como:
Catálogo
Pedidos
Estoque
Pagamento
Entrega
Fidelidade
Cada domínio possui linguagem, regras e objetivos próprios.
Isso é muito diferente de dividir o sistema apenas por linguagem de programação, tabela ou tipo de arquivo.
3. Identifique os limites do serviço
O segundo passo é descobrir onde um serviço termina e o outro começa.
Esse limite é chamado de service boundary.
Considere a palavra “cliente”.
Para a área de vendas, cliente pode significar:
nome;
telefone;
preferências;
histórico comercial.
Para o setor financeiro, cliente pode significar:
documento;
limite;
inadimplência;
risco de crédito.
Para o setor de entrega, cliente pode significar:
nome do destinatário;
endereço;
instrução de recebimento.
São visões diferentes da mesma pessoa.
Não é obrigatório construir uma estrutura universal gigantesca contendo tudo o que todos os setores sabem.
No COBOL, essa estrutura poderia acabar assim:
01 CLIENTE-GLOBAL.
05 CLIENTE-DADOS-PESSOAIS.
05 CLIENTE-DADOS-FINANCEIROS.
05 CLIENTE-DADOS-LOGISTICOS.
05 CLIENTE-PREFERENCIAS.
05 CLIENTE-DADOS-FISCAIS.
05 CLIENTE-HISTORICO.
05 CLIENTE-CAMPOS-FUTUROS.
05 CLIENTE-CAMPOS-QUE-NINGUEM-SABE-PARA-QUE-SERVEM.
Depois de alguns anos, ninguém teria coragem de alterar esse copybook.
Cada serviço deve conhecer apenas a visão necessária para cumprir sua responsabilidade.
O serviço de entregas não precisa conhecer a renda do cliente.
O serviço de marketing não precisa conhecer o número completo do cartão.
O serviço de catálogo não precisa saber a situação de uma cobrança bancária.
Um bom limite reduz a quantidade de conhecimento compartilhado.
Sinal de limite ruim
Imagine um serviço chamado “Serviço Central”.
Ele:
cadastra cliente;
calcula preço;
reserva estoque;
processa pagamento;
emite nota;
envia e-mail;
agenda entrega;
atualiza pontos;
gera relatório;
consulta fraude.
O serviço possui uma API moderna, executa em container e aparece em um desenho cheio de hexágonos.
Mesmo assim, ele continua sendo um monólito.
A roupa mudou.
O imperador continua o mesmo.
4. Escolha a granularidade adequada
O terceiro passo é decidir o tamanho dos serviços.
Esse é um dos pontos mais difíceis porque não existe um número mágico.
Um microsserviço não precisa ter:
cem linhas;
mil linhas;
cinco classes;
uma tabela;
um endpoint.
O tamanho correto depende da responsabilidade.
Grande demais
Se o serviço cuida de várias capacidades distintas, ele começa a se transformar em outro monólito.
Sintomas:
várias equipes alteram o mesmo código;
o deployment é arriscado;
qualquer mudança exige testes enormes;
escalar uma função obriga escalar todas;
módulos internos ficam fortemente acoplados.
Pequeno demais
Se cada função mínima vira um serviço, surge uma explosão de componentes.
Podemos imaginar:
Serviço Valida CPF
Serviço Calcula Dígito do CPF
Serviço Remove Pontuação do CPF
Serviço Formata CPF
Serviço Verifica CPF Vazio
Serviço Registra CPF
Agora cadastrar uma pessoa requer uma peregrinação por seis serviços.
O mestre chama isso de:
A Técnica do Nanosserviço de Mil Cortes.
Nenhum corte parece fatal isoladamente, mas o sistema morre lentamente em latência, logs, pipelines e reuniões.
O custo real de cada serviço
Todo novo serviço precisa de:
código;
testes;
repositório;
pipeline;
documentação;
configuração;
logs;
métricas;
alertas;
controle de acesso;
certificados;
versionamento;
processo de deployment;
suporte;
tratamento de falhas;
equipe responsável.
Portanto, um serviço de 300 linhas pode gerar uma carga operacional muito maior do que um módulo COBOL de 20 mil linhas bem organizado.
Pergunta prática
Um serviço está em boa granularidade quando podemos dizer:
“Este componente é responsável por esta capacidade e pode evoluir sem exigir mudanças constantes em todo o restante.”
Não existe perfeição inicial.
Os limites podem evoluir à medida que o conhecimento sobre o negócio aumenta.
5. Projete a API como um contrato
Depois que as responsabilidades estão claras, precisamos definir como os serviços se comunicam.
A API é o contrato público do serviço.
Ela deve expressar ações de negócio, não detalhes internos de banco.
Exemplo ruim
POST /insertPedido
PUT /updateStatusPedido
GET /selectPedido
DELETE /deletePedido
Esse modelo simplesmente expõe operações de tabela.
É o equivalente digital de colocar uma janela na parede do banco de dados e deixar cada sistema meter a mão lá dentro.
Exemplo melhor
POST /pedidos
GET /pedidos/123
POST /pedidos/123/cancelamento
POST /pedidos/123/confirmacao
Essas operações representam intenções empresariais.
A API deve definir claramente:
formato da requisição;
formato da resposta;
campos obrigatórios;
códigos de erro;
autenticação;
autorização;
versionamento;
regras de repetição;
limites de consumo;
comportamento em falhas.
Idempotência
Esse nome estranho é essencial.
Imagine que uma aplicação solicite um pagamento.
Ela envia a requisição, mas a resposta demora.
O cliente não sabe se o pagamento foi processado.
Então envia novamente.
Sem idempotência, o usuário pode ser cobrado duas vezes.
Uma chave idempotente pode identificar a solicitação:
IDEMPOTENCY-KEY: PAGAMENTO-2026-0009981
Se o serviço receber a mesma chave novamente, devolve o resultado já registrado.
No mundo COBOL, pense em um identificador único de transação armazenado antes do processamento.
Antes de executar, o sistema verifica:
IF TRANSACAO-JA-PROCESSADA
RETORNAR-RESULTADO-ANTERIOR
ELSE
PROCESSAR-TRANSACAO
END-IF
Em sistemas distribuídos, isso não é luxo.
É sobrevivência.
6. Cada serviço deve possuir seus dados
O quinto passo do diagrama fala de data ownership.
Um serviço deve controlar os dados de sua responsabilidade.
Isso não significa necessariamente possuir uma máquina física exclusiva.
Significa que outros serviços não devem alterar diretamente suas estruturas internas.
Considere:
Serviço de Pedidos
Serviço de Pagamentos
Serviço de Estoque
Serviço de Entregas
Se todos acessarem e atualizarem as mesmas tabelas, qualquer mudança poderá afetar todos.
O banco compartilhado cria dependências ocultas:
uma coluna removida quebra outro serviço;
uma atualização direta ignora regras;
um relatório pesado afeta transações;
ninguém sabe quem é o dono da tabela;
todos precisam coordenar deployments.
O sistema pode ter vinte aplicações separadas, mas continuar sendo um monólito de banco de dados.
Estratégia recomendada
Pedidos controla pedidos
Pagamento controla cobranças
Estoque controla quantidades e reservas
Entrega controla remessas
Quando um serviço precisa de informação de outro, utiliza:
API;
mensagem;
evento;
réplica controlada;
cache;
visão materializada.
“Mas e o JOIN?”
O programador COBOL acostumado ao Db2 pergunta:
— Mestre, como faremos o JOIN?
O mestre responde:
— Com cuidado, pequeno gafanhoto.
Em microsserviços, os dados podem estar separados.
Um relatório consolidado pode usar:
data warehouse;
data lake;
modelo de leitura;
CQRS;
eventos;
réplica de consulta;
processo batch de consolidação.
Não é recomendável montar todo relatório corporativo chamando quinze APIs em tempo real.
Isso cria uma consulta que depende simultaneamente de quinze serviços.
Se um falhar, o relatório pode virar uma página branca contendo a mensagem:
“Erro inesperado. Tente novamente mais tarde.”
A mensagem oficial da era digital.
7. Comunicação síncrona e assíncrona
O sexto passo é escolher como os serviços conversam.
Comunicação síncrona
Um serviço envia uma solicitação e espera uma resposta.
Exemplos:
REST;
SOAP;
gRPC;
z/OS Connect;
chamadas via gateway.
Fluxo:
Cliente → Pedido → Estoque → Resposta
É útil quando a resposta é necessária naquele momento.
Por exemplo:
consultar saldo;
validar limite;
obter preço;
confirmar disponibilidade.
Mas há um risco.
Se A chama B, B chama C, C chama D e D chama E, temos uma corrente.
A → B → C → D → E
Todos precisam funcionar dentro do tempo esperado.
A latência se acumula.
As probabilidades de falha também.
O usuário clicou uma vez, mas o sistema realizou uma pequena expedição ao Himalaia.
Comunicação assíncrona
O serviço publica uma mensagem e continua.
Exemplo:
PedidoCriado
↓
IBM MQ, Kafka ou outro broker
├── Estoque
├── Pagamento
├── Notificação
└── Fidelidade
Isso permite desacoplamento.
O serviço de pedidos não precisa esperar que o e-mail seja enviado para confirmar o pedido.
A notificação pode ocorrer alguns segundos depois.
A mensageria também ajuda a absorver picos.
Se chegam dez mil pedidos, a fila pode armazená-los enquanto os consumidores processam gradualmente.
Comando e evento
Um comando solicita uma ação:
ReservarEstoque
Um evento declara um fato:
EstoqueReservado
Essa diferença é importante.
O comando pode falhar ou ser recusado.
O evento representa algo que já ocorreu.
Easter egg do mainframe
Programadores mainframe já trabalham com ideias semelhantes há décadas:
MQ;
filas;
processamento batch;
desacoplamento;
checkpoints;
reprocessamento;
arquivos de entrada e saída;
controle de transação.
Muitas práticas apresentadas como descobertas revolucionárias da computação moderna estavam tranquilamente funcionando em data centers quando os atuais evangelistas de cloud ainda assistiam desenho animado em televisão de tubo.
8. Falhas devem ser previstas
O sétimo passo é tratar falhas desde o início.
Em um programa local, muitos componentes vivem no mesmo ambiente.
Em microsserviços, a rede é parte do sistema.
E a rede possui um senso de humor sombrio.
Timeout
Toda chamada remota precisa de um limite.
Sem timeout, o programa pode esperar indefinidamente.
Exemplo:
Serviço de pedido chama pagamento
Pagamento não responde
Após dois segundos, a chamada é encerrada
O timeout precisa ser escolhido com base em dados reais.
Muito curto:
operações válidas são canceladas.
Muito longo:
recursos ficam presos;
usuários aguardam;
filas de threads se acumulam.
Retry
O retry tenta novamente uma operação temporariamente falha.
Pode funcionar para:
erro de rede;
serviço temporariamente indisponível;
timeout transitório;
resposta 503.
Não deve ser usado para:
senha inválida;
saldo insuficiente;
documento incorreto;
regra de negócio rejeitada;
mensagem malformada.
Tentar novamente uma operação impossível é apenas falhar com dedicação.
Backoff e jitter
As tentativas não devem ocorrer todas imediatamente.
Podemos esperar:
500 milissegundos
1 segundo
2 segundos
4 segundos
O jitter adiciona uma variação aleatória.
Sem isso, milhares de clientes podem repetir ao mesmo tempo e esmagar o serviço que estava tentando se recuperar.
Circuit breaker
O circuit breaker interrompe chamadas para um serviço que está falhando.
Estados comuns:
CLOSED
OPEN
HALF-OPEN
Quando fechado, chamadas passam.
Quando aberto, chamadas são bloqueadas rapidamente.
No estado semiaberto, algumas chamadas de teste verificam se houve recuperação.
Pense em um disjuntor elétrico.
Ele não discute filosofia com o curto-circuito.
Ele interrompe a corrente.
Fallback
O fallback fornece alternativa:
cache;
informação parcial;
resposta padrão segura;
fila para processamento posterior.
Mas o fallback não pode inventar dados críticos.
Se o saldo não está disponível, o sistema não deve escolher um valor aleatório apenas para manter a experiência “fluida”.
9. Sagas e transações distribuídas
No mainframe, estamos acostumados com transações fortes.
Uma unidade de trabalho pode terminar com:
COMMIT
ou:
ROLLBACK
Em microsserviços, uma transação pode atravessar vários bancos.
Exemplo:
Criar pedido;
Reservar estoque;
Cobrar pagamento;
Criar entrega.
Se o pagamento falhar depois da reserva, o que acontece?
Uma solução é usar o padrão Saga.
Cada etapa possui uma ação e, quando necessário, uma compensação.
Criar pedido
Reservar estoque
Pagamento falhou
Liberar estoque
Cancelar pedido
A compensação não apaga magicamente o passado.
Ela executa uma nova operação que neutraliza o efeito anterior.
Por exemplo:
débito realizado;
transferência cancelada;
crédito compensatório efetuado.
Isso exige regras claras.
A palavra “desfazer” parece simples até envolver:
dinheiro;
estoque;
impostos;
nota fiscal;
transporte;
auditoria.
10. Observabilidade: enxergar o sistema
O oitavo passo é adicionar observabilidade.
Em um monólito, podemos investigar:
um log;
um dump;
uma região CICS;
um job;
uma tabela;
um programa.
Em microsserviços, uma requisição pode atravessar dezenas de componentes.
Precisamos de:
logs;
métricas;
traces.
Logs
Um log útil deve informar:
data e hora;
serviço;
operação;
identificador da transação;
resultado;
tempo;
erro;
ambiente.
Um log inútil diz:
Ocorreu um erro.
Esse tipo de mensagem possui a precisão investigativa de um oráculo gripado.
Métricas
Métricas respondem perguntas como:
quantas requisições chegaram?
qual a latência média?
quantas falharam?
quantos timeouts ocorreram?
qual a profundidade da fila?
quantas mensagens aguardam processamento?
quantos circuit breakers estão abertos?
Tracing distribuído
Um trace acompanha a jornada de uma solicitação.
Gateway: 20 ms
Pedido: 40 ms
Estoque: 80 ms
Pagamento: 950 ms
Notificação: 25 ms
Agora podemos localizar o gargalo.
Sem um correlation ID, investigar um problema distribuído é como procurar um job no JES2 sabendo apenas que ele “rodou na terça-feira”.
Observabilidade empresarial
Não basta saber que CPU e memória estão normais.
Devemos observar:
pedidos concluídos;
pagamentos recusados;
transferências pendentes;
reservas expiradas;
mensagens em dead-letter queue;
divergências de conciliação.
O sistema pode estar tecnicamente perfeito e comercialmente inútil.
Todos os containers verdes.
Nenhuma venda concluída.
11. Segurança em todos os serviços
O nono passo é proteger cada serviço.
Não podemos confiar automaticamente em tudo que está dentro da rede.
A segurança deve considerar:
autenticação;
autorização;
criptografia;
segredos;
comunicação entre serviços;
privilégio mínimo.
Autenticação
Responde:
Quem é você?
Autorização
Responde:
O que você pode fazer?
Uma pessoa autenticada não deve automaticamente poder:
alterar limites;
consultar qualquer conta;
cancelar transferências;
acessar dados administrativos.
Identidade entre serviços
Serviços também precisam se identificar.
Podem usar:
certificados;
mTLS;
tokens;
contas de serviço;
scopes;
políticas de rede.
Gestão de segredos
Nunca devemos guardar senhas e tokens:
no código;
em repositórios;
em imagens de container;
em logs;
em arquivos abertos;
em variáveis sem proteção.
No universo mainframe, isso se relaciona com:
RACF;
SAF;
perfis;
certificados;
keystores;
controle de datasets;
privilégio mínimo.
Regra do templo
O serviço de notificações não precisa atualizar conta bancária.
O serviço de catálogo não precisa consultar cartão.
O serviço de entrega não precisa acessar dados de fraude.
Cada serviço deve possuir apenas os acessos necessários.
12. Automação de deployment
O décimo passo é automatizar a entrega.
Microsserviços aumentam o número de componentes.
Sem automação, cada deployment vira uma cerimônia.
Imagine cinquenta serviços exigindo:
cópia manual;
mudança de parâmetro;
abertura de chamado;
autorização;
teste manual;
atualização de planilha;
conferência por e-mail;
reunião de aprovação.
A empresa não criou agilidade.
Criou cinquenta pequenas repartições públicas digitais.
Pipeline típico
Commit
↓
Build
↓
Teste unitário
↓
Análise de qualidade
↓
Análise de segurança
↓
Teste de contrato
↓
Empacotamento
↓
Homologação
↓
Teste integrado
↓
Produção
↓
Verificação
Deployment independente
Um serviço deve poder ser implantado sem exigir publicação simultânea de todos os outros.
Se cinco serviços sempre precisam mudar juntos, o acoplamento continua forte.
Eles apenas moram em apartamentos diferentes, mas ainda compartilham o mesmo banheiro.
Estratégias
Rolling
Substitui instâncias gradualmente.
Blue-green
Mantém dois ambientes:
Blue: versão atual
Green: nova versão
Depois da validação, o tráfego muda.
Canary
Uma pequena parcela recebe a nova versão.
5% nova
95% antiga
Se tudo estiver bem, a nova versão avança.
Banco de dados e rollback
Código pode voltar rapidamente.
Banco de dados nem sempre.
Por isso, mudanças de schema devem acontecer em etapas.
Um padrão útil é:
adicionar nova estrutura;
manter compatibilidade;
atualizar aplicações;
migrar dados;
remover estrutura antiga posteriormente.
Esse padrão é conhecido como expand and contract.
13. Microsserviços e COBOL podem viver juntos
Uma das maiores confusões é pensar que microsserviços exigem substituir COBOL.
Não exigem.
Um programa COBOL pode ser exposto ou integrado por:
CICS;
IMS;
IBM MQ;
z/OS Connect;
APIs REST;
eventos;
Kafka;
adaptadores;
pipelines CI/CD;
OpenAPI.
Uma transação CICS bem definida pode funcionar como serviço empresarial.
Ela pode possuir:
entrada conhecida;
saída conhecida;
regra delimitada;
segurança;
transação;
alta disponibilidade;
auditoria;
monitoramento.
Em alguns casos, uma transação COBOL possui limites mais claros do que uma aplicação moderna dividida artificialmente em dezenas de containers.
Padrão Strangler Fig
Uma estratégia segura de modernização é envolver o legado e substituir partes gradualmente.
Usuário
↓
Camada de APIs
↓
Sistema legado + novos serviços
Com o tempo, determinadas capacidades são extraídas.
O tráfego passa gradualmente para os novos componentes.
Não é necessário desligar o mainframe em uma sexta-feira às 18h e esperar que tudo funcione na segunda-feira.
Essa estratégia normalmente termina com:
pizza fria;
executivos nervosos;
consultores desaparecidos;
e um programa COBOL sendo religado às três da manhã.
14. Passo a passo para um projeto real
O jovem aprendiz perguntou:
— Mestre, como começo sem transformar a empresa em um laboratório de caos?
O mestre respondeu:
Passo 1 — Mapear o negócio
Liste processos reais:
pedidos;
pagamentos;
cadastro;
faturamento;
entrega;
atendimento.
Não comece pelas tabelas ou programas.
Passo 2 — Descobrir responsabilidades
Para cada processo, determine:
quem decide?
quem possui as regras?
quem altera?
quem utiliza os dados?
quem responde pela operação?
Passo 3 — Mapear sistemas atuais
Identifique:
programas COBOL;
transações CICS;
jobs;
tabelas Db2;
arquivos VSAM;
filas MQ;
interfaces;
dependências.
Passo 4 — Escolher uma capacidade pequena, mas relevante
Evite começar pelo processo mais crítico da empresa.
Escolha algo:
com limites claros;
risco controlado;
valor perceptível;
poucas dependências.
Passo 5 — Criar contrato
Defina:
API;
mensagens;
erros;
autenticação;
versionamento;
idempotência.
Passo 6 — Definir propriedade dos dados
Determine:
quais dados pertencem ao serviço;
como serão migrados;
como outros consumidores terão acesso;
como evitar atualizações diretas.
Passo 7 — Planejar falhas
Pergunte:
o que acontece se o serviço parar?
o que acontece se a mensagem duplicar?
o que acontece se a resposta atrasar?
como reprocessar?
como compensar?
como recuperar?
Passo 8 — Instrumentar
Inclua desde o início:
logs estruturados;
métricas;
traces;
alertas;
correlation ID.
Passo 9 — Automatizar
Crie pipeline de:
build;
teste;
segurança;
deployment;
rollback;
validação.
Passo 10 — Medir resultados
Verifique se realmente melhorou:
tempo de entrega;
frequência de deployment;
número de falhas;
tempo de recuperação;
acoplamento;
satisfação da equipe;
custo operacional.
Não aceite sucesso apenas porque o diagrama ficou bonito.
15. Sinais de que o caminho está errado
Observe os seguintes sintomas:
Todos os serviços são implantados juntos
Isso indica dependência excessiva.
Todos usam o mesmo banco
A independência pode ser apenas visual.
Uma operação simples chama dezenas de serviços
A granularidade provavelmente está pequena demais.
Ninguém sabe quem é o responsável
Serviço sem dono vira ruína digital.
Qualquer mudança quebra consumidores
O contrato está instável.
Há retries sem limite
Uma pequena falha pode virar tempestade.
Não existe correlation ID
O suporte trabalhará por adivinhação.
Existem muitos serviços e poucas equipes
A operação ficará abandonada.
Kubernetes foi instalado antes de compreender o domínio
O projeto começou pelo telhado.
16. Quando não usar microsserviços
O aprendiz esperava uma defesa absoluta.
Mas o mestre surpreendeu:
— Nem todo sistema precisa de microsserviços.
Um monólito modular pode ser melhor quando:
a equipe é pequena;
o produto está começando;
o domínio ainda não é conhecido;
a infraestrutura é limitada;
o volume é moderado;
todas as partes mudam juntas;
não existe maturidade operacional.
Um monólito modular oferece:
transações locais;
debugging mais simples;
menor custo;
testes mais diretos;
menos falhas de rede;
deployment único;
operação centralizada.
O problema não é o monólito.
O problema é o monólito desorganizado.
Da mesma forma, o mérito não está nos microsserviços.
O mérito está nos serviços bem delimitados.
Um monólito bem construído pode ser elegante.
Um conjunto de microsserviços mal construído pode parecer uma cidade em que cada cômodo da casa possui prefeitura, alfândega e controle de passaporte.
17. Curiosidades e easter eggs do templo
Easter egg 1 — “Novo” nem sempre é novo
Mensageria, transações, isolamento, filas e processamento distribuído existem há décadas em ambientes corporativos.
O vocabulário mudou.
Os problemas continuam reconhecíveis.
Easter egg 2 — O mainframe já conhecia resiliência
CICS, IMS, MQ, RACF, WLM, sysplex e outros componentes foram construídos para:
disponibilidade;
segurança;
recuperação;
gerenciamento de carga;
integridade transacional.
O microsserviço moderno não inventou a necessidade de sobrevivência em produção.
Easter egg 3 — O verdadeiro monólito distribuído
Quando todos os serviços:
compartilham banco;
mudam juntos;
dependem uns dos outros;
falham em cadeia;
pertencem à mesma equipe;
temos um monólito distribuído.
Ele possui todas as dificuldades do monólito e todas as dificuldades da rede.
Uma obra-prima do sofrimento híbrido.
Easter egg 4 — A lei do café
Quanto maior a cadeia de serviços, maior a probabilidade de o operador precisar preparar café antes de terminar o trace.
Essa lei ainda aguarda validação acadêmica, mas já foi confirmada empiricamente em milhares de data centers.
Conclusão — A lição do pequeno gafanhoto
O jovem programador fechou o diagrama.
Agora compreendia que microsserviços não eram apenas caixas coloridas conectadas por flechas.
Eles exigiam decisões profundas sobre:
negócio;
limites;
responsabilidade;
dados;
comunicação;
falhas;
segurança;
observabilidade;
deployment;
equipes.
O mestre Bellacosa levantou-se e caminhou até o mainframe.
— Pequeno gafanhoto — disse ele — o objetivo não é criar mais serviços.
— Então qual é o objetivo, mestre?
— Criar partes do sistema que possam compreender sua própria missão, carregar seus próprios dados, falar claramente com as demais e sobreviver quando o mundo ao redor estiver falhando.
O jovem refletiu.
— E como saberei se projetei corretamente?
O mestre apontou para o terminal.
— Quando uma equipe puder modificar uma capacidade, testá-la, implantá-la e recuperá-la sem convocar cinquenta pessoas para uma reunião de emergência, você estará próximo do caminho.
— E se eu dividir tudo em serviços pequenos?
— Você terá muitos serviços pequenos.
— E isso não é microsserviço?
— Não necessariamente.
— E se eu usar containers?
— Terá containers.
— Kubernetes?
— Terá Kubernetes.
— APIs?
— Terá APIs.
— Cloud?
— Terá uma fatura mensal muito interessante.
O aprendiz finalmente sorriu.
Na tela, o sistema registrou:
MICROSERVICE DESIGN TRAINING
STATUS: COMPLETED
RETURN CODE: 0000
Mas antes que ele comemorasse, surgiu uma segunda mensagem:
WARNING:
PRODUCTION IS A DISTRIBUTED SYSTEM.
EXPECT THE UNEXPECTED.
O mestre terminou o café.
O jovem observou as luzes do data center.
E, em algum lugar entre uma transação CICS, uma fila MQ, uma API REST e um container perdido no cluster, ele finalmente compreendeu:
Uma boa arquitetura de microsserviços não nasce quando dividimos o sistema em pedaços. Ela nasce quando compreendemos quais pedaços realmente possuem motivo para existir de forma independente.
E esse, caro Padawan do COBOL, é o primeiro golpe da antiga arte de projetar sistemas distribuídos sem transformar a produção em um episódio perdido de Kung Fu, dirigido por um arquiteto, revisado por um monge e patrocinado pelo departamento de incidentes críticos.