메인 프로젝트 (11) 알림 일괄 처리 Batch

InSeok·2022년 12월 12일
0

프로젝트

목록 보기
10/13

알림 일괄 처리

  • 읽은 알림이나 생성된지 오래된 알림에 대하여 매번 API를 호출해서 처리를 한다면, 서버에 부하를 유발하여, 실 서비스에 영향이 갈수도 있다는 생각이 들었습니다.
  • 실시간으로 처리하기보다는 유저 활동이 적은시간에 한번에 일괄처리 하는것이 효율적이라고 판단하여 Spring Batch를 도입하였습니다.

1. 배치 애플리케이션이란?

  • 배치(batch)는 데이터를 실시간으로 처리하는게 아니라, 일괄적으로 모아서 한번에 처리하는 작업을 의미합니다.

Spring Batch

  • Spring Batch에서는 Job이 있습니다. Job은 여러개의 Step으로 구성되고, Step 은 Tasklet(기능) 으로 구성됩니다. 배치 작업 하나가 Job에 해당 됩니다.

이번 프로젝트에서는 Tasklet으로 구현하였으므로, Taskelt 기준으로 설명하겠습니다.

설정

  • build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-batch' # batch
}
  • application.yml
batch:
  jdbc:
    initialize-schema: ALWAYS #batch 스키마 자동 생성
  job:
    enabled: false #시작과 동시에 실해되는건 방지
  • FitchallengeApplication.java
@SpringBootApplication
@EnableJpaAuditing
@EnableScheduling   #스케줄링 활성화
@EnableBatchProcessing  #배치기능 활성화
public class FitChallengeApplication{

      public static void main (String[]args){
         SpringApplication.run(FitChallengeApplication.class, args);
      }

   }

BatchConfig.java

@Configuration
@RequiredArgsConstructor
public class BatchConfig {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private final NotificationTasklet notificationTasklet;

		//Batch Job 생성
    @Bean
    public Job notificationJob() {
        return jobBuilderFactory.get("notificationJob")
                .start(notificationStep())
                .build();
    }

		//Batch Step 생성
    @Bean
    @JobScope //Job 실행시점에 Bean이 생성됨
    public Step notificationStep() {
        return stepBuilderFactory.get("notificationStep")
                .tasklet(notificationTasklet)
                .build();
    }
}

Tasklet

  • 일반적인 Component와 비슷한 개념, 개발자가 지정한 커스텀한 기능을 위한 단위
  • 개발자가 이 STEP에서 하고 싶은 내용을 자유롭게 만들 수 있습니다.
  • Tasklet interface를 구현하여 execute 메서드를 구현하여 실행할 내용을 넣어주면 된다.
@RequiredArgsConstructor
@Component
@StepScope // Step 시점에 Bean이 생성
@Slf4j
public class NotificationTasklet implements Tasklet {

    private final QueryNotificationRepository notificationRepository;

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext){
      
log.info(contribution.toString());
log.info(chunkContext.toString());
log.info(">>>>> Delete Notification");

        //읽음 상태인 알림 일괄삭제
        notificationRepository.deleteNotificationIsRead();
        //생성일로부터 3일이 지난 알림 일괄삭제
        notificationRepository.deleteNotificationIsNotRead();

        return RepeatStatus.FINISHED;
    }
}

Scheduler

  • batch를 수행하기 위한 Scheduler를 파일에 구성(매일 자정에 실행)
💡 Spring Batch는 Batch Job을 관리하지만 `Job`을 구동하거나 실행시키는 기능은 지원하고 있지않다.Spring에서 Batch Job을 **실행**시키기 위해서는 `Quartz, Scheduler`와 같은 전용 Scheduler를 사용해야한다.
@Slf4j
@Component
@RequiredArgsConstructor
public class JobScheduler {

    private final JobLauncher jobLauncher;
    private final BatchConfig batchConfig;

    @Scheduled(cron="0 0 12 * * *")
    public void runJob(){

        Map<String, JobParameter> confMap = new HashMap<>();
        confMap.put("time", new JobParameter(System.currentTimeMillis()));
        JobParameters jobParameters = new JobParameters(confMap);

        try {
            jobLauncher.run(batchConfig.notificationJob(), jobParameters);

        } catch (JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException
                 | JobParametersInvalidException | org.springframework.batch.core.repository.JobRestartException e) {

log.error(e.getMessage());
        }
    }
}
  • jobLauncher.run()메서드는 첫번째 파라미터로 Job, 두번째 파라미터로 Job Parameter를 받고있습니다.
  • Job Parameter의 역할은 반복해서 실행되는 Job의 유일한 ID입니다.
profile
백엔드 개발자

0개의 댓글