김병찬

Backend Engineer

chan4527@naver.com
github.com/GitBchan

눈에 보이는 증상이 아니라 진짜 원인을 찾을 때까지 파고드는 백엔드 개발자입니다. 느리거나 이상하게 동작하는 문제를 만나면 추측으로 고치지 않고, 측정하고 재현해 원인을 좁힌 뒤 최소한으로 고치는 방식을 선호합니다.

특히 보안·동시성·장애처럼 평소엔 드러나지 않지만 터지면 큰 지점을 코드와 데이터로 방어하는 데 관심이 많고, 성능 수치를 위해 코드를 넓게 갈아엎기보다 무엇을 고치고 무엇을 안 고칠지 근거를 남기며 결정합니다.

Tech Stack

Java Spring Boot JPA MySQL PostgreSQL Redis AWS Docker

Project — SearchON

AI 검색 노출 진단 서비스SW마에스트로 17기

2026.04–진행중 · 백엔드 단독

ChatGPT·Perplexity 같은 AI 검색에 사이트가 잘 노출되는지 진단하는 서비스. 서버가 사용자 입력 URL을 대신 스캔하는 구조라 보안·동시성·외부연동 안정성이 핵심이었습니다. 스캔 파이프라인을 보안·수집·콘텐츠·스키마 등 10여 개 기능 슬라이스로 분리해 설계하고, 500개 이상의 테스트로 회귀를 방어했습니다.

스캔 파이프라인을 프로파일링해 숨은 병목을 찾아 제거 2.8×
  • 단계별로 시간을 재보니 스캔 시간의 94%가 content 분석 한 단계에 몰려 있었습니다.
  • 중복 파싱부터 없앴는데 10%밖에 안 줄어, 파싱 자체는 병목이 아니라고 보고 다시 측정했습니다. 진짜 원인은 여러 AI 크롤러 관점이 같은 페이지를 받는데도 매번 처음부터 다시 추출하던 것이었습니다.
  • 같은 HTML은 한 번만 추출해 재사용하도록 바꿔(동작은 그대로, 테스트 통과) content 단계를 283ms → 100ms(2.8배), 전체 스캔은 307ms → 121ms로 줄였습니다.
사용자가 넣은 URL을 서버가 대신 요청하는 구조의 SSRF 위험 차단
  • 아무 URL이나 서버가 대신 요청하다 보니, 내부망 주소나 클라우드 메타데이터가 노출될 수 있는 위험이 있었습니다.
  • 외부 요청을 하나의 보안 경로로 통일하고, 사설 IP·리다이렉트 우회·비정상 포트를 미리 검사해 막았습니다.
  • 위험한 요청은 오류로 중단하지 않고 진단 결과로 남겨, 스캔은 계속 진행되도록 했습니다.
예전 공유 링크가 열 때마다 500 에러 나던 하위 호환 문제 발견·수정
  • 스캔 결과를 JSON으로 저장해 공유 링크·캐시에 재사용하는데, 응답 형식을 바꾸면서 캐시 무효화와 하위 호환 처리를 빠뜨려 예전에 만든 공유 링크가 열 때마다 500 에러가 났습니다.
  • 저장된 결과는 코드가 바뀐 뒤에도 남는다는 점을 전제로, 읽어들이지 못하면 500 대신 공유는 404로 돌려주고 캐시는 새로 스캔하도록 바꿨습니다.
  • 잘못된 저장본 하나가 엔드포인트 전체를 무너뜨리던 것을 없애고, 회귀 테스트를 더했습니다.
AI가 못 읽는 페이지를 '정상'으로 잘못 판정하던 것을 실제 측정으로 바로잡음
  • 본문이 JS 렌더링 후에만 나타나는 사이트(예: 다나와)를 기본 기준값으론 "콘텐츠 충분"으로 잘못 판정했습니다.
  • 실제 사이트에서 본문 길이를 직접 재보니 300~436자였고, 이를 근거로 기준값을 올렸습니다. 바뀐 기준은 엔진 버전을 올려 반영했습니다.
  • 해당 유형에서 보이지 않던 콘텐츠 41%를 제대로 잡아내도록 개선했습니다.

Project — Jobveloper

AI 면접 시뮬레이션 서비스캡스톤·산학

2025.03–06 · 백엔드 리드

질문 생성·음성 변환·분석이 이어지는 AI 면접 서비스. 빌드 이후 부하테스트로 병목을 측정·진단하며 리팩토링했습니다.

측정으로 14초짜리 병목을 한 줄 수정으로 해결 — 내 오진단까지 바로잡음 79×
  • 보관함 목록 API가 부하 시 p99 55초·에러 17.8%로, 목록을 여는 것조차 사실상 실패했습니다.
  • 검색이 느린 줄 알았으나 측정하니 진범은 목록에 쓰지도 않는 전체 개수 세기 쿼리가 매번 30만 행을 훑는 것이었고, 반환 방식만 바꿔 제거했습니다.
  • p99 55초 → 0.7초, 에러 17.8% → 0% (응답 형태는 그대로 유지).
N+1이 커넥션 풀 포화의 진짜 원인임을 데이터로 규명 6.8×
  • 세션 상세 API가 부하 시 커넥션 풀 고갈로 요청이 줄줄이 대기(pending 190), p99 1.23초였습니다.
  • 풀을 키워도 안 풀려 요청당 쿼리를 세어보니 한 번에 21개가 나가는 중복 조회(N+1)가 커넥션을 오래 점유하고 있었고, 21 → 4로 줄였습니다.
  • p99 1.23초 → 0.18초, 대기 190 → 0 · 풀 확장보다 쿼리 축소가 답이었습니다.
외부 API·비동기가 얽힌 흐름에서 정합성·중복 제어
  • 무거운 AI 후처리가 저장 트랜잭션보다 먼저 실행돼 아직 없는 데이터를 읽는 버그와, 연속 클릭 시 같은 작업이 중복 실행되는 문제가 있었습니다.
  • 무거운 작업을 커밋 이후로 분리하고, 중복 요청은 분산 락으로 단일 실행을 보장했습니다.
  • 커밋 전 데이터 노출과 중복 처리를 제거했습니다.

일하는 방식. 동기 작업을 비동기로 바꾸면 응답은 빨라 보여도 완료 시간·에러는 오히려 나빠질 수 있어, 이 착시를 응답과 완료 두 지표로 함께 확인했습니다. 계획했던 큰 리팩터링도 측정해 보고 불필요하면 접었습니다. 무엇을 안 할지 정하는 것도 엔지니어링 판단이라고 봅니다.

Etc.

활동 SW마에스트로 17기 (2026.04–11) — SearchON(GEO·AI 검색 노출 진단 서비스) 백엔드 개발
학력 경기대학교 컴퓨터공학부 · 2026.08 졸업예정

S3에 index.html로 업로드 · 인쇄(Ctrl+P) 시 페이지 단위로 끊깁니다