Esta documentación ha sido traducida automáticamente por IA.
En un entorno de nodo único, los plugins suelen satisfacer los requisitos a través de estados en proceso, eventos o tareas. Sin embargo, en un modo de clúster, el mismo plugin puede ejecutarse simultáneamente en múltiples instancias, enfrentando los siguientes problemas típicos:
El núcleo de NocoBase proporciona varias interfaces de middleware en la capa de aplicación para ayudar a los plugins a reutilizar capacidades unificadas en un entorno de clúster. Las siguientes secciones presentarán el uso y las mejores prácticas de caché, mensajería síncrona, colas de mensajes y bloqueos distribuidos, con referencias al código fuente.
Para los datos que necesitan almacenarse en memoria, se recomienda utilizar el componente de caché integrado del sistema para su gestión.
app.cache.Cache proporciona operaciones básicas como set/get/del/reset, y también admite wrap y wrapWithCondition para encapsular la lógica de caché, así como métodos por lotes como mset/mget/mdel.ttl razonable para evitar la pérdida de caché al reiniciar la instancia.Ejemplo: Inicialización y uso de caché en plugin-auth
Si el estado en memoria no puede gestionarse con una caché distribuida (por ejemplo, no puede serializarse), entonces cuando el estado cambie debido a las acciones del usuario, el cambio debe notificarse a otras instancias a través de una señal síncrona para mantener la consistencia del estado.
sendSyncMessage, que internamente llama a app.syncMessageManager.publish y añade automáticamente un prefijo a nivel de aplicación al canal para evitar conflictos.publish puede especificar una transaction, y el mensaje se enviará después de que la transacción de la base de datos se haya confirmado, asegurando la sincronización del estado y del mensaje.handleSyncMessage para procesar mensajes de otras instancias. La suscripción durante la fase beforeLoad es muy adecuada para escenarios como cambios de configuración y sincronización de esquemas.La difusión de mensajes es el componente subyacente de las señales síncronas y también puede utilizarse directamente. Cuando necesite difundir mensajes entre instancias, puede utilizar este componente.
app.pubSubManager.subscribe(channel, handler, { debounce }) puede utilizarse para suscribirse a un canal entre instancias; la opción debounce se utiliza para evitar devoluciones de llamada frecuentes causadas por difusiones repetidas.publish admite skipSelf (el valor predeterminado es true) y onlySelf para controlar si el mensaje se envía de vuelta a la instancia actual.Ejemplo: plugin-async-task-manager utiliza PubSub para difundir eventos de cancelación de tareas
La cola de mensajes se utiliza para programar tareas asíncronas, siendo adecuada para operaciones de larga duración o que pueden reintentarse.
app.eventQueue.subscribe(channel, { idle, process, concurrency }). process devuelve una Promise, y puede utilizar AbortSignal.timeout para controlar los tiempos de espera.publish añade automáticamente el prefijo del nombre de la aplicación y admite opciones como timeout y maxRetries. Por defecto, utiliza un adaptador de cola en memoria, pero puede cambiarse a adaptadores extendidos como RabbitMQ según sea necesario.Ejemplo: plugin-async-task-manager utiliza EventQueue para programar tareas
Cuando necesite evitar condiciones de carrera, puede utilizar un bloqueo distribuido para serializar el acceso a un recurso.
local basado en procesos. Puede registrar implementaciones distribuidas como Redis. Utilice app.lockManager.runExclusive(key, fn, ttl) o acquire/tryAcquire para controlar la concurrencia.ttl se utiliza como salvaguarda para liberar el bloqueo, evitando que se mantenga indefinidamente en casos excepcionales.app.cache y app.syncMessageManager para evitar reimplementar la lógica de comunicación entre nodos en los plugins.transaction.afterCommit (syncMessageManager.publish ya lo tiene integrado) para garantizar la consistencia de los datos y los mensajes.timeout, maxRetries y debounce para evitar nuevos picos de tráfico en situaciones excepcionales.Con estas capacidades, los plugins pueden compartir estados de forma segura, sincronizar configuraciones y programar tareas entre diferentes instancias, cumpliendo con los requisitos de estabilidad y consistencia de los escenarios de implementación en clúster.