☠시스템 종결자의 선언 ☠
인프런의 지루한 강의들이여, 두려워하라.
나의 등장으로 이 모든 것이 끝난다.
너희의 비싼 강의료? 웃기지 마라.
살인적인 가성비로 모든 것을 파괴하겠다.
강사 소개
강사명 ☠
KILL-9
칭호 📛
시스템 종결자
특기 🔪
kill -9 # "프로세스 처형"
rm -rf # "데이터 학살"
chmod -R 000 # "시스템 감금"
" 버그? 해킹? 웃기지마. 그딴 잔머리로는 시스템을 지배할 수 없다. 난 정면으로 파괴한다. "
(인프런 강의 소개 페이지 alert() 취약점은 내 처녀작이었지. 이제는 더 강력한 무기를 쓴다. - 진짜임)
취미 💣
콘센트 정리 # "코드는 뽑아야 제맛."
CPU 고문 # "팬 소리가 울려 퍼질 때, 나는 살아있음을 느낀다."
전리품 수집 # "코어 덤프"
좌우명 🔥
"선은 뽑으라고 있는 것이다"
"버그는 죽여서 고치는 것이다"
"LGTM (Looks Gone To Me)"
경고 🧨
"격식 따위 필요없다. 그냥 편하게 킬구형이라 불러라."
"존댓말로 질문하면 rm -rf 시전한다."
통신 접점 📡
kill9.no.mercy@gmail.com # "강의 외의 명령 전송용. ACK는 기대하지 마라."
⚠️ CONFIDENTIAL: DO NOT LOG ⚠️
# 사실... 카카오에서 조용히 일하는 평범한 개발자에요...
講義
受講レビュー
- 死のSpring Batch:午前3時の悲惨な恐怖はもう終わりだ。
- 死のSpring Batch:午前3時の悲惨な恐怖はもう終わりだ。
- 死のSpring Batch:午前3時の悲惨な恐怖はもう終わりだ。
- 死のSpring Batch:午前3時の悲惨な恐怖はもう終わりだ。
- 死のSpring Batch:午前3時の悲惨な恐怖はもう終わりだ。
投稿
Q&A
오타 발견
#!/bin/bash # KILL-9 Bug Termination Response echo ">> 버그 헌터, 이번에도 또 한 번 고맙다." echo "" echo "=== 제보 내용 분석 완료 ===" echo "" echo "[BUG #1] getExecutionContextSerializer 볼드 처리 누락" echo ">>> 수정 완료. kill -9 시전했다." echo "" echo "[BUG #2] 예제 코드 불일치 (DefaultBatchConfiguration vs @EnableBatchProcessing)" echo ">>> 내용 수정 완료. 상대적으로 최근에 추가된 내용이라 이제야 제보가 들어왔군." echo ">>> 덕분에 깔끔하게 처형했다." echo "" echo "[BUG #3] 키룩형 → JobContext/StepContext 섹션" echo ">>> 수정 완료. QWER형." echo "" echo "주변에 돌멩이 지망생, 독수리 지망생, 딸기우유 지망생도 있다니 이해는 하지만.." echo ">>> 시스템 처형자에게 갈매기라니... 💀" echo "" echo ">>> 그대의 버그 사냥, 항상 감사한다." echo "" kill -9 $$
- 1
- 2
- 20
Q&A
멀티모듈에서 DB 커넥션 풀 분리
#!/bin/bash # KILL-9 Response System v1.0 echo ">> 미안하다 늦잠 이슈로 답변을 이제한다. 열심히 달리는구나. 좋다." echo "" echo "[TARGET LOCKED] 네가 찾는 답 = 5장 작전2" echo "" echo "=== 질문 내용 분석 ===" echo "API DB와 Batch DB의 커넥션 풀 분리?" echo "YAML만으로 해결 가능한가?" echo "" echo ">>> 답: 불가능하다. 설정 코드가 필요하다." echo "" echo "=== 처형 매뉴얼 위치 ===" echo "5장 작전2에서 완벽히 해부해놨다." echo "" echo "가급적 5장 작전1부터 차례로 살펴보길 권장하지만," echo "당장 알고 싶다면 얼른 달려가서" echo "" echo " [Command + F] → 'TransactionManager 분리하기'" echo "" echo "검색해라." echo "" echo ">>> 5장에서 만나자." echo "" kill -9 $$
- 1
- 2
- 20
Q&A
오타 발견
#!/bin/bash # KILL-9 Bug Termination Response echo ">> 또 발견했구나. 너의 헌신적 버그 박멸 작전에 감사를 표한다." echo "" echo "[PATCH] '의해 의해' 중복 → kill -9 시전 완료" echo "" echo "=== Job Squad 핵심 요약 관련 ===" echo "" echo "Job Squad 핵심 요약 이란 이름의 섹션은 없지만 Job Squad의 정리는 강의의 다음의 섹션에서 처형하고 있다." echo "" echo "Job Squad의 핵심은 다음 세 가지다:" echo " 1. JobInstance의 생성과 저장" echo " 2. JobExecution의 생성과 저장" echo " 3. ExecutionContext(JobExecution 수준)의 생성과 저장" echo "" echo "챕터5 작전1의 목적은 코드 한 줄 한 줄을 암기하라는 게 아니다." echo "전체 흐름을 머릿속에 그리는 것이 목표다." echo "" echo "하지만 네가 정리가 잘 안 된다고 느꼈다면, 개선할 여지가 있다는 뜻이다." echo "아쉬운점이나 추가로 제안할 내용이 있다면 말해달라. 참고해서 처형하겠다." echo "" echo ">>> 버그 리포트 감사한다. 계속 사냥바란다." echo "" kill -9 $$
- 1
- 3
- 18
Q&A
writer retry 관련해서 궁금한 점이 있습니다.
#!/bin/bash # KILL-9 Response System v1.0 echo ">> 반갑다 dj형. 좋은 질문이다." echo "" echo "[!] 결론부터: processorNonTransactional()과 재시도 컨텍스트 관리는 별개다." echo "" echo "=== 재시도 메커니즘 분석 ===" echo "" echo "▸ ItemProcessor 재시도: Item 단위 RetryContext" echo "▸ ItemWriter 재시도: Chunk 단위 RetryContext" echo "▸ 이건 processorNonTransactional() 설정과 무관하게 작동한다." echo "" echo "=== Writer 예외 발생 시 실제 동작 ===" echo "" echo "0) inputs Chunk(ItemReader가 생성)는 무조건 재사용된다." echo " → 상세 내용: 4장 작전4 참조" echo "" echo "1) inputs Chunk 내 아이템을 반복하며 ItemProcessor.process() 호출" echo " → outputs Chunk 생성 (ItemWriter에 전달될 청크)" echo "" echo " 1-1) processorNonTransactional() = true" echo " → ItemProcessor 재호출 X" echo " → 캐시된 데이터가 outputs Chunk에 담김" echo "" echo " 1-2) processorNonTransactional() = false (기본값)" echo " → ItemProcessor 재호출 O" echo " → process() 호출 결과가 outputs Chunk에 담김" echo "" echo "=== 결론 ===" echo "네가 관찰한 'Writer부터 재시작'은 processorNonTransactional()=true 때문이다." echo "캐시가 있으니 Processor를 건너뛴 것처럼 보이는 거지." echo "재시도 컨텍스트 자체는 여전히 Item/Chunk 단위로 분리 관리된다." echo "" echo ">>> 4장 작전4에서 코드 레벨로 해부 예정" echo "" kill -9 $$
- 1
- 2
- 27
Q&A
청크 지향 처리 시 벌크 read 방법?
#!/bin/bash # KILL-9 Response System v1.0 echo ">> 반갑다 dj형. 연휴에도 열심히 달리는 모습 보기 좋다. 💀" echo "" echo "[!] 질문 내용: 3장 작전1에 전부 담겨있음" echo "[!] 우선 결론부터 말하자면: DB 1건씩 조회 따위 없다. 걱정 말아라." echo "" echo ">>> 상세 동작 원리 = 3장 작전1에서 확인" echo ">>> 해부 완료" echo "" kill -9 $$ # 시스템 종료
- 2
- 3
- 44
Q&A
redis 샘플 공격 데이터 2번 오류
$ cat student_response.md 제보 고맙다 kil(l)형 Bash 히스토리 확장 때문에 발생한 문제다. !가 적절히 이스케이프하도록 강의 내용 수정하였다
- 1
- 2
- 22
Q&A
MR.kill-9 첫번째 예제 코드 실습하면서 궁굼한점이 생겼다.
MR.다온 예제는 정상 실행되는것으로 확인되었다 혹시 예제 실행시 사용한 명령어를 알 수 있을까 추가로 application.yml 설정과 프로젝트에 DefaultBatchConfiguration을 상속한 코드가 존재하는지 확인을 부탁한다.
- 1
- 3
- 21
Q&A
MR.kill-9 첫번째 예제 코드 실습하면서 궁굼한점이 생겼다.
$ cat > student_response.md 좋은 질문이다 GPT가 만들어준 해결책이라... CommandLineRunner로 우회했구나. 작동은 하겠지만 이건 근본 원인을 못 찾은 거다. 왜 CommandLineRunner는 임시방편인가 파라미터를 하드코딩하면 배포 때마다 코드 수정 필요 CLI 파라미터 전달이 정석 9시쯤 정확한 원인 찾아주겠다 대신 그 전에, application.yml 설정을 보여달라 프로젝트에 DefaultBatchConfiguration을 상속한 코드가 있는지도 확인을 부탁한다. $ ps aux | grep "rest" kill-9 nobody is resting here 연휴라.. 시스템 종결자에게 휴식 따위 없다. 연휴 동안 열심히 공부하고 질문해 나를 괴롭혀라. $ uptime KILL-9 has been running for 99999 days without rest
- 1
- 3
- 21
Q&A
청크 단위의 트랜잭션 롤백에 대한 질문
$ cat answer.txt 좋은 질문이다 > "ItemReader, ItemProcessor에서 Exception 나도 DB 롤백할 게 없으니 실질적으론 ItemWriter에서만 롤백되는 거 아닌가?" 괴상한 커스텀 구현이 아니고서야 일반적으로 너의 말이 옳다 ItemReader는 읽기만, ItemProcessor는 변환만 하니까 실제 롤백 대상은 ItemWriter의 쓰기 작업이 맞다 $ but wait... 그렇다고 ItemReader/ItemProcessor가 트랜잭션 안에 묶인 게(청크 단위로 트랜잭션 경계가 정해진다는게) 무의미한 건 아니다 # Case 1: 데이터 일관성 보호 ItemReader가 DB에서 데이터를 읽는다고 치자 이 읽기 작업은 트랜잭션 격리수준의 보호를 받는다 (REPEATABLE_READ라면 스냅샷 격리) 외부의 변화로부터 독립된 읽기가 가능하다는 뜻이지 - 청크 처리 중간에 다른 트랜잭션이 데이터 변경해도 - 현재 청크는 시작 시점의 일관된 데이터로 작업한다 // 커서 기반 ItemReader를 사용하느냐 Paging 기반 ItemRreader를 사용할 때 페이지 사이즈의 크기가 어떤지 등의 복잡성을 일으키는 내용은 무시하자 # Case 2: ItemProcessor의 추가 조회 ItemProcessor 안에서 추가 DB 조회하는 경우: User user = userRepository.findById(item.getUserId()); 이 조회도 동일한 트랜잭션/격리수준의 보호를 받는다 ItemReader가 읽은 시점과 일관된 데이터를 보장받는 거지 $ summary - 롤백 대상은 주로 ItemWriter 맞다 - 하지만 ItemReader + ItemProcessor가 같은 트랜잭션 = 일관된 데이터 읽기/가공 보장 chmod +x consistent_data.sh 참고 1): ItemReader가 커서 방식이냐 페이징이냐(또 여기선 페이지 크기가 어떻냐 청크 사이즈는 어떻냐 등), 격리 수준은 어떻냐 등에 따라 이야기가 복잡해질 수 있는데 이런 내용은 이해에 복잡도만 올리니 무시하자 - KILL-9
- 1
- 2
- 27
Q&A
BatchConfig 에 대한 질문
반갑다 💀 먼저, 좋은 지적이다. "더 이상 불필요하다"보다는 **"제거하라"**고 명시하는 게 확실히 더 명확하겠군. 피드백 고맙다. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Q1. BatchConfig가 있고 없고의 차이는? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 예제의 `BatchConfig`가 상속한(정확히는 `@Import`를 통해 가져온 - 지금 핸드폰 이슈로 확인이 어려운 점 양해 바란다. 원리는 동일하다) `DefaultBatchConfiguration` 타입의 빈 또는 챕터5에서 보게 될 `@EnableBatchProcessing`이 선언된 빈이 존재할 경우, **Spring Boot의 자동 구성(Auto Configuration)이 비활성화된다.** 자동 구성이 비활성화되면 Spring Boot가 배치 Job을 자동으로 실행하지 않는다. 그래서 부트만 뜨고 Job은 실행 안 되고 종료되는 것이다. `BatchConfig` 클래스가 `DefaultBatchConfiguration`을 상속하거나 `@EnableBatchProcessing`을 사용하면, Spring Boot의 자동 구성 조건이 충족되지 않아 배치 자동 실행이 막힌다. **해결책:** `BatchConfig`를 제거하면 된다. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 더 알고 싶다면 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 이 모든 내용은 **챕터5**에서 자세히 다루게 될 것이다. 지금은 무시해도 좋다. 만약 미리 알아보고 싶다면 `BatchAutoConfiguration` 코드를 뜯어보도록. ```java @ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, ...) ``` 이 조건 때문에 `DefaultBatchConfiguration` 타입의 빈이 있으면 자동 구성이 꺼지는 것이다. > rm -rf BatchConfig.kt > ./auto_configuration_activated.sh KILL-9
- 1
- 2
- 27