10 KiB
Especificação do Formato de Serialização
1. Visão Geral
Este documento descreve as estratégias de serialização para a comunicação entre processos no sistema de simulação de tráfego distribuído. A serialização é necessária para transmitir objetos Java através de sockets entre diferentes processos (cruzamentos, coordenador, dashboard).
2. Requisitos
2.1 Objetos a Serializar
Os principais objetos que precisam ser serializados são:
- Vehicle: Contém estado completo do veículo (id, tipo, rota, métricas)
- Message: Container para todas as mensagens entre processos
- Estatísticas: Dados agregados dos cruzamentos e semáforos
2.2 Requisitos Funcionais
- Integridade: Todos os dados devem ser preservados durante a serialização/desserialização
- Compatibilidade: Suporte para evolução de classes (adicionar campos)
- Performance: Latência mínima para não impactar a simulação
- Depuração: Capacidade de inspecionar mensagens facilmente
2.3 Requisitos Não-Funcionais
- Tamanho da mensagem otimizado
- Fácil manutenção e extensibilidade
- Compatibilidade com ferramentas de monitorização
3. Comparação: Java Serialization vs JSON
3.1 Java Serialization
Vantagens ✅
-
Nativo do Java
- Sem dependências externas
- Suporte built-in na JVM
- Integração direta com Serializable
-
Preservação de Tipos
- Mantém tipos Java exatos
- Serializa grafo completo de objetos
- Suporte automático para herança
-
Performance de Escrita
- Serialização binária mais rápida
- Menos overhead de conversão
- ObjectOutputStream otimizado
-
Facilidade de Implementação
- Basta implementar Serializable
- Controle fino com serialVersionUID
- Métodos customizados: writeObject/readObject
Desvantagens ❌
-
Acoplamento Java
- Apenas entre aplicações Java
- Dificulta interoperabilidade futura
- Formato proprietário
-
Tamanho das Mensagens
- Formato binário verboso
- Inclui metadata de classes
- 2-3x maior que JSON compacto
-
Depuração Difícil
- Formato binário não legível
- Necessita ferramentas especiais
- Difícil inspecionar mensagens
-
Problemas de Segurança
- Vulnerabilidades conhecidas (CVEs)
- Desserialização insegura
- Necessita validação cuidadosa
-
Evolução de Classes
- serialVersionUID requer gestão manual
- Quebra compatibilidade facilmente
- Difícil manter versões diferentes
Métricas Estimadas
Tamanho Médio: 400-600 bytes (Vehicle completo)
Latência: 0.5-1ms (serialização + rede local)
Throughput: ~10,000 msgs/s
3.2 JSON (com Gson/Jackson)
Vantagens ✅
-
Legibilidade Humana
- Formato texto simples
- Fácil depuração
- Inspecionável com ferramentas comuns
-
Interoperabilidade
- Padrão universal
- Facilita integração futura
- Dashboard web, APIs, etc.
-
Tamanho Otimizado
- Formato compacto
- ~40% menor que Java Serialization
- Compressão opcional (gzip)
-
Evolução Flexível
- Campos opcionais nativos
- Backward/forward compatibility
- Versionamento natural
-
Ferramentas e Ecossistema
- Bibliotecas maduras (Gson, Jackson)
- Validação com JSON Schema
- Suporte a logs estruturados
-
Segurança
- Sem execução de código
- Validação mais simples
- Menos vetores de ataque
Desvantagens ❌
-
Dependência Externa
- Necessita biblioteca (Gson/Jackson)
- Aumenta tamanho do JAR
- Possível quebra de dependência
-
Performance de Conversão
- Parsing de texto
- Reflexão Java
- ~20-30% mais lento que binário
-
Tipos Perdidos
- Necessita type hints
- Problemas com genéricos
- Enums requerem atenção
-
Memória
- String temporárias
- Maior uso de heap
- GC mais frequente
Métricas Estimadas
Tamanho Médio: 250-350 bytes (Vehicle completo)
Latência: 0.8-1.5ms (conversão + rede local)
Throughput: ~8,000 msgs/s
4. Decisão e Recomendação
4.1 Análise de Contexto
Características do Projeto:
- Sistema distribuído Java-only (curto prazo)
- Comunicação intra-rede local (baixa latência)
- Volume moderado de mensagens (~100-1000/s)
- Necessidade de depuração durante desenvolvimento
- Potencial expansão futura (dashboard web)
4.2 Recomendação: JSON (Gson)
Justificativa
-
Desenvolvimento e Depuração 🔍
- A fase atual do projeto requer debugging extensivo
- JSON facilita inspeção de mensagens
- Logs legíveis sem ferramentas especiais
-
Manutenibilidade 🔧
- Mais fácil para equipe aprender/modificar
- Evolução de protocolo mais simples
- Menos problemas de compatibilidade
-
Extensibilidade 🚀
- Dashboard web futuramente
- APIs REST potenciais
- Integração com ferramentas de monitorização
-
Performance Aceitável ⚡
- Diferença de latência irrelevante (< 1ms)
- Volume de mensagens não é crítico
- Rede local minimiza overhead
-
Segurança 🔒
- Evita vulnerabilidades de Java Serialization
- Validação mais simples e segura
4.3 Quando Usar Java Serialization
Java Serialization seria preferível se:
- Performance crítica (> 100k msgs/s)
- Objetos muito complexos com referências circulares
- Garantia de ambiente Java puro permanente
- Necessidade de preservar estado exato (locks, transient)
5. Implementação Recomendada
5.1 Arquitetura de Serialização
┌─────────────────────────────────────────┐
│ Application Layer │
│ (Vehicle, Message, Statistics) │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ Serialization Interface │
│ - serialize(Object): byte[] │
│ - deserialize(byte[], Class<T>): T │
└─────────────────┬───────────────────────┘
│
┌─────────┴─────────┐
│ │
┌───────▼──────┐ ┌────────▼─────────┐
│ JsonSerializer│ │JavaSerializer │
│ (Gson-based) │ │(ObjectStream) │
└───────────────┘ └──────────────────┘
5.2 Estrutura de Mensagens JSON
Exemplo 1: Transferência de Veículo
{
"messageId": "a3c5e7f9-1234-5678-90ab-cdef12345678",
"type": "VEHICLE_TRANSFER",
"senderId": "Cr1",
"destinationId": "Cr2",
"timestamp": 1729595234567,
"payload": {
"id": "V123",
"type": "LIGHT",
"entryTime": 15.7,
"route": ["Cr1", "Cr2", "Cr5", "S"],
"currentRouteIndex": 1,
"totalWaitingTime": 3.2,
"totalCrossingTime": 1.8
}
}
Exemplo 2: Atualização de Estatísticas
{
"messageId": "b4d6e8f0-2345-6789-01bc-def123456789",
"type": "STATS_UPDATE",
"senderId": "Cr3",
"destinationId": "Dashboard",
"timestamp": 1729595234789,
"payload": {
"intersectionId": "Cr3",
"queueLengths": {
"North": 5,
"South": 3,
"East": 7,
"West": 2
},
"vehiclesProcessed": 142,
"averageWaitTime": 4.5
}
}
5.3 Biblioteca Escolhida: Gson
Por que Gson (não Jackson)?
- ✅ Mais simples e leve
- ✅ Menos configuração necessária
- ✅ API mais intuitiva para iniciantes
- ✅ Melhor para modelos simples (nosso caso)
- ⚠️ Jackson seria melhor para: streaming, performance extrema, binding complexo
6. Plano de Implementação
Fase 1: Setup
- Adicionar dependência Gson ao pom.xml
- Criar interface
MessageSerializer - Implementar
JsonMessageSerializer - Implementar
JavaMessageSerializer(fallback)
Fase 2: Adapters
- Criar adaptadores Gson para classes do modelo
- Configurar serialização customizada se necessário
- Implementar testes unitários
Fase 3: Integração
- Integrar serializer nos sockets
- Adicionar logs de mensagens
- Implementar mecanismo de versionamento
Fase 4: Otimização (Opcional)
- Implementar compressão (gzip)
- Pool de serializers
- Métricas de performance
7. Estrutura de Arquivos
src/main/java/sd/
├── serialization/
│ ├── MessageSerializer.java # Interface comum
│ ├── JsonMessageSerializer.java # Implementação Gson
│ ├── JavaMessageSerializer.java # Implementação nativa
│ ├── SerializerFactory.java # Factory pattern
│ └── adapters/ # Type adapters Gson
│ ├── VehicleAdapter.java
│ └── MessageAdapter.java
└── network/
├── MessageSocket.java # Wrapper para socket
└── MessageProtocol.java # Protocolo de comunicação
8. Considerações Finais
8.1 Boas Práticas
- Versionamento: Incluir campo
versionnas mensagens - Validação: Validar mensagens após desserialização
- Logging: Logar mensagens em desenvolvimento (desabilitar em produção)
- Exceções: Tratar erros de serialização gracefully
- Testes: Testar serialização round-trip para todas as classes
8.2 Monitorização
- Tamanho médio de mensagens
- Latência de serialização/desserialização
- Taxa de erros de serialização
- Throughput de mensagens
8.3 Documentação
Cada tipo de mensagem deve ser documentado com:
- Propósito
- Estrutura JSON
- Exemplo
- Sender/Receiver esperado
- Comportamento em caso de erro
9. Referências
- Gson User Guide
- Java Serialization Specification
- JSON Schema
- Effective Java - Item 87: Consider using a custom serialized form
Documento criado em: 22 de outubro de 2025
Versão: 1.0
Autor: Equipa SD - Trabalho Prático