묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
청크 지향 처리 시 벌크 read 방법?
킬구형, 청크 지향 처리 시 벌크 read를 할 수 있는 방법이 있어?ItemReader 사용 시 소스에서 1건 씩 데이터를 읽어온다면, 단건 SELECT문이 매번 날아가거나 아니면 JDBC의 ResultSet next()를 사용하는 것 같은데,, 전자면 DB 부하가 너무 심하고 후자여도 네트워크 IO가 꽤 발생할 것 같은데..지금 수백? 수천만? 건 정도의 데이터를 마이그레이션 해야하는 업무를 받았는데, 청크 생성 시 DB 부하나 네트워크 트래픽을 좀 줄이고 싶은데 다건 SELECT를 통해 처리하는 방법이 있을까?
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
redis 샘플 공격 데이터 2번 오류
오타 발견root@4ea86c29f1f7:/data# redis-cli set attack:2 "{\"id\":2,\"timestamp\":\"${TODAY}T09:28:47\",\"targetIp\":\"203.0.113.50\",\"attackType\":\"XSS\",\"payload\":\"<script>alert('HACKED!');</script>\"}" 위 명령어 실행 시, 아래와 같은 에러 메시지 발생!bash: !': event not found 에러 발생 원인bash: !': event not found 에러는 Bash의 히스토리 확장(history expansion) 때문에 납니다. ! 문자(예: HACKED!)가 들어가면 bash가 !로 시작하는 히스토리 토큰(예: !!, !$, !123)으로 해석하려 하고, 매칭되는 히스토리 항목이 없으면 event not found 오류가 납니다. set +H # 히스토리 확장 끄기 ... redis-cli set attack:2 "{\"id\":2,\"timestamp\":\"${TODAY}T09:28:47\",\"targetIp\":\"203.0.113.50\",\"attackType\":\"XSS\",\"payload\":\"<script>alert('HACKED!');</script>\"}" ... set -H # # 히스토리 확장 켜기OKredis key들을 set 하기 전에 히스토리 확장을 끄고 실행할 경우 정상 동작
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
MR.kill-9 첫번째 예제 코드 실습하면서 궁굼한점이 생겼다.
강의 예제를 따라가면서 SystemFailureJobConfig 배치를 실행했는데, 계속 FlatFileItemReader에서 JobParameter로 전달한 inputFile이 null로 들어오는 문제가 발생했다.정확하게는 Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.file.FlatFileItemReader]: Factory method 'systemFailureItemReader' threw exception with message: Path must not be null이 오류 였으며, public FlatFileItemReader<SystemFailure> systemFailureItemReader( @Value("#{jobParameters['inputFile']}") String inputFile) { log.info("오잉 Reader inputFile: " + inputFile); // null return new FlatFileItemReaderBuilder<SystemFailure>() .name("systemFailureItemReader") //여기서 path not null 오류 발생 .resource(new FileSystemResource(inputFile)) .delimited() .delimiter(",") .names("errorId", "errorDateTime", "severity", "processId", "errorMessage") .targetType(SystemFailure.class) .linesToSkip(1) .build(); }.name("systemFailureItemReader") 이 위치에서 발생하고 있었다. 그리고 line numbers are likely diverged. try to find the current location inside 'SystemFailureJobConfig. systemFaliureItemReader()'이 메시지도 함께 보였다.GPT에 물어봐서 해결이 되긴 했는데, KillBatchSystemApplication에서 CommandLineRunner를 구현하고 직접 경로를 지정해주었다.@SpringBootApplication @AllArgsConstructor public class KillBatchSystemApplication implements CommandLineRunner { private final JobLauncher jobLauncher; private final Job systemFailureJob; public static void main(String[] args) { SpringApplication.run(KillBatchSystemApplication.class, args); } @Override public void run(String... args) throws Exception { JobParameters params = new JobParametersBuilder() .addString("inputFile", "/Users//Desktop/kill-batch-system2/system-failures.csv") .toJobParameters(); jobLauncher.run(systemFailureJob, params); } }실무에서는 CLI로 파라미터를 전달하는것이 핵심이라 했던걸로 기억한다.CLI로 전달한 JobParameter를 StepScope Bean에서 안전하게 받는 다른 방법은 없나?? 아 지금 작업도구는 MacOS M1, Spring Boot 3.4.7 이다. 연휴 잘 보내길 바란다.
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
청크 단위의 트랜잭션 롤백에 대한 질문
청크 단위로 트랜잭션된다는건 이해했다. 그에 관련해서 궁금증이 생겼는데,reader, processor에서 처리하다가 Exception이 나도 사실 DB엔 롤백할게 없으니 사실상 Writer 작업 중에만 단 한번 롤백이 수행될 것이라고 예상되는데 맞는가?read 시에, process 도중에도 롤백이 일어날 경우가 있는지 궁금하다. 추가로 과거 스프링 배치 공식 문서의 잘못된 다이어그램 이라던지null을 줘야 끝난다는 점과 97개 와 같이 자세한 예시를 들어준 점,read(), process()가 각각 10번씩 수행된다는 것과 같이사용자들이 많이 헷갈려 하는걸 명확하게 알려줘서 좋은 것 같다.
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
[🔥응급🔥] 미스터 KILL-9 트랜잭션에 대해서 궁금한게 있다!
앞선 질문에 대한 답변 고맙다 미스터 KILL-9덕분에 손쉽게 엑셀을 처형(처리)할 수 있었지 하지만 그 다음 관문이 존재하는군 후후..각 STEP 마다 RepeatStatus 에 따라서 트랜잭션이 보장하는건 이해했다하지만 여러 관계가 존재하는 테이블 데이터 적재 시트랜잭션을 어떻게 보장할지 감이 안온다 미스터 KILL-9 예를 들어 설명하지..FILE-A, FILE-B 각각 다른 컬럼을 가진 파일들이지FILE-A는 TABLE-A에 적재하고FILE-B는 TABLE-B에 적재한다각 FILE 당 ROW 100개씩 읽으면서 적재하고 문제가 생기면 해당 100건만 롤백할텐데문제는 TABLE-A 와 TABLE-B의 관계다TABLE-A 가 부모고 TABLE-B자 자식 테이블인 상황에서특정 TABLE-B 데이터 롤백 시 TABLE-A 데이터도 마찬가지로 롤백 해야할거 같은데 이런 경우 어떻게 원자성을 보장할 수 있는가에 답변할 수 있겠는가..? 현재 내가 떠오른 방안은 결국은 모든 데이터 처리이니 특정 부분 처리 실패하면 데드 DLQ (Dead Letter Queue)에 담아서 나중에 처형(처리)하도록 해야하나 싶다!
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
BatchConfig 에 대한 질문
Spring Boot + Kotlin + java 21로 진행중이다.먼저 좋은 강의 너무 고맙고,나도 다른 사람의 Q&A 처럼 BatchConfig가 있어서 수행시에 부트만 떴다가 꺼지고 아무것도 출력되지 않아서 당황했다 (그래서 강의 자료에 더이상 불필요하다 보다는 제거하라고 명시하면 좋을 것 같다)질문이 있는데1. BatchConfig가 있고 없고가 어떤 것 때문에 수행결과에 차이점을 주는거야?2. Kotlin을 사용한 Spring Boot에서는 @Import를 사용하지 않았는데, 이때도 자동으로 설정을 해주는걸까? BatchConfig가 있다는 것 자체로 배치 수행은 안하고 부트가 바로 끝나버려 두 질문 다 그냥 궁금증일 뿐이다. BatchConfig를 제거하면 수행에는 문제가 없다.
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
ExcelFileReader는 왜 존재하지 않는거지 미스터 킬구
킬구형 안녕 FlatFileReader 라는 아주 편안한 기능은 존재하는데 어째서 ExcelFileReader 기능은 존재하지 않는거지? gpt 말로는 공식 확장 모듈은 spring-batch-excel 이 존재한다고는 하는데 이거 믿고 사용해도 되는지 모르겠네 킬구형은 excel 파일 읽고 DB에 쓸 때 아파치 poi 라이브러리로 직접 파싱해?
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
오타발견
그러나 JdbcCursorItemReader는 기본적으로 커서의 순반향 이동만 지원순반향->순방향근데 맨날 오타글만 올리는데 괜찮음?귀찮으면 안하고
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
오타?복붙실패
InFearLearn 서버 침입 사건: 해커 패턴 추적 작전작전 수행을 위한 실전 코드부터 살펴보자.여기코드에서 @Bean@StepScopepublic MongoCursorItemReader<SecurityLog> securityLogReader(이 아이템리더쪽 복붙하고 안다듬어서 들여쓰기 밀림
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
kill-9 5TA Alarm
ItemWriter 구현체에 JpaPagingItemReader라고 Write 되어있다. fix 하라
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
스냅샷 읽기
cursorReader에서 스냅샷을 읽어서 동일한 스탭에서 데이터가 변경되어도 영향을 받지 않는다 하셨는데,이거는 mysql의 repeatable read와 관련된 스냅샷인걸까요? 아니면 배치 자체에서 제공하는 스냅샷인가요?
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
강의 공부에 대해서 관련된 질문!
공부중인데 내용이 너무 좋아서 블로그에 공부한 예제 코드와 정리된 내용을 일부 작성하려 하는데 괜찮을까요?? 스크린샷으로 첨부하거나 그런건 아니고 코드는 제 ide 에서 실행한것과 git repo 에 올리면서 공유하려고 해~ 그리고 공부한 내용들은 직접 작성 하고 정리해서 올리려고 하는데 괜찮은지 궁금해서 질문해!!
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
오타 발견 및 건의 및 궁금증
1.오타JobScope와 StepScop가 선언된 빈은 애플리케이션 구동 시점에는 우선 프록시 객체로만 존재한다. 그 후 Job이나 Step이 실행된 후에 프록시 객체에 접근을 시도하면 그 때 실제 빈이 생성된다.StepScop <-오타2.건의(내가틀렸을수도있음 그러면 수정해주셈)그리고 JobParameters가 잡 실행 내부에서 불변이라는 내용이 필요할거같음배치쓰던사람들은 당연한거라 생각할수있는데(잡파라미터랑 잡이름으로 유니크체크한댔나 그런거도 있으니까)배치 첨쓰는사람은 왜 잡파라미터가 있는데 ExecutionContext를 사용하지 라는 생각을 할수있을거같음3.궁금증컴파일 시점에 없는 값을 어떻게 참조할 것인가?여기서 잡의 스텝생성시점에서 di받는 잡파라미터 자리에 null을 넣는식으로 처리하는 방법이 있다고했는데,만약 코틀린의 경우엔 명시적으로 잡파라미터를 ?를 붙여서 nullable로 선언하고 로직에서 NullSafe 박는식으로밖에 해결할수없고 저게 맘에안들면 빈주입해야함?저런 null전달같은 꼼수딴거없음?강의가 자바기반이라고 적혀있어서 물어봐도되나싶긴한데 예전에 저것땜에 고생했었는데 다른방법을 못찾아서 물어봄
-
미해결스프링 배치
소스코드가 어디에 있나요?
소스코드가 깃허브에 있다고 하는데, 각 단원별로 어떤 브랜치와 연결되어 있는지 알수가 없네요.과제교제에는 소스 위치 내용은 없어요.
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
이너 클래스로 구현하는 이유
킬구형 안녕!지금 실무에서 Spring Batch를 사용해서 배치 기능 구현하고 있는데 궁금한 점이 있어.강의의 예제 코드들을 보다보면 Job에 필요한 항목들을 따로 클래스 파일로 빼서 구현하지 않고 JobConfig 클래스 내에서 이너 클래스로 구현하던데 특별한 이유가 있을까!?@Slf4j public static class BrainwashProcessor implements ItemProcessor<InFearLearnStudents, BrainwashedVictim> {강의가 너무 재밌어서 점심시간에도 공부 중이야 ㅎㅎ
-
해결됨죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
allowStartIfComplete 질문
킬구형 안녕,강의를 보다가 궁금한 점이 생겨서 문의를 남겨. "정리하자면, allowStartIfComplete은 식별 파라미터 없이 Job을 재시작한 경우에만 적용되는 옵션이다." 이 문장을 보고 궁금증이 생겼는데,identifying JobParameters 가 없어서 Job 그리고 그 하위 Step 들이 다시 수행될수도 있겠지만, Job => Step A (성공) / Step B (실패) 여서 잡을 재시작하는 케이스에서,Step A 가 allowStartIfComplete true 면 A부터 스텝을 수행할텐데, 이 케이스에서도 allowStartIfComplete 를 쓰는게 아닌가 싶어서 문의를 남겨!이러면 Spring Batch 6 에서도 의미있는 파라미터가 아닌가 싶어서! (강의 잘보고 있습니다, 감사합니다!!)
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
2장.작전1. 실행시 오류에 대해서 문의.
,로분리된 csv파일로 하고 public FlatFileItemReader<SystemFailure> systemFailureItemReader( @Value("#{jobParameters['inputFile']}") String inputFile) { return new FlatFileItemReaderBuilder<SystemFailure>() .name("systemFailureItemReader") .resource(new FileSystemResource(inputFile)) .delimited() .delimiter(",") .names("errorId", "errorDateTime", "severity", "processId", "errorMessage") .targetType(SystemFailure.class) .linesToSkip(1) .strict(true) .build(); }----------실행하면, 오류가 발생합니다.PS D:\Test\springboot\kill-batch-system> ./gradlew bootRun --args='--spring.batch.job.name=systemFailureJob inputFile=d:/Test/springboot/kill-batch-system/system-failures.csv'.....Caused by: org.springframework.batch.item.file.transform.IncorrectTokenCountException: Incorrect number of tokens found in record: expected 5 actual 1..... PS D:\Test\springboot\kill-batch-system> 그런데, \t으로 구분하고, .delimiter("\t")로 하면 정상작동합니다. 이유가 뭘까요?윈도우 환경입니다.그리고, 실행시 파일의 위치를 절대경로로 주어야 하나요?상대경로일경우, 파일의 위치를 어디에 두어야 하나요?
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
챕터별 설명하신 내용의 실행가능한 소스가 있는지 궁금합니다.
중간중간 소스만으로 실행가능한 소스를 만들고, 이해하는게 어렵습니다.큰 챕터별로 실행가능한 소스가 없는지 궁금합니다.즐거운 하루보내세요.
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
전략적 침투: Spring Boot Application 실행에대해서
./gradlew bootRun --args='--spring.batch.job.name=systemTerminationSimulationJob'위에 코드로 터미널에서 실행하는데 System.out.println로 출력해둔 건 나오지않고 스프링부트 로그만 뜨고 끝나버리더군요 AI에게 물어봤더니 그럴경우 강제적으로 하는방법이 있다고해서 ApplicationRunner를 주입시켜서 해봤는데 또 잘나옵니다. ApplicationRunner를 계속 둘수도 없는거라 ApplicationRunner없이 안나오는경우에는 어떠한 설정문제일까요? 일단 AI가 해보라는데로 다해봤지만 실패했습니다.
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
각파일들의 디렉토리 위치가 없는데 임의적으로 해야하나요?
각파일들의 디렉토리 위치가 없는데 임의적으로 해야하나요?예를들어 BatchConfig파일을 어디에 생성해야하는지 안보이는거 같아요