You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8.8 KiB

Spring Batch 프로젝트 설정 가이드

1. 개발 환경 준비

필수 설치 항목

  • OpenJDK 1.8 이상
  • MariaDB 10.x 이상
  • Gradle 6.x 이상 (또는 Wrapper 사용)

2. 데이터베이스 설정

2.1 MariaDB 설치 및 실행

Windows:

# MariaDB 다운로드 및 설치
# https://mariadb.org/download/

# MariaDB 서비스 시작
net start MySQL

Linux:

sudo systemctl start mariadb

2.2 데이터베이스 및 사용자 생성

-- MariaDB에 접속
mysql -u root -p

-- 데이터베이스 생성
CREATE DATABASE batch_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 사용자 생성 및 권한 부여
CREATE USER 'batch_user'@'%' IDENTIFIED BY 'batch_password';
GRANT ALL PRIVILEGES ON batch_db.* TO 'batch_user'@'%';
FLUSH PRIVILEGES;

-- 확인
SHOW DATABASES;
SELECT user, host FROM mysql.user WHERE user = 'batch_user';

-- 종료
EXIT;

2.3 스키마 생성

방법 1: 명령줄에서 실행 (권장)

Windows:

cd D:\workspace\springbatch-test
mysql -u batch_user -p batch_db < src\main\resources\db\schema.sql

Linux:

cd /path/to/springbatch-test
mysql -u batch_user -p batch_db < src/main/resources/db/schema.sql

방법 2: MySQL 클라이언트에서 실행

mysql -u batch_user -p
USE batch_db;
SOURCE D:/workspace/springbatch-test/src/main/resources/db/schema.sql;

2.4 테이블 생성 확인

USE batch_db;
SHOW TABLES;

-- 예상 출력:
-- BATCH_JOB_EXECUTION
-- BATCH_JOB_EXECUTION_CONTEXT
-- BATCH_JOB_EXECUTION_PARAMS
-- BATCH_JOB_EXECUTION_SEQ
-- BATCH_JOB_INSTANCE
-- BATCH_JOB_SEQ
-- BATCH_STEP_EXECUTION
-- BATCH_STEP_EXECUTION_CONTEXT
-- BATCH_STEP_EXECUTION_SEQ
-- QRTZ_* (Quartz 관련 테이블들)
-- TB_CUSTOMER
-- TB_CUSTOMER_PROCESSED
-- TB_BATCH_LOG

3. 애플리케이션 설정

3.1 application.yml 수정

src/main/resources/application.yml 파일에서 데이터베이스 연결 정보를 확인/수정:

spring:
  datasource:
    url: jdbc:mariadb://localhost:3306/batch_db
    username: batch_user
    password: batch_password

3.2 스케줄 설정 (선택사항)

테스트를 위해 스케줄을 짧게 설정하려면 src/main/java/com/example/batch/scheduler/BatchScheduler.java 수정:

// 기본: 매일 새벽 2시
CronScheduleBuilder.cronSchedule("0 0 2 * * ?")

// 테스트용: 30초마다 실행
CronScheduleBuilder.cronSchedule("0/30 * * * * ?")

4. 프로젝트 빌드 및 실행

4.1 Gradle Wrapper 생성 (처음 한 번만)

gradle wrapper

4.2 빌드

Windows:

gradlew.bat clean build

Linux/Mac:

./gradlew clean build

4.3 실행

Windows:

gradlew.bat bootRun

Linux/Mac:

./gradlew bootRun

또는 JAR 파일로 실행:

java -jar build/libs/springbatch-test-1.0.0.jar

5. 배치 실행 테스트

5.1 수동 실행 (REST API)

배치 잡을 수동으로 실행:

curl -X POST http://localhost:8080/api/batch/customer/run

또는 브라우저/Postman에서:

POST http://localhost:8080/api/batch/customer/run

5.2 상태 확인

Health Check:

curl http://localhost:8080/api/batch/health

5.3 배치 실행 로그 확인

데이터베이스에서 확인:

-- 배치 실행 로그
SELECT * FROM TB_BATCH_LOG ORDER BY CREATED_AT DESC;

-- 처리된 고객 데이터
SELECT * FROM TB_CUSTOMER_PROCESSED ORDER BY PROCESSED_AT DESC;

-- Spring Batch 메타데이터
SELECT
    je.JOB_EXECUTION_ID,
    ji.JOB_NAME,
    je.STATUS,
    je.START_TIME,
    je.END_TIME
FROM BATCH_JOB_EXECUTION je
JOIN BATCH_JOB_INSTANCE ji ON je.JOB_INSTANCE_ID = ji.JOB_INSTANCE_ID
ORDER BY je.CREATE_TIME DESC;

6. 다중 서버 테스트

6.1 동일한 애플리케이션을 다른 포트로 실행

터미널 1:

java -jar build/libs/springbatch-test-1.0.0.jar --server.port=8080

터미널 2:

java -jar build/libs/springbatch-test-1.0.0.jar --server.port=8081

