J juno.log

Resume

최준호

Backend / Server Engineer

대용량 데이터의 성능과 정합성 문제를 무중단으로 풀어 온 백엔드 엔지니어

19h 41m→30m

부가세 배치 97.5% 단축

93.9%

AI 코드리뷰봇 운영 (830건)

2억 건

발송 이력 무중단 이관

p95 80~84%

판매관리 API 단축

Resume

이력서

대용량 데이터 처리와 무중단 전환 경험을 중심으로 정리한 백엔드 이력서

200만 소상공인이 사용하는 금융 장부 서비스에서 대용량 배치, 데이터 이관, API 성능 개선을 맡아 왔습니다. 단일 writer DB, 신규 인덱스 제한 같은 까다로운 운영 조건에서도 병목을 측정하고 서비스 영향을 통제하며 데이터 경로와 구조를 개선했습니다.

백엔드 개발에만 머무르지 않고 Databricks 파이프라인부터 운영 화면까지 직접 구현합니다. AI 비서 백엔드와 사내 코드리뷰봇·검수봇도 설계부터 운영까지 맡아 제품과 팀의 개발 효율을 함께 높였습니다.

Experience

한국신용데이터

백엔드 엔지니어 (장부팀)

2025.01 ~ 현재 (1년 6개월)

200만 소상공인이 사용하는 금융 장부 서비스에서 대용량 배치, 데이터 이관, 핵심 API와 운영 화면을 개발했습니다. 맡은 기능은 설계부터 배포와 운영까지 책임졌습니다.

  • 부가세 배치 19시간 41분 → 약 30분 단축 (100만+ 사업장, Databricks 집계 기반 재설계).
  • 발송 이력 2억 건을 Dual Write로 기존 쓰기 경로를 유지하며 이관 (서비스 중단 없음).
  • 판매관리 핵심 API p95 80~84% 단축 (쿼리 재작성·무중단 인덱스 추가).
  • 복권 리워드 지급에 트랜잭셔널 outbox 멱등 파이프라인 설계 (비멱등 외부 발급 API 위 중복 지급 방지, 동일 키 32 동시요청 → 외부 호출 1회 검증).

한국신용데이터

데이터실 AI TF (겸직)

2025.04 ~ 2025.09 (6개월)

소상공인용 AI 비서 백엔드를 단독으로 설계하고 구현했습니다. 채팅과 실시간 스트리밍뿐 아니라 정책 엔진과 유료 멤버십까지 맡았습니다.

  • AI 비서의 채팅, 정책 엔진, 유료 멤버십 백엔드를 단독으로 설계하고 구현.
  • SSE 실시간 스트리밍 API를 신설해 AI 답변을 토큰 단위로 즉시 전달, 응답 대기 없는 채팅 경험을 구현.

Skills

Languages
Java · Kotlin · TypeScript
Frameworks
Spring Boot · Spring Batch · JPA
Data
PostgreSQL · MySQL · Redis · SQS
Infrastructure
AWS · Docker · Jenkins · Datadog
AI
Claude Agent SDK · Spring AI

AI Experience

사내 AI 생산성 도구를 직접 설계·구축해 운영하고 있습니다. AI 앰버서더 2기로 활동하며 실무에서 검증한 활용법을 사내에 공유합니다.

  • Claude Agent SDK 기반 코드리뷰 봇을 직접 구축해 운영했습니다. 830건을 기준으로 리뷰 실행 p50 2.6분, 성공률 93.9%를 기록했습니다.
  • 멀티모달 이미지와 텍스트를 확인하는 알림톡 검수 봇 MVP를 1시간 40분 만에 만들어 수작업 검수를 없앴습니다.
  • AI 앰버서더 2기로 테크톡 3회와 Office Hour 11회+를 운영하며 실무 활용 사례를 공유했습니다.

Growth

기술 공유
사내 테크톡 3회 · AI Office Hour 11회+ 운영
오픈소스
REST-assured Kotlin Extension · Spring Boot 3.3 호환성 개선

Community

  • Nexters 25기 백엔드 개발자, 26기 회장
  • 우아한테크코스 5기 백엔드 수료 (2023.02 ~ 2023.11)

Education

  • 한국기술교육대학교 컴퓨터공학부 (2019.03 ~ 2026.02, 졸업)

Portfolio

프로젝트 상세

문제–해법–결과를 중심으로 정리한 8개 프로젝트

부가세 예상세액 배치 성능 재설계

한국신용데이터 · 2025.06 ~ 2025.08

Kotlin Spring Batch Databricks Delta Tables PySpark

100만+ 사업장 · 19시간 41분 → 약 30분 (97.5% 단축)

