Hemos implementado un servidor django (nginx/gunicorn/django), pero para escalar el servidor hay varias instancias de la misma aplicación django en ejecución.
Aquí está el diagrama (arquitectura):
Cada rectángulo azul es una máquina virtual.
HAProxy envía todas las solicitudes a example.com/admin al Servidor 3. Otras solicitudes se dividen entre el Servidor 1 y el Servidor 2 (saldo de carga).
Viejo problema:
Cada máquina tiene una carpeta de medios y cuando el administrador carga algo, los medios cargados solo están en el servidor 3. (los usuarios normales no pueden cargar nada)
Resolvimos esto enviando todas las solicitudes a example.com/media/* al Servidor 3 y nginx del Servidor 3 atiende todos los archivos y medios estáticos.
Problema ahora mismo
También estamos usando sorl-thumbnail.
Cuando llega una solicitud para example.com/,sorl-thumbnail intenta acceder al archivo multimedia pero no existe en esta máquina porque está en Server3.
Entonces, ahora todas las solicitudes a esa máquina (servidor 1 o 2) obtienen 404 para ese archivo multimedia.
Una solución que me viene a la mente es hacer una partición compartida entre las 3 máquinas y usarla como medio. Otra solución es sincronizar todas las carpetas de medios después de cada carga, pero esta solución tiene un problema y es que tenemos casi 2000 solicitudes por segundo y, a veces, la sincronización puede no ser lo suficientemente rápida y sorl-thumbnail crea el registro de la base de datos de archivo vacío y ocurre 404.
Gracias de antemano y perdón por la pregunta larga.
Debe usar un almacén de objetos para guardar y servir los archivos cargados por el usuario. django-storages hace que la implementación sea realmente simple.
Si no desea utilizar AWS S3 basado en la nube o equivalente, puede alojar su propia tienda de objetos local compatible con S3 con minio .
En su configuración actual, no veo ninguna manera fácil de arreglar dónde la cantidad de máquinas virtuales es dinámica según la carga.
Si tiene automatización de implementación, tal vez pruebe rsync para que la máquina virtual se encargue de sincronizar archivos con otras máquinas virtuales.
Pregunta: ¿Cuál era el problema?
obtuvimos 404 en otras máquinas porque las solicitudes normales (solicitudes que solicitan una plantilla) obtendrían un 404 que no se encuentra en los medios en miniatura. El problema real fue con las etiquetas de plantilla de miniaturas sorl.
Esto es lo que terminamos haciendo:
En los modelos que necesitaban una miniatura, agregamos funciones para crear esa miniatura específica.
y usando una señal posterior a guardar en la máquina de administración llamó a todas esas funciones para asegurarse de que todas las miniaturas se crearon después de guardar y la tabla para sorl-thumbnail está llena.
ahora en las plantillas en lugar de llamar a las etiquetas de plantilla sorl-thumbnail ahora llamamos a una función en el modelo.