Red de conocimiento informático - Conocimiento informático - Cómo diseñar un servicio de archivos

Cómo diseñar un servicio de archivos

En el artículo Programación orientada a la arquitectura, expuse mis puntos de vista sobre la relación entre arquitectura y código: "¡El código debe reflejar la arquitectura"!

Este artículo verifica esta visión a través del diseño y la implementación de las funciones principales de los servicios de archivos. ¡El proceso de diseño combina "diseño basado en casos de uso" y "diseño basado en dominios"!

El servidor de archivos tiene dos funciones principales: "Carga de archivos" y "Descarga de archivos". Es posible que la carga deba admitir cargas reanudadas y cargas de varias partes. La descarga puede requerir protección de descarga; por ejemplo, los clientes no especificados no pueden descargar.

Además de estas dos funciones principales, generalmente hay una función adicional, que es la "conversión". La conversión incluye:

Además de las funciones comerciales anteriores, también incluye las siguientes restricciones no funcionales:

Según la función, se pueden dividir los siguientes módulos funcionales:

Primer paso La arquitectura en capas divide aproximadamente los módulos de acuerdo con el método de capas del diseño del dominio:

Del proceso anterior, podemos ver que el "módulo de carga" tiene una cierta dependencia de el "módulo de conversión", como se muestra a continuación:

Sin embargo, el "módulo de carga" es un módulo principal y el "módulo de conversión" es un módulo no principal. Las funciones de los módulos principales son relativamente estables, mientras que las funciones de los módulos no principales son relativamente inestables. Dejar que los módulos estables dependan de módulos inestables hará que los módulos estables se vuelvan inestables, por lo que las dependencias deben "invertirse".

La "Inversión de dependencia" resuelve el problema de dependencia del módulo. Sin embargo, la conversión es un proceso que requiere mucho tiempo. Por ejemplo, cuando un usuario sube un vídeo, sin conversión, puede obtener una respuesta tan pronto como se completa la carga. Sin embargo, si se realiza la conversión, puede tardar el doble o. incluso tres o cuatro veces más tiempo para obtener comentarios y experiencia. Muy mal. Y, en general, la puntualidad de la carga y la visualización no requiere inmediatez, por lo que la conversión debe ser un proceso asincrónico.

Hay muchas formas de ejecutar de forma asincrónica, como subprocesos personalizados, basados ​​en eventos, etc. Esto se maneja a través de eventos. (Para eventos de dominio, consulte Diseño de dominio: Eventos de dominio)

La carga de archivos creará un UploadEvent y UploadListener escucha el evento UploadEvent. Cuando se escucha UploadEvent, se realiza la conversión.

Después de que el proceso de conversión es asincrónico, ¿cómo informar al cliente del resultado de la conversión? Hay varias soluciones:

Además, la descarga se puede realizar directamente a través de un servidor web como Nginx, por lo que el módulo de descarga puede ser directamente independiente.

Para el módulo de configuración, la configuración se puede dividir en dos tipos:

La "configuración estática" se puede configurar mediante archivos de propiedades. La "configuración dinámica" requiere la configuración correspondiente según diferentes sistemas, por lo que para la configuración de recursos como imágenes y videos, cree las clases de configuración correspondientes y constrúyalas dinámicamente a través del Repositorio de acuerdo con los parámetros.

La estructura general es la siguiente:

Basado en el diseño anterior, el proceso debe ajustarse en consecuencia.

El proceso de descarga se mantiene sin cambios, con un proceso adicional para obtener el enlace del archivo convertido:

También se ha ajustado el módulo correspondiente y se ha añadido un nuevo módulo de mensajes para gestionar el Monitor de envío y recepción de mensajes. Este mensaje es un evento de dominio, por lo que también se coloca en la capa de dominio.

Proceso de carga:

Proceso de descarga:

Proceso de obtención de enlace real:

Por ejemplo, ahora queremos agregar un "segundo función de transferencia "”, es decir, para los archivos que ya existen en el servidor, la operación de carga ya no se realizará y la URL del archivo se devolverá directamente. Luego es necesario realizar las siguientes extensiones:

Las modificaciones anteriores no requieren ningún cambio en el proceso existente.

Los eventos conectan todo el proceso de carga:

Dado que la mayoría de ellos son eventos internos en la actualidad, los eventos Spring se utilizan para procesarlos. La lógica del código es la siguiente:

Para mejorar la flexibilidad del servidor de archivos, lógica de conversión configurable. Si no se realiza la configuración correspondiente, no se realizará el procesamiento correspondiente.

Las siguientes cuatro clases son configuraciones para cada tipo de archivo:

El Repositorio correspondiente es la clase de almacenamiento para guardarlos y restaurarlos:

Aquí se basa en To ¡Consiga esto mediante la configuración de atributos (consulte "Selección técnica" para conocer los motivos)! Tome VideoConfigRespository como ejemplo:

Configure las propiedades en el archivo de propiedades en videoConfigList a través de la anotación ConfigurationProperties de Spring.

El resultado de la conversión está representado por ConvertResult y ConvertFileInfo:

ConvertResultRespository es el almacén de este agregado y se utiliza para guardar y restaurar este agregado. Aquí no se utiliza una base de datos, sino que se guarda directamente en forma de texto (ver el motivo en "Selección técnica").

El servicio de conversión realiza las operaciones correspondientes según la clase de herramienta correspondiente al delegado de configuración (código omitido):

Proporciona dos interfaces:

Este artículo proporciona una El servicio de archivos tiene un proceso de implementación y diseño de arquitectura relativamente completo. Todo el proceso de diseño de arquitectura es el siguiente:

Todo el proceso toma las decisiones correspondientes para cada restricción y la verifica. La estructura del código coincide exactamente con el diseño arquitectónico. Puede comprender la lógica del código mirando el diagrama de diseño de la arquitectura.

Si hay inexactitudes u omisiones, ¡todos son bienvenidos a discutirlo y darnos consejos!