9.1 KiB
Corrección: MongoDB Separado por Microservicio
Fecha: 29 de Abril de 2026
Cambio: Arquitectura actualizada a instancias independientes de MongoDB
📋 Cambio Realizado
Se corrigió la arquitectura para que cada microservicio tenga su propia instancia de MongoDB completamente separada.
Antes ❌
┌──────────────────────────────┐
│ MongoDB (Instancia Única) │
├──────────────────────────────┤
│ Base de datos: reports │
│ Base de datos: notifications │
└──────────────────────────────┘
↑
Compartida entre servicios
Ahora ✅
┌──────────────────────────────┐
│ MongoDB Reports │ ← Puerto 27017
│ (Instancia 1) │
│ BD: voxpopuli_reports │
└──────────────────────────────┘
API Reportes
┌──────────────────────────────┐
│ MongoDB Notifications │ ← Puerto 27018
│ (Instancia 2) │
│ BD: voxpopuli_notifications │
└──────────────────────────────┘
API Notificaciones
🔧 Cambios Realizados
1. docker-compose.yaml
Antes: Una única instancia mongodb
Ahora: Dos instancias separadas
mongodb-reports:
image: mongo:7.0
container_name: voxpopuli_mongo_reports
ports:
- "27017:27017" # Puerto específico para reportes
volumes:
- mongo_reports_data:/data/db
mongodb-notifications:
image: mongo:7.0
container_name: voxpopuli_mongo_notifications
ports:
- "27018:27017" # Puerto específico para notificaciones (mapea al 27017 interno)
volumes:
- mongo_notifications_data:/data/db
Volúmenes:
volumes:
mysql_data:
mongo_reports_data: # Nuevo
mongo_notifications_data: # Nuevo
rabbitmq_data:
2. src/core/config.py
Antes:
mongodb_url: str = "mongodb://localhost:27017"
mongodb_db: str = "voxpopuli_reports"
mongodb_notifications_db: str = "voxpopuli_notifications"
Ahora:
# Instancia 1: Reportes
mongodb_reports_url: str = "mongodb://admin:admin_password@localhost:27017"
mongodb_reports_db: str = "voxpopuli_reports"
# Instancia 2: Notificaciones
mongodb_notifications_url: str = "mongodb://admin:admin_password@localhost:27018"
mongodb_notifications_db: str = "voxpopuli_notifications"
3. src/infrastructure/adapters/persistence/mongodb.py
Antes:
mongo_client = MongoClient(ConfSettings.mongodb_url)
mongodb = mongo_client[ConfSettings.mongodb_db]
def get_reports_collection() -> Collection:
return mongodb["reportes"]
Ahora:
# Cliente separado para Reportes (Puerto 27017)
mongo_client_reports = MongoClient(ConfSettings.mongodb_reports_url)
mongodb_reports = mongo_client_reports[ConfSettings.mongodb_reports_db]
# Cliente separado para Notificaciones (Puerto 27018)
mongo_client_notifications = MongoClient(ConfSettings.mongodb_notifications_url)
mongodb_notifications = mongo_client_notifications[ConfSettings.mongodb_notifications_db]
def get_reports_collection() -> Collection:
return mongodb_reports["reportes"]
def get_notifications_collection() -> Collection:
return mongodb_notifications["notificaciones"]
4. src/infrastructure/adapters/persistence/notification_repository_mongo.py
Cambio: Usar la función get_notifications_collection() centralizada en lugar de crear el cliente localmente
from infrastructure.adapters.persistence.mongodb import get_notifications_collection
class NotificationRepositoryMongo(NotificationRepository):
def __init__(self):
self.collection = get_notifications_collection() # Usa instancia separada
📊 Arquitectura Final
┌─────────────────────────────────────────────────────┐
│ VoxPopuli Services │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ Usuarios │ │ Reportes │ │Notificacio│ │
│ │ │ │ │ │nes │ │
│ │ Puerto 8000 │ │ Puerto 8001 │ │ Puerto... │ │
│ └──────┬───────┘ └──────┬───────┘ └────┬──────┘ │
│ │ │ │ │
│ ↓ ↓ ↓ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ MySQL │ │ MongoDB │ │ MongoDB │ │
│ │ (Usuarios) │ │ Reports │ │ Notif. │ │
│ │ │ │ │ │ │ │
│ │ Puerto 3306 │ │ Puerto 27017 │ │ Puerto... │ │
│ └──────────────┘ └──────────────┘ └────────────┘ │
│ │
│ Instancias │
│ Independientes │
│ │
└─────────────────────────────────────────────────────┘
↓
┌──────────────────┐
│ RabbitMQ │
│ (Compartida) │
│ Puerto 5672 │
└──────────────────┘
🚀 Cómo Levantar
# Levantar todos los servicios con instancias separadas
docker-compose up -d
# Verificar que ambas instancias de MongoDB están corriendo
docker-compose ps
# Resultado esperado:
# voxpopuli_mysql Up (healthy)
# voxpopuli_mongo_reports Up (healthy) Puerto 27017
# voxpopuli_mongo_notifications Up (healthy) Puerto 27018
# voxpopuli_rabbitmq Up (healthy)
🔌 Puertos Finales
| Servicio | Contenedor | Puerto Externo | Puerto Interno |
|---|---|---|---|
| MySQL | voxpopuli_mysql | 3306 | 3306 |
| MongoDB (Reports) | voxpopuli_mongo_reports | 27017 | 27017 |
| MongoDB (Notifications) | voxpopuli_mongo_notifications | 27018 | 27017 |
| RabbitMQ AMQP | voxpopuli_rabbitmq | 5672 | 5672 |
| RabbitMQ Management | voxpopuli_rabbitmq | 15672 | 15672 |
🧪 Verificar Separación
Conectar a MongoDB Reports
docker exec -it voxpopuli_mongo_reports mongosh \
-u admin -p admin_password \
--authenticationDatabase admin
# En la terminal de MongoDB:
use voxpopuli_reports
db.reportes.find() # Solo verá reportes
Conectar a MongoDB Notifications
docker exec -it voxpopuli_mongo_notifications mongosh \
-u admin -p admin_password \
--authenticationDatabase admin
# En la terminal de MongoDB:
use voxpopuli_notifications
db.notificaciones.find() # Solo verá notificaciones
✅ Beneficios de esta Arquitectura
- Aislamiento Completo - Cada servicio es totalmente independiente
- Escalabilidad - Escalar reportes sin afectar notificaciones (y viceversa)
- Backup Independiente - Backups separados por tipo de dato
- Seguridad - Credenciales y acceso separados
- Performance - Sin contención de recursos entre servicios
- Mantenibilidad - Más fácil de mantener y depurar
- High Availability - Una BD puede fallar sin afectar la otra
📝 Variables de Entorno (Opcional)
Si necesitas cambiar los puertos en producción:
# .env
MONGODB_REPORTS_URL=mongodb://admin:password@mongo-reports:27017
MONGODB_NOTIFICATIONS_URL=mongodb://admin:password@mongo-notifications:27017
Luego actualizar en config.py:
mongodb_reports_url: str = Field(
default=os.getenv("MONGODB_REPORTS_URL", "...")
)
mongodb_notifications_url: str = Field(
default=os.getenv("MONGODB_NOTIFICATIONS_URL", "...")
)
🎯 Resumen
✅ Cada microservicio tiene su propia instancia de MongoDB
✅ Datos completamente aislados
✅ Puertos independientes (27017 y 27018)
✅ Conexiones separadas en código
✅ Configuración centralizada
✅ Totalmente escalable
Cambio Completado: Arquitectura microservicios con MongoDB independiente por servicio ✅