Problem
약 100만 사업장의 예상세액 계산에 19시간 41분이 걸렸습니다. 원본 카드매출을 직접 조회하는 구조라 단일 writer DB에 배치, API, 통계 쿼리가 몰렸습니다. 커넥션 풀 분리와 배치 튜닝만으로는 마감 시간을 맞출 수 없었습니다.
Solution
계산 작업을 OLTP 밖으로 옮기고 데이터실과 함께 부가세 전용 Delta Tables 증분 집계를 만들었습니다. 카드매출은 사전 집계값을 조회하도록 바꾸고, 매입세액 약 7천만 건은 월별로 나눠 처리해 GC 실패를 없앴습니다.
Result
전체 계산 시간을 약 30분으로 줄여 마감 전에 부가세 알림을 안정적으로 발송했습니다.
병목을 애플리케이션 밖으로 옮긴 구조 전환

Before · OLTP 집중

  1. 원본 카드매출
  2. 단일 Writer DB
  3. 전 사업장 재계산

After · 계산 경로 분리

  1. Delta 증분 집계
  2. 월별 분할 처리
  3. 사전 집계값 조회

19시간 41분 → 약 30분 · 97.5% 단축

  • 동시성을 높여도 단일 writer DB의 I/O 병목이 해소되지 않아 애플리케이션 병렬화 대신 데이터 경로를 바꿨습니다.
  • 매출세액, 매입세액, 경감공제를 각각 증분 처리해 전체 재계산 비용을 줄였습니다.

발송 이력 2억 건 무중단 이관

한국신용데이터 · 2025.11 ~ 2025.12

Kotlin PostgreSQL JDBC Dual Write Databricks

2억 건 · Dual Write · 기존 쓰기 경로 유지

Problem
두 DB에 흩어진 알림 발송 내역을 통합해야 했습니다. 초기 upsert 방식은 대량 적재 성능이 낮았고 JPA 기반 이관은 OOM을 일으켰습니다.
Solution
범위별로 DELETE한 뒤 batch INSERT하도록 바꾸고, 배치 크기를 30,000건, 조회 범위를 1주로 제한했습니다. 별도 v2 테이블과 Dual Write로 신규 데이터의 정합성을 유지했습니다. 이관 과정에서 연도 필터와 enum 매핑 버그도 발견해 수정했습니다.
Result
운영 중인 테이블에 영향을 주지 않고 2억 건을 이관했습니다. 사장님별 발송 이력은 한 곳에서 조회하도록 통합했습니다.
실시간 트래픽과 과거 데이터의 병렬 이관
Lane / Phase 01Dual Write02Backfill03Reconcile04Read Switch 실시간 트래픽 v1·v2 동시 기록신규 쓰기 계속동시 기록 유지v2 조회 전환 과거 2억 건 범위 확정30,000건씩 적재자동 정합성 대사이관 종료

01Dual Write

실시간 트래픽
v1·v2 동시 기록
과거 2억 건
범위 확정

02Backfill

실시간 트래픽
신규 쓰기 계속
과거 2억 건
30,000건씩 적재

03Reconcile

실시간 트래픽
동시 기록 유지
과거 2억 건
자동 정합성 대사

04Read Switch

실시간 트래픽
v2 조회 전환
과거 2억 건
이관 종료

서비스 중단 0 · 단계별 롤백 가능

  • 단독으로 분석·설계·구현했습니다.
  • 반복 실행해도 결과가 달라지지 않도록 적재 구조를 설계해 부분 실패 시 복구 비용을 줄였습니다.
  • 이관 중에는 모니터링 봇이 데이터 정합성을 자동으로 대사하도록 했습니다.

판매관리 API 성능 개선

한국신용데이터 · 2026.05 ~ 2026.06

Kotlin Spring Boot MySQL EXPLAIN ANALYZE Online DDL

6.39억 행 · 핵심 API p95 80~84% 단축

Problem
약 6.39억 행(1.3TB)의 원본 POS 테이블을 조회해 인기 메뉴 응답에 최대 30초가 걸렸고, 90일 조회는 타임아웃됐습니다. 다른 조직이 관리하는 테이블이라 신규 인덱스 추가도 원칙적으로 불가능했습니다.
Solution
실행 계획을 확인해 불필요한 조인을 제거하고, 임시 테이블로 중복을 제거하던 쿼리를 EXISTS로 바꿨습니다. 조회하는 파티션을 84개에서 약 7개로 줄였고, 꼭 필요한 인덱스 1건만 Online DDL로 추가했습니다.
Result
인기 메뉴 p95 944.7ms → 185.7ms, 메뉴 이상 감지 174.9ms → 37.4ms, 판매 알림 246.1ms → 40.2ms로 단축하고 90일 타임아웃을 해소했습니다.
프로덕션 일별 p95 응답 시간 비교
인기 메뉴80% 단축
944.7ms
185.7ms
메뉴 이상 감지79% 단축
174.9ms
37.4ms
판매 알림84% 단축
246.1ms
40.2ms
  • 단독으로 분석·구현했습니다.
  • 함수 조인 키 때문에 발생한 성능 회귀는 당일 롤백한 뒤 다시 구현했습니다. 재발을 막기 위해 인덱스를 활용하기 쉬운 쿼리 작성 지침도 정리했습니다.

