Spring으로 결제서비스 만들기(2)

2024. 3. 27. 16:37·Spring/결제

2024.03.27 - [Spring/결제] - Spring으로 결제서비스 만들기(1)

 

Spring으로 결제서비스 만들기(1)

시나리오 - 고객이 유료 API를 사용 - 서비스팀은 유료 API 사용 이력 남김 - 유료 API 사용 이력을 파일로 정산팀에게 전달 (임시로 랜덤 데이터 생성) // 고객번호, url, 상태, 생성일 - 정산팀은 1일

lsdiary.tistory.com

 

이전글에서는 정산팀은 1일 단위로 정산이라는 조건까지 구현을 완료했다.

  • 매주 금요일 1주일치 1일 정산을 집계해서 DB에 저장 후, 고객사에 이메일 보냄 // 고객번호, 서비스번호, 횟수, 요금

이번에는 위 조건에 대해 확장을 해보도록 한다.

일주일치 csv파일을 만들어야하니 7개의 Worker Step을 만드는 Patitioning 기법을 통해 만든다.

 

ApiOrderGeneratePartitionJobConfiguration.java

@Configuration
@RequiredArgsConstructor
public class ApiOrderGeneratePartitionJobConfiguration {
    private final JobRepository jobRepository;
    private final PlatformTransactionManager platformTransactionManager;

    @Bean
    public Job apiOrderGenerateJob(Step managerStep){
        return new JobBuilder("apiOrderGenerateJob", jobRepository)
                .start(managerStep)
                .incrementer(new RunIdIncrementer())
                .validator(new DefaultJobParametersValidator(new String[]{"targetDate", "totalCount"}, new String[0]))
                .build();
    }
    @Bean
    @JobScope
    public Step managerStep(
        PartitionHandler partitionHandler,
        @Value("#{jobParameters['targetDate']}") String targetDate,
        Step apiOrderGenerateStep

    ){
        return new StepBuilder("managerStep", jobRepository)
                .partitioner("delegateStep", getPartitioner(targetDate))
                .step(apiOrderGenerateStep)
                .partitionHandler(partitionHandler)
                .build();
    }

    //매니저 스텝이 워커 스텝을 어떻게 다룰지를 정의
    @Bean
    public PartitionHandler partitionHandler(Step apiOrderGenerateStep){
        TaskExecutorPartitionHandler taskExecutorPartitionHandler = new TaskExecutorPartitionHandler();
        taskExecutorPartitionHandler.setStep(apiOrderGenerateStep);
        taskExecutorPartitionHandler.setGridSize(7);
        taskExecutorPartitionHandler.setTaskExecutor(new SimpleAsyncTaskExecutor());
        return taskExecutorPartitionHandler;

    }

    //워커 스텝을 위해서 StepExecution을 생성하는 인터페이스
    Partitioner getPartitioner(String targetDate){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate date = LocalDate.parse(targetDate, formatter);
        //파티션별 이름과, 사용할 ExecutionContext 지정
        return x -> {
            final Map<String, ExecutionContext> result = new HashMap<>();

            IntStream.range(0, 7)
                    .forEach(it ->{
                        ExecutionContext value = new ExecutionContext();
                        value.putString("targetDate",date.minusDays(it).format(formatter));
                        result.put("partition" + it, value);
                    });
            return result;
        };
    }

    @Bean
    public Step apiOrderGenerateStep(
            ApiOrderGenerateReader apiOrderGenerateReader,
            ApiOrderGenerateProcessor apiOrderGenerateProcessor
    ){
        return new StepBuilder("apiOrderGenerateStep",jobRepository)
                .<Boolean, ApiOrder>chunk(5000, platformTransactionManager)
                .reader(apiOrderGenerateReader)
                .processor(apiOrderGenerateProcessor)
                .writer(apiOrderGenerateWriter(null))
                .build();
    }

