Acervo original preservado
Este conteúdo histórico pode conter propostas ou instruções anteriores ao checkout atual. Consulte Arquitetura para o comportamento documentado e Tutoriais para as ressalvas operacionais.
Ambiente local e propostas experimentais — sem adoção corporativa
Istio e Kubernetes Gateway API citados neste acervo são experimentos exclusivos do ambiente local. Recomendações históricas não representam decisões aprovadas nem a exposição oficial de DEV, STAGING ou PROD. Helm e Helmfile são ferramentas locais. Consulte Estudos e experimentos.
Alias amigável para tenant no Gateway¶
1. Contexto¶
Atualmente, o acesso às rotas do gateway é realizado via subdomínio baseado no tenantId, no formato:
{tenantId}.gateway.totvs.app
O tenantId é um UUID4, o que gera problemas de:
- baixa legibilidade
- dificuldade de uso por usuários finais
- baixa aderência a padrões de mercado (ex:
empresa-x.api.com)
Objetivo¶
Permitir que o usuário defina um alias amigável para o tenant, possibilitando acesso via:
{alias}.gateway.totvs.app
Exemplo:
acme.gateway.totvs.app → tenantId: 507f1f77bcf86cd799439011
2. Problema¶
A resolução de alias requer:
- leitura dinâmica de dados (base persistida)
- baixa latência (executa no data plane)
- consistência eventual aceitável
- alta frequência de leitura
Ou seja, não é apenas um problema de DNS ou roteamento — é um problema de resolução de identidade multi-tenant em tempo de requisição.
3. Opções de Arquitetura¶
3.1 Resolver via Proxy dedicado (Go + cache em memória)¶
Descrição
- Criar um microserviço proxy antes do
security-checker - Mantém um mapa
alias → tenantIdem memória - Atualizações via RabbitMQ + sincronização periódica
- Reescreve a URI antes de encaminhar
Vantagens
- separação clara de responsabilidade
- pode ser reutilizado por outros serviços
Desvantagens
- adiciona latência (novo hop), baixo impacto
- aumenta complexidade operacional
- duplicação de lógica de cache/invalidação
- dificulta debugging (reescrita implícita de URI)
Conclusão:
Não recomendado — custo maior que o benefício.
3.2 Resolver via Envoy / Gateway API / Ingress¶
Descrição
- Configurar resolução de alias diretamente na camada de rede
- Atualizar dinamicamente mapeamentos no proxy
Vantagens
- resolução antecipada (na borda)
- reduz carga nos microserviços
Desvantagens
- alta complexidade (config dinâmica, xDS, sync)
- acopla regra de negócio à infraestrutura
- difícil manter consistência com banco de dados
- difícil observabilidade
Conclusão:
Não recomendado — problema não é de roteamento, é de domínio.
3.3 Resolver no gateway-security-checker (sem cache distribuído)¶
Descrição
- Resolver alias diretamente no checker
- Cache local em memória por instância
- fallback direto para MongoDB
Vantagens
- simples de implementar
- sem novas dependências
- regra próxima do domínio de segurança
Desvantagens
- miss impacta banco
- inconsistência entre instâncias possível
Conclusão:
Boa para primeira versão (MVP).
3.4 Resolver no gateway-security-checker com cache distribuído (Recomendado)¶
Descrição
- Resolução feita no checker
- cache em múltiplos níveis:
- arquivo em volume (hot path)
- MongoDB (fonte de verdade)
Vantagens
- baixa latência
- escalável horizontalmente
- consistente entre instâncias
- simples operacionalmente comparado a proxy/envoy
Desvantagens
- requer Redis
- lógica de cache mais elaborada
Conclusão:
Opção recomendada
3.5 Resolver no gateway-security-checker utilizando volume persistente como cache compartilhado¶
Descrição
- Resolver alias diretamente no
gateway-security-checker - Utilizar um arquivo em volume persistente como cache compartilhado entre instâncias
- Manter MongoDB como fonte de verdade
- Atualizar o arquivo a partir de eventos ou sincronização periódica
Vantagens
- evita introdução do Redis como nova dependência
- pode parecer mais simples operacionalmente em uma primeira análise
- permite manter um snapshot local dos aliases
- pode ser útil como mecanismo auxiliar de recuperação
Desvantagens
- volume persistente não é um cache distribuído
- concorrência entre múltiplas réplicas exige controle de lock
- risco de leitura de arquivo parcialmente atualizado
- maior complexidade para invalidação consistente
- latência de I/O tende a ser maior que Redis/memória
- comportamento depende do tipo de storage utilizado no Kubernetes
- pode se tornar gargalo em cenários de alta leitura
- dificulta observabilidade de hit/miss e tempo de resolução
- adiciona acoplamento entre aplicação e filesystem compartilhado
Conclusão
Não recomendado como cache principal.
Apesar de reduzir uma dependência externa, o uso de volume persistente troca um problema conhecido e bem suportado por Redis por uma solução mais frágil para ambiente distribuído.
O volume persistente pode ser considerado apenas como mecanismo auxiliar, por exemplo, para manter um snapshot local de emergência caso Redis e MongoDB estejam temporariamente indisponíveis.
Para o fluxo principal de resolução de alias, a abordagem recomendada continua sendo:
- cache local em memória
- Redis como cache distribuído
- MongoDB como fonte de verdade
Essa combinação atende melhor aos requisitos de baixa latência, alta frequência de leitura, escala horizontal e consistência eventual aceitável.
4. Arquitetura Recomendada¶
Fluxo de resolução¶
-
Request chega com host:
acme.gateway.totvs.app -
Extrair subdomínio:
acme -
Resolver:
- se for UUID4 → usar direto
- senão:
- volume persistente
- MongoDB (através de microserviço)
-
Injetar no contexto:
x-tenant-id: 507f1f77bcf86cd799439011 x-tenant-alias: acme -
Continuar fluxo normal
5. Estratégia de Cache¶
5.1 Modelo de cache em camadas¶
| Camada | Função |
|---|---|
| Memória | acesso ultra rápido |
| Redis | compartilhamento global |
| MongoDB | fonte de verdade |
5.2 Fluxo de leitura¶
1. cache local
2. Redis
3. Mongo
4. popular Redis + cache local
5.3 Estratégia de invalidação¶
Evento via RabbitMQ¶
- evento:
tenant-alias.updated - payload:
{
"alias":"acme",
"tenantId":"507f1f77bcf86cd799439011",
"action":"UPDATED"
}
Comportamento¶
- atualizar Redis
- invalidar cache local
5.4 TTL sugerido¶
| Camada | TTL sugerido |
|---|---|
| Memória | 5 minutos |
| Redis | 15 minutos ou sem TTL |
6. Modelagem de Dados¶
Collection: tenant_aliases¶
{
"_id":"ObjectId",
"alias":"acme",
"tenantId":"507f1f77bcf86cd799439011",
"enabled":true,
"createdAt":"2026-04-16T10:00:00Z",
"updatedAt":"2026-04-16T10:00:00Z"
}
Regras obrigatórias¶
Unicidade¶
aliasdeve ser único globalmente
Normalização¶
- lowercase
- trim
Charset permitido¶
[a-z0-9]
Restrições¶
- não permitir:
www,admin,api,doc
- evitar conflito com UUID4:
- bloquear alias com formato de UUID4 sem hifens
7. Decisão de Design¶
Não reescrever URI como regra principal¶
Em vez disso:
- Resolver identidade
- Propagar via header
Headers internos¶
x-tenant-id
x-tenant-alias
x-original-host
Benefícios¶
- melhor observabilidade
- debugging mais simples
- menor acoplamento
- mantém contexto original
8. Observabilidade¶
Logs recomendados¶
{
"originalHost":"acme.gateway.totvs.app",
"alias":"acme",
"tenantId":"507f...",
"resolutionSource":"redis",
"resolutionTimeMs":2
}
Métricas¶
- cache hit/miss (local e Redis)
- tempo de resolução
- erros de alias não encontrado
- fallback para Mongo
9. Riscos e Mitigações¶
| Risco | Mitigação |
|---|---|
| cache inconsistente | evento + TTL |
| alias não encontrado | fallback Mongo + validação |
| conflito alias/UUID | validação no cadastro |
| alta latência em miss | Redis |
| crescimento da base | cache lazy (não preload total) |
10. Conclusão¶
A resolução de alias é um problema de identidade multi-tenant, não de roteamento.
A melhor abordagem é:
- Resolver no
gateway-security-checker - Usar cache em múltiplos níveis
- Manter Mongo como fonte de verdade
- Utilizar eventos para consistência
Evitar:
- proxies adicionais
- lógica no ingress/envoy
- reescrita implícita de URI