복권 리워드 지급 tx-outbox 멱등 설계

한국신용데이터 · 2026.05 ~ 2026.06

Kotlin Spring Batch PostgreSQL Transactional Outbox 멱등성

비멱등 외부 발급 API 위 멱등 지급 보장 · 동일 키 32 동시요청 → 외부 호출 1회

Problem
장부 미션 35종을 수행하면 복권 리워드를 지급해야 했습니다. 그런데 외부 리워드 발급 API가 호출할 때마다 발급되는 비멱등 방식이라, 중복 지급을 막을 책임이 호출하는 장부 쪽에 있었습니다. 미션마다 멱등 범위도 평생 1회, 일, 주, 월로 제각각이었습니다.
Solution
트랜잭셔널 outbox 기반 멱등 지급 파이프라인을 설계했습니다. 자연키 복합 UNIQUE로 PENDING 상태를 선점해 동시 요청을 막았고, 외부 발급 호출은 트랜잭션 밖에서 수행해 DB 커넥션을 점유하지 않게 했습니다. 성공하면 지급을 확정하고, 실패하면 outbox에 보존해 relay 워커가 백그라운드에서 재시도하다 한도를 넘기면 DEAD로 격리했습니다. outbox와 지급 양쪽의 멱등 키는 (사업장×유저×미션×주기버킷) 같은 단위로 맞췄습니다.
Result
미션 35종을 하나의 멱등 키 체계로 일반화하고 단위 테스트 62개로 검증했습니다. 동일 키로 32개를 동시에 요청해도 외부 호출이 정확히 1회만 일어나는지를 동시성 테스트로 확인했습니다. 적대적 자가 리뷰로 멀티사업장 멱등 불일치 같은 잠복 결함을 출시 전에 잡아 2026년 6월 프로덕션에 배포했습니다.
트랜잭셔널 Outbox 멱등 지급 흐름
Prepare 리워드 claim 자연키 복합 UNIQUE로 PENDING 선점 (동시요청 차단)
Send Core 외부 발급 호출 (트랜잭션 밖) DB 커넥션 비점유
성공 → 지급 확정 outbox PUBLISHED
실패 → relay 재시도 Spring Batch 워커 백그라운드 재시도
한도 초과 → DEAD 격리 중복 발급 위험 바운딩

동일 키 32 동시요청에도 외부 호출 정확히 1회 (동시성 테스트 검증)

  • 단독으로 설계·구현했습니다.
  • 외부 발급이 비멱등이라, outbox와 지급 양쪽에 복합 UNIQUE를 걸어 멱등성을 이중으로 방어했습니다.
  • 도메인 로직은 Spring·JPA 의존 없이 순수 Kotlin으로 분리했습니다.

AI 비서 실시간 스트리밍 백엔드

한국신용데이터 · 데이터실 AI TF · 2025.04 ~ 2025.09

Kotlin Spring MVC SSE Coroutines Spring AI

백엔드 1인 · 실시간 응답 스트리밍

Problem
AI 답변이 완성될 때까지 사용자는 빈 화면에서 기다려야 했습니다. 백엔드 개발자 한 명이 채팅, 스트리밍, 정책, 멤버십을 모두 설계해야 했습니다.
Solution
단방향 응답에 맞춰 SSE를 선택하고 청크, 도구 상태, 완료 신호로 구성된 응답 형식을 설계했습니다. 사용 한도 정책은 일별, 월별, 이벤트 규칙으로 나누고 Spring AI로 호출 방식을 추상화했습니다.
Result
채팅 API, 실시간 스트리밍, 정책 엔진, 유료 멤버십까지 4개 영역을 단독으로 설계하고 구현했습니다.
응답 생성과 저장 시점을 분리한 SSE 시퀀스
ClientChat APIAI ServiceStorage
질문 + SSE 연결
정책·멤버십 검증 후 요청
chunk / tool_state 반복
완료 신호를 받은 뒤 메시지 저장
  1. Client Chat API 질문 + SSE 연결
  2. Chat API AI Service 정책·멤버십 검증 후 요청
  3. AI Service Client chunk / tool_state 반복
  4. Chat API Storage 완료 신호를 받은 뒤 메시지 저장
  • 응답이 완료된 뒤에만 메시지를 저장해 스트리밍 중간 상태가 영속 데이터에 섞이지 않도록 했습니다.

