백엔드 · 풀스택

전은성

6년차 백엔드 개발자 · 레거시 개선과 데이터 모델 전환

멈추면 안 되는 시스템을 바꾸는 일을 합니다.

실무
6년차

Java · Spring 중심, 프론트까지

기술 글
79

문제 · 원인 · 해결 기록

운영 시스템
3

탄소배출 · 블록체인 · 장비 관리

기술 스택

문제를 겪고 판단을 내린 것만. 학습만 한 것은 뺐습니다.

백엔드
Java Java Spring Spring Python Python
데이터베이스
PostgreSQL PostgreSQL MySQL MySQL Redis Redis
프론트엔드
React React
인프라
Kubernetes Kubernetes Docker Docker GitHub Actions GitHub Actions Linux Linux
Hyperledger Fabric
AI
Claude Code Claude Code

프로젝트

여기엔 결론만 적었습니다. 대부분 과정이 글에 남아 있습니다.

탄소배출 산정 B2B 웹앱

MySQL · JPA/QueryDSL · Gradle 멀티모듈 · React

제품 단위 탄소배출량을 산정하는 서비스. 스키마 관리, 조회 성능, 누적된 이중 구조를 차례로 정리했습니다.

  • 도입한 도구를 3주 만에 걷어냄

    Flyway가 기존 DB에서는 무사한데 새 DB에서만 실패했습니다. 마이그레이션 도구의 핵심 가치가 재현성인데 그게 깨진 상태였고, 예외를 커스텀 로직으로 계속 흡수하는 쪽은 기각했습니다 — 설정이 221줄까지 자란 시점이 이미 신호였습니다.

    도입 22일 → 철수, 필요한 부분만 자동화로 대체

    Flyway를 3주 만에 걷어낸 이야기 그 뒤 빈틈을 메운 방법

  • 읽기 비용을 쓰기 시점으로

    5중 CTE 뷰가 조회마다 재계산되고 있었습니다. 물질화 테이블로 옮기되 섀도우·전환 2단계로 무중단 롤아웃했고, 갱신 지점은 기존 캐시 무효화 지점만 믿지 않고 전수조사해 가장 빈번한 경로가 빠진 것을 찾았습니다.

    PDF 생성 6.4s → 0.7s

    뷰를 물질화 테이블로 N+1 제거 4종 세트 PDF 7초의 범인

  • 같은 버그를 두 번 고친 날

    V1/V2 이중 스택이 남아 한 버그를 양쪽에서 고쳐야 했습니다. 단계를 나눠 통합했고, 도달 불가능한 파일도 함께 걷어냈습니다 — 죽은 코드가 더 최신이라 판단 근거를 오염시키던 상태였습니다.

    2,389줄 삭제 · 죽은 파일 102개 정리

    같은 버그를 두 번 고친 날 죽은 파일이 더 최신이었다

블록체인 DevOps 플랫폼 공공

Java 21 · Spring Boot · Kubernetes · Hyperledger Fabric/Besu · Next.js · 폐쇄망

공공 스마트시티 사업 · 약 6개월 백엔드 · 인프라 담당 · 프론트 협업 1명

기관마다 격리된 Kubernetes 클러스터와 블록체인 네트워크를 REST API 한 번으로 만들어 주는 멀티테넌시 BaaS 플랫폼입니다. 공공 SI라 감리·인수인계·폐쇄망이 전제였고, 그 제약이 기술 선택을 대부분 규정했습니다. 인터넷이 차단된 환경이라 전체 이미지를 로컬 레지스트리로 미리 적재하고 외부 pull 시도 자체를 막았습니다.

  • 기관 온보딩을 API 한 번으로

    신규 기관 1곳에 약 157회의 CLI 조작과 설정 파일 5종 직접 작성이 필요했습니다. 단계마다 수 분씩 대기가 걸리는데 그때마다 사람이 다음 명령을 쳐야 해서 하루가 통째로 묶였습니다. 전 과정을 스크립트로 통합하고 WAS가 SSH로 원격 실행하게 했습니다. 프로비저닝이 20~43분 걸리므로 트랜잭션 커밋 이후 비동기로 돌려 HTTP 요청을 붙잡지 않게 했고, 상태를 DB에 남겨 실패 시점을 확인할 수 있게 했습니다.

    운영자 조작 157회 → 1회 · 개입 시간 수 시간 → 0분

    전체 소요 시간이 준 것은 아닙니다. Kind·Istio·Helm의 물리적 대기 20~43분은 자동화 전후가 같고, 줄어든 것은 사람이 붙어 있어야 하는 시간입니다.

  • 격리를 네임스페이스가 아니라 클러스터 단위로

    기관 간 데이터 격리가 감리 요구사항이었습니다. 네임스페이스 격리는 커널과 API 서버를 공유해 블록체인 노드처럼 상태를 가진 워크로드에는 부족하다고 보고 기관당 독립 클러스터를 택했습니다. 포트는 기관마다 10개 블록을 배정하되 재사용을 전면 금지했습니다 — 삭제된 기관의 포트를 다시 쓰면 잔여 연결과 충돌하는데, 최대값 +1로만 할당하면 그 경우가 구조적으로 생기지 않습니다.

    기관당 독립 클러스터 · 포트 재사용 0

    대가는 자원입니다. 기관 1곳당 약 0.9 core · 2.4GiB · PVC 28Gi가 필요해 수용 가능한 기관 수가 제한됩니다. 격리 수준과 집적도를 맞바꾼 선택이었습니다.

  • 성격이 다른 두 블록체인을 같은 API로

    Fabric(허가형·체인코드·인증서)과 Besu(EVM·스마트 컨트랙트·계정)는 배포와 운영 방식이 완전히 다릅니다. 그대로 두면 사용자가 두 체인의 CLI를 각각 배워야 했습니다. 원격 실행 계층을 추상 클래스로 두고 체인별 구현을 분리해 같은 REST 인터페이스로 제공했고, Pod 기동 지연으로 산발적으로 나던 실패는 대기·재시도를 공통 헬퍼로 뽑아 흡수했습니다.

    Fabric 네트워크 생성 20단계 자동화 · 스크립트 1,178줄

    TOCTOU 한 건 대신 버그 클래스를 비동기 API의 거짓 성공 오퍼레이터 버그를 CRD 패치로 kubectl exec은 왜 멈추는가

