Spring 작업 대기열 처리

Spring에서 특정 작업을 대기열에 넣고 순차적으로 처리하려면 QueueExecutor 또는 Spring Batch를 사용할 수 있습니다. 다음은 주요 방법들입니다.


1. BlockingQueueExecutorService 사용

Java의 BlockingQueueExecutorService를 활용하여 작업을 순차적으로 처리할 수 있습니다.

예제 코드:

java
import java.util.concurrent.*; public class TaskQueue { private final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>(); private final ExecutorService executor = Executors.newSingleThreadExecutor(); public TaskQueue() { executor.submit(() -> { while (true) { try { // Queue에서 작업을 하나씩 꺼내어 실행 Runnable task = taskQueue.take(); task.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); } public void addTask(Runnable task) { taskQueue.offer(task); } public void shutdown() { executor.shutdown(); } }

사용 방법:

java
TaskQueue taskQueue = new TaskQueue(); // 작업 추가 taskQueue.addTask(() -> System.out.println("작업 1 실행")); taskQueue.addTask(() -> System.out.println("작업 2 실행"));

2. Spring Async와 @Scheduled를 조합

Spring의 비동기 처리를 활용하면서 작업 대기열을 만들어 순차적으로 처리합니다.

설정:

  1. @EnableAsync 활성화

    java
    @Configuration @EnableAsync public class AsyncConfig { }
  2. BlockingQueue와 비동기 작업:

    java
    import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @Service public class QueueService { private final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>(); public void addTask(Runnable task) { taskQueue.offer(task); } @Async public void processTasks() { while (!taskQueue.isEmpty()) { try { Runnable task = taskQueue.take(); task.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } }
  3. 사용 예제:

    java
    @RestController public class TaskController { private final QueueService queueService; public TaskController(QueueService queueService) { this.queueService = queueService; } @PostMapping("/addTask") public ResponseEntity<String> addTask(@RequestBody String taskName) { queueService.addTask(() -> System.out.println("Executing task: " + taskName)); queueService.processTasks(); return ResponseEntity.ok("Task added"); } }

3. Spring Batch

작업이 많은 경우, Spring Batch를 활용하여 작업을 대기열처럼 구성할 수 있습니다. Job과 Step을 설계하여 순차 처리합니다.

주요 특징:

  • 대량 데이터를 처리할 때 유용.
  • 작업의 상태를 관리.

구성:

  1. Tasklet 정의:

    java
    @Component public class SampleTasklet implements Tasklet { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { System.out.println("Task 실행"); return RepeatStatus.FINISHED; } }
  2. StepJob 정의:

    java
    @Configuration public class BatchConfig { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; public BatchConfig(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) { this.jobBuilderFactory = jobBuilderFactory; this.stepBuilderFactory = stepBuilderFactory; } @Bean public Step sampleStep(SampleTasklet tasklet) { return stepBuilderFactory.get("sampleStep") .tasklet(tasklet) .build(); } @Bean public Job sampleJob(Step sampleStep) { return jobBuilderFactory.get("sampleJob") .start(sampleStep) .build(); } }
  3. Job 실행:
    Spring Batch의 JobLauncher로 실행하거나 @Scheduled로 주기적으로 실행합니다.


상황에 따른 선택:

  • 간단한 대기열: BlockingQueueExecutorService를 사용.
  • 웹 요청 기반 작업: Spring Async와 비동기 작업 처리.
  • 대량 처리: Spring Batch.

원하는 사용 사례에 따라 추가로 커스터마이징할 수 있습니다. 어떤 방식이 적합한지 알려주시면 더 구체적으로 도와드리겠습니다!

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다