AI 코드리뷰봇 자체 구축·운영

한국신용데이터 · 2025.12 ~ 현재

Claude Agent SDK Python FastAPI LSP

운영 830건 · p50 2.6분 · 성공률 93.9%

Problem
코드 리뷰 등록까지 수십 분이 걸렸습니다. AI SDK 4개에 의존했고 대규모 변경을 분석할 때 타임아웃이 발생해 운영 구조도 복잡했습니다.
Solution
저장소 캐시와 언어별 프롬프트를 적용하고, 리뷰 결과를 핵심과 상세로 나눠 출력하도록 바꿨습니다. AI 연동은 Claude Agent SDK 하나로 통합했습니다. Critical 이슈가 발견되면 변경 요청을 남기는 품질 게이트도 추가했습니다.
Result
리뷰 대기 시간을 2~3분으로 줄였습니다. 운영 데이터 830건에서 p50 2.6분, 성공률 93.9%를 기록했고 여러 저장소에 적용했습니다.
코드 리뷰 실행 구조 개선

Before

  • AI SDK 4개 결합
  • 저장소 매번 재탐색
  • 대용량 변경 타임아웃

After

  • Claude Agent SDK 단일화
  • 저장소·컨벤션 캐시
  • 품질 게이트 자동화
  • AI 호출 경로와 비용·감사 로그를 단일 SDK에서 관리하도록 정리했습니다.

KOIN 레거시 API 마이그레이션 & 동아리 개편

BCSDLab · 동아리 회장 · 2019.09 ~ 2024.12

Java Spring MySQL 이벤트 스토밍 리더십 KOIN_API_V2

단발성 프로젝트 난립 → KOIN 단일 체제 · 레거시 → KOIN_API_V2 전면 마이그레이션

Problem
단발성 포트폴리오용 프로젝트가 반복해서 생겼다 중단되며 동아리 리소스와 온보딩 비용을 잠식했습니다. 레거시 API도 유지보수가 어려운 구조였습니다.
Solution
회장으로서 동아리를 단일 프로젝트(KOIN) 체제로 개편하고, 이벤트 스토밍 워크숍으로 도메인을 다시 설계했습니다. 레거시 API는 KOIN_API_V2로 단계적으로 마이그레이션했습니다.
Result
어드민을 제외한 모든 서비스의 마이그레이션을 완료해 함께 개발하고 유지할 수 있는 코드베이스로 전환했습니다.
난립하던 단발성 프로젝트 체제에서 KOIN 단일 체제로

Before

  • 단발성 포트폴리오용 프로젝트 난립
  • 유지보수 어려운 레거시 API
  • 높은 온보딩 비용

After

  • KOIN 단일 프로젝트 체제
  • 이벤트 스토밍 기반 도메인 재설계
  • KOIN_API_V2 전환 (어드민 외 완료)
  • 동아리 회장으로서 회원·트랙·프로젝트 현황을 점검하고 조직 문화 개편을 함께 추진했습니다.

Pium 조회 성능 개선 & 무중단 배포

우아한테크코스 · 반려식물 관리 서비스 · 2023.06 ~ 2023.11

Java Spring Boot JPA N+1 Blue/Green

조회 쿼리 7회 → 1회 · TPS +11% · 배포 다운타임 30초 → 0

Problem
7인 팀(FE 3, BE 4)으로 반려식물 관리 서비스를 만들면서, 조회 한 번에 N+1 쿼리가 발생해 응답이 느렸고 배포할 때마다 약 30초의 다운타임이 생겼습니다.
Solution
연관 조회의 N+1을 제거해 조회 쿼리를 7회에서 1회로 줄이고, Blue/Green 배포를 도입해 배포 중에도 서비스가 끊기지 않도록 했습니다.
Result
조회 TPS를 11% 높이고 배포 다운타임을 없앴습니다.
조회 성능과 배포 안정성 개선
조회 쿼리 수86% 감소
7회
1회
배포 다운타임무중단 전환
30초
0초
  • 사용자가 체감하는 조회 속도와 배포 안정성을 우선순위로 잡고 개선했습니다.

For fellow developers

숫자 뒤에 있는 이야기가 궁금하다면

코인 백엔드로 시작해 지금에 이르기까지, 각 단계에서 무엇을 배우고 성장했는지를 시간순으로 풀어놨어요.

개발자로서의 여정 보기