전체 글
-
파드가 죽으면 상태는 누가 바꾸나 — 대용량 엑셀 다운로드 (2)회사 2026. 8. 13. 20:27
1편에서 요청마다 파드를 띄우는 구조로 바꿨습니다. 그런데 그 파드가 죽으면 작업 상태를 바꿔줄 사람이 없어집니다. catch도 finally도 실행되지 않는 실패를 어떻게 다뤘는지, 그 과정에서 만난 버그들을 정리했습니다.들어가며1편의 결론은 이랬습니다. 요청 1건 = 파드 1개. API 서버가 작업을 DB에 넣고 Argo REST API로 파드를 띄우면, 파드가 자기 몫만 처리하고 종료합니다.깔끔해 보였습니다. 그런데 코드를 보다가 이상한 걸 발견했습니다.public void generate(UUID downloadId) { DownloadRequest request = load(downloadId); try { runGeneration(request); // ..
-
테스트 직전에 엎은 설계 — 대용량 엑셀 다운로드 (1)회사 2026. 8. 13. 19:10
정산 시스템에 100만 행 규모의 엑셀 다운로드를 붙이면서, 파일을 만들 곳을 두 번 옮겼습니다.API 서버에서 배치 서버로, 그리고 폴링에서 온디맨드 파드로.코드를 다 쓰고 테스트 직전에 지운 v1과, 그 과정에서 배운 것을 정리했습니다. 들어가며레거시 정산 시스템을 현대화하는 프로젝트를 하고 있습니다. 기존 시스템에는 없던 신규 기능 중 하나가 조회 결과 엑셀 다운로드였습니다. 어드민에서 기간·제휴사·브랜드 조건으로 정산 내역을 조회하고, 그 결과를 엑셀로 받아 회계 자료로 쓰는 흐름입니다.100만 행이면 동기 응답은 처음부터 불가능합니다. 게이트웨이 타임아웃은 물론이고, 브라우저가 몇 분씩 로딩 상태로 멈춰 있는 것도 받아들일 수 없습니다. 그래서 비동기는 시작부터 전제였습니다. 문제는 그다음이..
-
LIMIT이 세 번인 이유 — 2단 구조로 50초를 밀리초로 (3/3)회사 2026. 7. 12. 14:06
1편에서 커서가 4필드가 된 이유를, 2편에서 분기별 keyset 조건이 유도되는 과정을 봤다. 마지막 편은 성능이다. 첫 버전은 50초가 걸렸다 — 최종 쿼리는 밀리초로 돌고, LIMIT이 세 번 등장한다. 각 LIMIT이 왜 거기 있는지, 그리고 "잘라도 정답이 보장되는가"라는 질문에 답한다.1편: 커서가 4개가 된 이유2편: 분기별 keyset의 논증3편: LIMIT이 세 번인 이유 (이 글) v1의 실패 — 50초첫 버전은 정직하게 짰다. UNION으로 합치고, 부가 정보(정책 테이블의 수수료 계산, 거래 원장의 영수증 번호)를 조인하고, 바깥에서 keyset과 LIMIT을 걸었다.SELECT ..., (정책 조인 계산), (거래 조인 컬럼)FROM ( SELECT ... FROM point..
-
커서가 한쪽에서 끊기면 다른 쪽은 어디서 재개하는가 — 분기별 keyset의 논증 (2/3)회사 2026. 7. 12. 13:55
1편에서 이종 테이블 UNION 목록의 커서가 4필드 (txn_date, source, member_no, seq)가 되는 과정을 봤다. 이번 편이 이 시리즈의 본론이다: keyset 조건을 UNION의 각 분기 안으로 내리면, 같은 커서인데 분기마다 조건의 모양이 달라진다. 왜 그런지 손으로 유도한다.1편: 커서가 4개가 된 이유2편: 분기별 keyset의 논증 (이 글)3편: LIMIT이 세 번인 이유 — 2단 구조로 50초를 밀리초로 문제 재현정렬과 커서를 다시 놓고 시작하자.ORDER BY txn_date, source, member_no, seq-- source: 'E'(적립) cursor = (txn_date, source, member_no, seq) = 마지막으로 응답한 행의 정..
-
UNION 두 테이블에 커서 페이징 걸기 — 커서가 4개가 된 이유 (1/3)회사 2026. 7. 12. 13:46
이 시리즈는 서로 다른 두 테이블을 UNION으로 합친 목록에 커서 기반 페이지네이션을 거는 과정의 기록이다. 커서 페이지네이션 자체는 좋은 글이 이미 많다 — 이 시리즈가 다루는 건 그 글들이 멈춘 지점, 정렬 축에 "출처 테이블"이 끼어드는 순간부터다.1편: 커서가 4개가 된 이유 (이 글)2편: 커서가 한쪽에서 끊기면 다른 쪽은 어디서 재개하는가 — 분기별 keyset의 논증3편: LIMIT이 세 번인 이유 — 2단 구조로 50초를 밀리초로 상황정산 백오피스의 거래 내역 화면을 개발하고 있었다. 요구사항은 단순해 보였다.포인트 적립 내역과 사용 내역을 한 목록에서 보여줄 것정렬은 일자순무한스크롤문제는 적립과 사용이 서로 다른 테이블이라는 것이다. 레거시 시절부터 쌓여온 원천 테이블이라 구조를 바꿀 ..
-
레거시 정산 시스템의 예외 처리, 2축 모델 설계회사 2026. 7. 5. 12:53
레거시 정산 시스템(iBatis + Oracle PL/SQL 배치)을 Java 21 / Spring Boot 4 스택으로 옮기면서, 예외 처리부터 다시 세웠다. 그 과정에서 마주친 설계 판단들과, 검증하다 발견한 실제 버그(없는 경로가 500을 반환하던 문제)를 정리한다.들어가며레거시 정산(settlement) 시스템을 현대화하는 마이그레이션을 하고 있다. AS-IS는 애플리케이션 계층이 iBatis 기반이고, 정산 배치는 Oracle PL/SQL 프로시저를 셸 스크립트로 돌리는 구조였다. 이걸 Java 21 / Spring Boot 4 / Spring Batch 스택으로 옮긴다. 새 프로젝트는 DDD + 헥사고날 구조의 Gradle 멀티모듈로 되어 있다. 이 서버는 내부 정산용이라, 외부 시스템과 직접..
-
AI를 위한 파이썬 복습프로젝트 2026. 4. 4. 17:03
https://docs.python.org/ko/3/tutorial/ The Python TutorialPython is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python’s elegant syntax an...docs.python.org https://www.youtube.com/watch?v=mEeZoDGITGw&list=PLU9-uwewPMe05-khW3YcDEaHMk_qA-7lI&index=2https://wikidocs.net/4307 개발 입문했던..
-
현재 Spring Security 구조이커머스 devops 2026. 1. 7. 15:07
로그인 전체 흐름1단계 : 로그인 요청클라이언트 ↓POST /api/auth/loginContent-Type: application/json{ "email": "user@example.com", "password": "1234"} 2단계: RestAuthenticationFilter 실행┌────────────────────────────────────────────────┐│ RestAuthenticationFilter ││ (AbstractAuthenticationProcessingFilter) │└────────────────────────────────────────────────┘ ↓ attemp..