백엔드 655파일 · 63,828줄  /  인프라 셸 49개 · 8,831줄(전량 작성)  /  REST 컨트롤러 123개  /  프론트 536파일  /  커밋 1,083

장비 관리 시스템 레거시

PostgreSQL · MyBatis · Spring · JSP

JSP와 바닐라 JS로 짜인 화면 수십 개가 있는 시스템. 권한 모델과 조회 성능을 개선했습니다.

  • 표현할 수 없는 상태 때문에 한 역정규화

    장비의 소속 조직을 두 단계 조인으로 유도하는데 "고객과 다른 조직에 속한 장비"를 모델이 표현할 수 없었습니다. 성능이 아니라 표현력 문제라 캐시나 뷰는 애초에 답이 아니었습니다. 백필을 기존 조인 경로 그대로 작성해 신구 경로가 같은 답을 내는 구간을 만들었습니다.

    전환 중에도 화면이 깨지지 않는 구간 확보

    정규화된 조인을 버리고

  • 인덱스를 만든 날과 쓰인 날이 13일 떨어져 있었다

    GIN trigram 인덱스가 실행 계획에 안 나타났습니다. 쿼리가 컬럼을 LOWER()로 감싸 인덱스 표현식과 달라진 것이었고, 인덱스를 다시 만드는 대신 쿼리를 인덱스에 맞췄습니다. 제조사 검색은 드롭다운으로 바꾸니 부분일치 자체가 필요 없어졌습니다.

    130개소 ILIKE 전환 · 매 검색 풀스캔 해소

    왜 안 빨라지지? 인증 필터가 DB를 네 번 방어 코드가 감춘 버그

자동매매 시스템 개인

Python · 증권사 API · Docker Compose · 실계좌 운용

직접 만들어 실계좌로 운용 중입니다. "맞게 생겼는지"와 "실제로 그런지"를 구분하는 습관이 여기서 나왔습니다.

  • 체결 47건을 역산해서야 드러난 오차

    화면 표시가 이상하다는 데서 출발해 실제 체결 내역을 역산했더니 요율이 틀려 있었습니다. 원인이 셋이었고 성격이 각각 달랐습니다 — 상수 미갱신, 세법 개정 누락, 참조 데이터 소스 자체의 오염. 판별 실패 시엔 과세 쪽으로 fallback하게 했습니다. 손익을 크게 보이게 하는 쪽이 더 위험합니다.

    세금 상대오차 1.250% → 0.068%

    4.1배짜리 수수료 오차

  • 켜는 게 맞나 — 3방향으로 검증하고 전부 기각

    ML 기능의 설정 버그를 고친 뒤 "그럼 켜는 게 맞나"를 별도 질문으로 분리했습니다. 교차검증에서 유의미해 보이는 값이 나왔지만 믿지 않고 walk-forward로 재측정한 결과 0과 구분되지 않았습니다. 검증 방식 자체의 낙관 편향이었습니다.

    A/B · 분류 · 회귀 3방향 검증 → 전부 기각

    ML을 켜는 게 맞나 체결이 0건인 이유

경력

위 프로젝트는 글로 근거를 댈 수 있는 것만 골랐습니다. 전체 이력은 아래와 같습니다.

  1. 2023 — 현재 ESG 컨설팅 기업 백엔드 개발 탄소배출 산정 웹앱 · 블록체인 DevOps 플랫폼 · 장비 관리 시스템
  2. 2021 — 2023 SI·솔루션 기업 개발 관리자 페이지 기능 개발 · 유지보수 · 솔루션 리뉴얼(MSA) · 국방부 시스템 개발 및 유지보수

일하는 방식

AI 페어링을 실무에 씁니다. 도구 자랑이 아니라 검증 장치를 어디에 두느냐의 문제로 다룹니다.

  • 스펙을 쓰게 하고 컨텍스트를 끊은 뒤 자기검토를 시킵니다. 같은 세션에서 물으면 대체로 "문제 없다"는 답이 옵니다.
  • 병렬 에이전트로 메모리 누수 51건을 찾았지만 그대로 믿지 않고 검증 게이트를 거쳐 49건만 적용했습니다. 1건은 데이터 유실 위험이라 보류했습니다.
  • 실패한 것도 남겼습니다 — AI가 쓴 커밋 메시지가 실제 diff와 달랐던 일이 있습니다.

스펙을 쓰게 하고 자기검토를 에이전트 72개로 누수 감사 커밋 메시지가 거짓말을 했다