이 문서는 AI로 번역되었습니다. 부정확한 내용이 있을 경우 영어 버전을 참조하세요
단일 노드 환경에서는 플러그인이 프로세스 내 상태, 이벤트 또는 태스크를 통해 요구사항을 충족할 수 있습니다. 하지만 클러스터 모드에서는 동일한 플러그인이 여러 인스턴스에서 동시에 실행될 수 있으며, 다음과 같은 일반적인 문제에 직면하게 됩니다.
NocoBase 코어는 애플리케이션 계층에 다양한 미들웨어 인터페이스를 미리 제공하여, 플러그인이 클러스터 환경에서 통합된 기능을 재사용할 수 있도록 돕습니다. 다음 섹션에서는 소스 코드와 함께 캐싱, 동기 메시징, 메시지 큐 및 분산 잠금의 사용법과 모범 사례를 소개합니다.
메모리에 저장해야 하는 데이터의 경우, 시스템에 내장된 캐시 컴포넌트를 사용하여 관리하는 것을 권장합니다.
app.cache를 통해 기본 캐시 인스턴스를 가져올 수 있습니다.Cache는 set/get/del/reset과 같은 기본 작업을 제공하며, 캐싱 로직을 캡슐화하는 wrap 및 wrapWithCondition과 mset/mget/mdel과 같은 배치(batch) 메서드도 지원합니다.ttl을 설정하는 것이 좋습니다.메모리 내 상태를 분산 캐시로 관리할 수 없는 경우(예: 직렬화할 수 없는 경우), 사용자 작업에 따라 상태가 변경될 때 변경 사항을 동기 신호를 통해 다른 인스턴스에 알려 상태 일관성을 유지해야 합니다.
sendSyncMessage를 구현했으며, 내부적으로 app.syncMessageManager.publish를 호출하고 채널에 애플리케이션 수준 접두사를 자동으로 추가하여 채널 충돌을 방지합니다.publish는 transaction을 지정할 수 있으며, 메시지는 데이터베이스 트랜잭션이 커밋된 후에 전송되어 상태와 메시지 동기화를 보장합니다.handleSyncMessage를 통해 다른 인스턴스에서 보낸 메시지를 처리할 수 있으며, beforeLoad 단계에서 구독할 수 있어 설정 변경, 스키마 동기화 등과 같은 시나리오에 매우 적합합니다.예시: plugin-data-source-main은 동기 메시지를 사용하여 다중 노드 스키마 일관성을 유지합니다.
메시지 브로드캐스팅은 동기 신호의 하위 컴포넌트이며 직접 사용하는 것도 지원합니다. 인스턴스 간에 메시지를 브로드캐스팅해야 할 때 이 컴포넌트를 통해 구현할 수 있습니다.
app.pubSubManager.subscribe(channel, handler, { debounce })를 사용하여 인스턴스 간에 채널을 구독할 수 있습니다. debounce 옵션은 중복 브로드캐스트로 인한 빈번한 콜백을 방지하는 데 사용됩니다.publish는 skipSelf(기본값은 true)와 onlySelf를 지원하며, 메시지가 현재 인스턴스로 다시 전송될지 여부를 제어하는 데 사용됩니다.예시: plugin-async-task-manager는 PubSub을 사용하여 태스크 취소 이벤트를 브로드캐스팅합니다.
메시지 큐는 비동기 태스크를 스케줄링하는 데 사용되며, 장시간 소요되거나 재시도 가능한 작업을 처리하는 데 적합합니다.
app.eventQueue.subscribe(channel, { idle, process, concurrency })를 통해 컨슈머를 선언합니다. process는 Promise를 반환하며, AbortSignal.timeout을 사용하여 타임아웃을 제어할 수 있습니다.publish는 애플리케이션 이름 접두사를 자동으로 추가하며, timeout, maxRetries 등의 옵션을 지원합니다. 기본적으로 인메모리 큐 어댑터를 사용하지만, 필요에 따라 RabbitMQ와 같은 확장 어댑터로 전환할 수 있습니다.예시: plugin-async-task-manager는 EventQueue를 사용하여 태스크를 스케줄링합니다.
경쟁 작업을 피해야 할 때, 분산 잠금을 사용하여 리소스에 대한 접근을 직렬화할 수 있습니다.
local 어댑터를 제공하며, Redis와 같은 분산 구현을 등록할 수 있습니다. app.lockManager.runExclusive(key, fn, ttl) 또는 acquire/tryAcquire를 통해 동시성을 제어합니다.ttl은 잠금 해제를 위한 안전장치로 사용되어, 예외적인 상황에서 잠금이 영원히 유지되는 것을 방지합니다.예시: plugin-data-source-main은 분산 잠금을 사용하여 필드 삭제 프로세스를 보호합니다.
app.cache, app.syncMessageManager와 같은 통합된 기능을 사용하십시오. 플러그인에서 노드 간 통신 로직을 중복 구현하는 것을 피하십시오.transaction.afterCommit을 사용해야 합니다(syncMessageManager.publish에 내장되어 있습니다). 이는 데이터와 메시지 일관성을 보장하기 위함입니다.timeout, maxRetries, debounce 값을 적절하게 설정하십시오.이러한 기능을 통해 플러그인은 서로 다른 인스턴스 간에 안전하게 상태를 공유하고, 설정을 동기화하며, 태스크를 스케줄링할 수 있어 클러스터 배포 시나리오의 안정성 및 일관성 요구사항을 충족합니다.