Solid Queue는 Jobs와 Workers라는 두 가지 주요 구성 요소로 이루어져 있습니다.
Solid Queue 아키텍처
-
Jobs: ActiveRecord 모델로, 사용자가 상호작용하는 부분입니다.
Job.perform_later와 같이 작업을 큐에 추가하는 메서드를 정의합니다. -
Workers: 실제 작업을 수행하는 요소로, 애플리케이션 설정에 따라 백그라운드 프로세스로 생성됩니다.
-
데이터베이스: Jobs와 Workers를 연결하는 핵심 요소이며, Solid Queue의 모든 작업은 다양한 데이터베이스 테이블을 통해 이루어집니다.
작업 생명 주기 및 성능 최적화
작업이 큐에 추가되면 solid_queue_jobs 테이블에 레코드가 생성됩니다. 즉시 실행될 작업은 solid_queue_ready_executions 테이블에도 추가됩니다.
-
폴링 효율성: Workers는
solid_queue_jobs대신 크기가 작은solid_queue_ready_executions를 폴링하여 성능을 향상시킵니다. -
동시성 처리: PostgreSQL 9.5 이상 및 MySQL 8.0 이상에서 지원되는
FOR UPDATE SKIP LOCKED구문을 사용하여, 한 Worker가 작업을 잠그는 동안 다른 Worker들이 테이블의 나머지 부분을 동시에 폴링할 수 있도록 하여 병목 현상을 방지합니다. SQLite는 이 기능을 지원하지 않아 Worker들이 순차적으로 대기해야 합니다.
작업 유실 방지 (Safety First)
Solid Queue는 작업 유실을 방지하기 위한 강력한 안전 장치를 갖추고 있습니다.
-
작업 Claim: Worker가 작업을 시작할 때
solid_queue_claimed_executions테이블에 레코드를 생성하고solid_queue_jobs테이블의claimed플래그를 설정합니다. -
프로세스 관리: 각 Worker 프로세스는
solid_queue_processes테이블에 자신의 레코드를 생성하고last_heartbeat_at을 주기적으로 업데이트합니다. -
Supervisor 역할: 백그라운드에서 실행되는 Supervisor 프로세스는
solid_queue_processes테이블을 모니터링하여last_heartbeat_at이 임계값(기본 5분)보다 오래된 Worker를 감지합니다. 문제가 발생한 Worker의 레코드를 삭제하고, 해당 Worker가 Claim했던 작업을 다시 ‘잡을 수 있는(up-for-grabs)’ 상태로 만들어 다른 Worker가 처리할 수 있도록 합니다. 이를 통해 작업이 영구적으로 멈추는 상황을 방지합니다.