6.2 클러스터링 확인

Quartz 스케줄러 상태 확인:

SELECT * FROM QRTZ_SCHEDULER_STATE;

두 개의 인스턴스가 표시되어야 하며, 배치는 한 서버에서만 실행됩니다.

7. 대용량 데이터 테스트

7.1 테스트 데이터 생성

대용량 데이터 삽입 스크립트:

-- 100만 건 테스트 데이터 생성 (약 1-2분 소요)
DELIMITER $$

DROP PROCEDURE IF EXISTS generate_customers$$

CREATE PROCEDURE generate_customers(IN num_rows INT)
BEGIN
    DECLARE i INT DEFAULT 0;
    DECLARE batch_size INT DEFAULT 10000;

    WHILE i < num_rows DO
        INSERT INTO TB_CUSTOMER (CUSTOMER_NAME, EMAIL, PHONE, ADDRESS, STATUS)
        SELECT
            CONCAT('Customer ', i + seq) as CUSTOMER_NAME,
            CONCAT('customer', i + seq, '@example.com') as EMAIL,
            CONCAT('010-', LPAD(FLOOR(RAND() * 10000), 4, '0'), '-', LPAD(FLOOR(RAND() * 10000), 4, '0')) as PHONE,
            CONCAT('Address ', FLOOR(RAND() * 1000)) as ADDRESS,
            'ACTIVE' as STATUS
        FROM (
            SELECT @row := @row + 1 as seq
            FROM (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
                  UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t1,
                 (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
                  UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2,
                 (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
                  UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t3,
                 (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
                  UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t4,
                 (SELECT @row := 0) r
            LIMIT batch_size
        ) seq_table
        WHERE i + seq <= num_rows;

        SET i = i + batch_size;

        -- 진행 상황 출력
        SELECT CONCAT('Inserted ', i, ' / ', num_rows, ' records') AS Progress;
    END WHILE;
END$$

DELIMITER ;

-- 100만 건 생성 (테스트용)
CALL generate_customers(1000000);

-- 데이터 확인
SELECT COUNT(*) FROM TB_CUSTOMER;

7.2 성능 측정

배치 실행 후 성능 확인:

SELECT
    JOB_NAME,
    STATUS,
    START_TIME,
    END_TIME,
    TIMESTAMPDIFF(SECOND, START_TIME, END_TIME) as DURATION_SECONDS,
    TOTAL_COUNT,
    SUCCESS_COUNT,
    FAIL_COUNT,
    ROUND(TOTAL_COUNT / TIMESTAMPDIFF(SECOND, START_TIME, END_TIME), 2) as RECORDS_PER_SECOND
FROM TB_BATCH_LOG
ORDER BY START_TIME DESC
LIMIT 10;

8. 트러블슈팅

8.1 데이터베이스 연결 오류

Error: Communications link failure

해결방법:

  1. MariaDB 서비스 실행 확인
  2. 포트 확인 (기본: 3306)
  3. 방화벽 설정 확인
  4. application.yml의 연결 정보 확인

8.2 Quartz 테이블 오류

Error: Table 'batch_db.QRTZ_LOCKS' doesn't exist

해결방법: schema.sql 파일을 다시 실행하여 Quartz 테이블 생성

8.3 Batch 테이블 오류

Error: Table 'batch_db.BATCH_JOB_INSTANCE' doesn't exist

해결방법: schema.sql 파일을 다시 실행하여 Spring Batch 메타데이터 테이블 생성

8.4 메모리 부족 오류

java.lang.OutOfMemoryError: Java heap space

해결방법: JVM 힙 메모리 증가:

java -Xmx2g -jar build/libs/springbatch-test-1.0.0.jar

또는 Chunk Size 감소:

private static final int CHUNK_SIZE = 1000;  // 5000 -> 1000

9. 프로덕션 체크리스트

  • 데이터베이스 연결 정보를 환경변수로 관리
  • 로그 레벨을 INFO로 변경
  • 스케줄 시간을 프로덕션 요구사항에 맞게 조정
  • API 엔드포인트를 실제 서비스로 변경
  • 에러 알림 시스템 연동 (이메일, Slack 등)
  • 모니터링 도구 연동 (Prometheus, Grafana 등)
  • Chunk Size와 성능 튜닝
  • 배치 실행 결과 알림 설정
  • 데이터베이스 백업 정책 수립
  • 서버 리소스 모니터링 설정

10. 다음 단계

  1. 파일 기반 배치 추가: CSV/Excel 파일 읽기 처리
  2. 멀티 스레드 처리: 병렬 처리로 성능 향상
  3. 파티셔닝: 대용량 데이터를 분할 처리
  4. 동적 Job Parameter: UI에서 파라미터 설정
  5. 배치 모니터링 대시보드: Web UI 추가
  6. 실패 재처리: 실패한 건만 재실행하는 기능
  7. 알림 시스템: 배치 완료/실패 시 알림

참고 자료