    @Bean
    @StepScope  //lazy로딩이 일어나 null이 인자로 들어가는것이 아니라, 맞는 데이터가 들어감
    public FlatFileItemWriter<ApiOrder> apiOrderGenerateWriter(
             @Value("#{stepExecutionContext['targetDate']}") String targetDate
    ){
        String fileName = targetDate + "_api_orders_csv";
        return new FlatFileItemWriterBuilder<ApiOrder>()
                .name("apiOrderGenerateWriter")
                .resource(new PathResource("/FastCampus/spring-payment/spring-payment/src/main/resources/datas/" + fileName))
                .delimited()    //기본값으로 두면 쉼표로구분
                .names("id", "customerId", "url", "state", "createdAt")
                .headerCallback(writer -> writer.write("id, customerId, url, state, createdAt"))
                .build();

    }
}

 

파티셔닝 기법을 위해서, 매니저 스텝을 따로 만들고 매니저 스텝이 파티션 핸들러를 통해 워커스텝이 어떻게 실행될지 설정해주고, 파티셔너를 통해 사용할 ExecutionContext를 지정 해줬다. 

원래 apiOrderGenerateWriter에서 @StepScope 어노테이션으로 인해 @Value로 받아왔던 jobParameters를 확장된 코드에서는 StepExecution을 파티셔너에서 설정해주므로 @Value를 stepExecution에서 받아온다.

잘 실행되는 것을 확인할 수있다.

실행시간을 확인하기 위해서 콘솔뿐만 아니라, BATCH_STEP_EXECUTION 테이블에서도 확인할 수있다.

하지만 보다시피 시작, 끝 시점만 알려줘서 실행에 걸린 시간을 알고싶으면 계산을해야한다.

이를 또 스프링에서는 다 준비를 해놨다.

https://docs.spring.io/spring-batch/reference/monitoring-and-metrics.html#built-in-metrics

 

Monitoring and metrics :: Spring Batch

If you want to use your own metrics in your custom components, we recommend using Micrometer APIs directly. The following is an example of how to time a Tasklet: import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Timer; impo

docs.spring.io

스프링 공식문서를 보면, Job, Step, Item에 대해서 모두 TIMER를 제공하고있다. 대다나다,,,

 

이제 csv로 만든 파일을 읽어서 특정고객에게 과금되는 금액을 알려주는 일일 정산배치를 만들어 보겠다.

 

2024.03.28 - [Spring/결제] - Spring으로 결제서비스 만들기(3)

 

Spring으로 결제서비스 만들기 준비(3)

2024.03.27 - [Spring/결제] - Spring으로 결제서비스 만들기 준비(2) Spring으로 결제서비스 만들기 준비(2) 2024.03.27 - [Spring/결제] - Spring으로 결제서비스 만들기 준비(1) Spring으로 결제서비스 만들기 준비(1

lsdiary.tistory.com

 

'Spring > 결제' 카테고리의 다른 글

Spring으로 결제서비스 만들기(4)  (1) 2024.03.31
Spring으로 결제서비스 만들기(3)  (0) 2024.03.28
Spring으로 결제서비스 만들기(1)  (0) 2024.03.27
'Spring/결제' 카테고리의 다른 글
  • Spring으로 결제서비스 만들기(4)
  • Spring으로 결제서비스 만들기(3)
  • Spring으로 결제서비스 만들기(1)
Ls._.Rain
Ls._.Rain
안되면 될때까지 삽질했던 기록
  • Ls._.Rain
    Ls{Diary}
    Ls._.Rain
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • Github (2)
      • Spring (51)
        • Batch Programming (13)
        • 결제 (4)
        • 대용량 트래픽 (32)
        • OpenAI (0)
        • Security (0)
        • WebSocket (0)
        • JPA (1)
      • Algorithm (67)
        • DFS (6)
        • BFS (6)
        • Dynamic Programming (10)
        • Brute Force (4)
        • Binary Search (6)
        • 구현, 시뮬레이션 (15)
        • Stack (1)
        • Greedy (4)
        • Priority_Queue (2)
        • Back Tracking (3)
        • Geometry (2)
        • SCC (1)
        • 투포인터 (4)
        • 최대유량 (1)
        • 정렬 (1)
      • OS (0)
      • DevOps (15)
        • AWS (11)
        • Docker (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • hELLO· Designed By정상우.v4.10.0
Ls._.Rain
Spring으로 결제서비스 만들기(2)
상단으로

티스토리툴바