김준아

보충역 (4급, 내과) · 산업기능요원 편입 희망

phone
010-5167-1710
email
junah.dev@gmail.com
github
github.com/junah201
blog
junah201.medium.com

About Junah

직접 측정해서 병목을 찾고, 구조를 바꿔 해결하는 백엔드 개발자입니다. 2년 넘게 운영 중인 알림 봇 ‘치직’은 등록 채널이 1.7만 개로 늘어나는 동안 병목이 드러날 때마다 구조를 바꿔 왔습니다. 피크 시간대 알림이 몇 시간씩 늦어졌을 때는 채널별 요청 약 7,000건을 API 1건으로 바꿔 실행 시간을 6분 30초에서 최대 1분 30초로 줄였고, 채널이 늘어 Lambda 무료 한도에 다시 다가섰을 때는 단계별 시간을 측정해 피크 시간대 실행 시간을 85% 줄였습니다.

외주 프로젝트 4건을 혼자 맡으며 비개발자 클라이언트와 문제를 정의하고, 바뀌는 요구사항을 조율해 왔습니다. 인수인계 없이 5개로 나뉜 레거시 백오피스를 하나로 통합했습니다. 운영하면서 생긴 문제는 포인트 원장(Ledger), 비트필드 권한처럼 구조를 다시 설계해 풀었습니다. 시행착오는 블로그에 기록하고, BBConf에서 발표했습니다.

Experience

주식회사투비웨어

인턴
2025. 07 - 2025. 09 (3개월)

Java Spring·Angular 기반 B2B 서비스에서 DB 이전과 프론트엔드 마이그레이션을 맡았습니다.

주요 업무

  • MSSQL → MariaDB 이전: 레거시 쿼리, 함수, 테이블 이관
  • 문제: API 호출 로직(로딩·에러·캐싱)이 화면마다 중복됨
  • Tanstack Query 패턴의 공용 Query 서비스를 만들어 호출 로직을 한 곳으로 모음
  • Angular 19 마이그레이션용 공통 컴포넌트, 서비스, 폴더 구조 템플릿 작성
  • 결과: 팀원들이 이 패턴을 기존 v12 코드에도 적용함

Projects

치직 – 서버리스 치지직 방송 알림 디스코드 봇 개인 · 운영 중

2024. 01 - 현재

치지직에서 방송이 시작되면 디스코드로 알림을 보내는 서비스입니다. 17,000+ 채널, 월 200,000+ 건의 알림을 처리하며, 치지직 알림 봇 중 가장 큰 규모입니다. 명령어 처리, 대시보드 API, 방송 감지를 모두 Lambda + DynamoDB로 구성했습니다.

알림 수 시간 지연 해결: 실행 시간 6분 30초 → 최대 1분 30초블로그: 로직 개선

  • 문제: 저녁 피크에 치지직 서버가 응답 없이 연결을 붙잡아, 요청마다 1분씩 대기하며 Lambda timeout이 연쇄 발생. 알림이 몇 시간씩 늦어짐
  • 채널별 GET 약 7,000건을 ‘팔로우 채널 라이브 상태’ API 1건으로 대체
  • 계정당 팔로우 3,000개 제한은 계정 7개에 채널을 나머지 연산으로 분배해 해결
  • 계정 차단을 막으려고 12시간마다 세션 갱신
  • 결과: 실행 시간 6분 30초 → 15초~1분 30초. Lambda가 무료 한도 안으로 들어와 월 비용 $11.5(Lambda $10 + DynamoDB $1.5) → $1.5(DynamoDB만)

무료 한도 초과 직전의 비용 개선: 실행 시간 85% 단축블로그: 비용·성능 개선

  • 문제: 월 사용량 376,000 GB-s로 무료 한도(400,000)에 근접. 98.5%가 방송 감지 함수
  • 단계별 소요 시간 로그를 12시간 수집해 병목을 측정: live-detail 52%, 팔로잉 목록 18%, DB 조회 15%, 디스코드 전송 11%
  • 채널별 get_item을 BatchGetItem(100개 단위, 실패 키는 백오프 재시도)으로 교체 → DB 조회 3.58초 → 0.11초
  • 방송 중인 채널만 방송 정보와 함께 주는 API로 전환해 목록 조회와 채널별 호출을 제거
  • 결과: 일주일 전 같은 시간대와 비교해 평균 실행 시간 69.1초 → 10.5초(85% 단축). 피크 시간대 속도로 하루 종일 돈다고 보수적으로 가정해도 월 사용량 376,000 → 113,000 GB-s(약 70% 감소)

보안 취약점 악용 사고 대응: 당일 패치블로그: 보안 사고 회고

  • 문제: 대시보드 URL의 서버 ID만 바꾸면 관리자 권한 없이 남의 서버에 알림을 보낼 수 있는 취약점(IDOR)이 악용되어, 약 3시간 반 동안 일부 서버에 @everyone 멘션이 도배됨
  • 제보 9분 만에 메시지를 보내는 Lambda 2개의 API Gateway 트리거를 제거해 공격 차단
  • API 요청 로그를 CloudWatch Logs Insights로 분석. 공격 시간대 요청 897건이 4개 계정에서 왔고, 그중 884건이 한 계정에 몰린 것을 확인. 피해 서버 관리자가 제공한 로그와 대조해 공격자 특정
  • 권한 검사를 공통 미들웨어로 옮기고 Lambda마다 검사 여부를 지정하게 바꿔 당일 재배포. 책임을 돌리지 않는 사과 공지 게시
  • 결과: 인지 후 9분 만에 공격을 멈추고 당일 패치. 권한 검사가 핸들러마다 흩어져 있어 빠뜨릴 수 있던 구조를 한 곳에서 관리하는 구조로 바꿈

그 외

  • 채널 증가로 길어진 감지 실행 시간을 채널 ID 기준 분할 병렬 실행으로 약 1/10로 단축블로그: 설계
  • DynamoDB 단일 테이블 설계: GSI로 채널별·서버별 알림 조회 패턴 지원

테더메이커 · 테더모아 – 암호화폐 수수료 환급 플랫폼 외주 · 풀스택 1인 개발

2024. 09 - 현재 운영 중 (테더메이커) / 2025. 04 - 2026. 02 (테더모아, 서비스 종료)

거래소 리베이트의 일부를 유저에게 돌려주는 서비스입니다. 거래소에서 받는 레퍼럴 수수료를 매일 읽어 유저 잔액을 갱신하고 정산합니다. 테더메이커는 가입자 약 900명, 월평균 약 2.0만 USDT(약 2,800만 원)를 처리하며, 국내 가상자산 규제(특금법) 변화 이후 해외 대상 서비스로 전환해 운영 중입니다. 테더모아는 운영 기간 동안 가입자 약 700명, 월평균 약 4.5만 USDT(약 6,300만 원)를 처리했고, 같은 규제 변화로 클라이언트가 사업 방향을 바꾸면서 2026년 2월 서비스를 종료했습니다. 두 서비스 모두 개발부터 운영까지 혼자 맡았습니다.

잔액 유실과 롤백 불가: Immutable Ledger로 재설계 블로그: 포인트 잔액을 UPDATE하던 구조에서 INSERT만 하는 구조로

  • 문제: balance 컬럼 하나를 UPDATE하는 구조라 관리자, Cron, 봇이 동시에 수정하면 변경이 유실됨. 이력이 없어 롤백도, 변경 사유 추적도 불가능했음
  • History 테이블을 붙여 봤지만 잔액과 이력이 어긋날 수 있어 원장(Ledger) 방식으로 전환
  • UPDATE 없이 모든 변동을 INSERT로 기록. (userExchangeId, version) 복합키로 순서를 보장하고 잔액 snapshot을 함께 저장
  • 정정은 반대 금액을 추가 기록(counter-entry), 버전 충돌은 재시도로 처리
  • 결과: lock 없이 동시성 문제 해소, 이력 기반 롤백 가능. 3개월 미사용 포인트 소멸 같은 기간 정책도 구현 가능해짐

그 외

  • 거래소 API 연동·크롤링으로 환급액 자동 갱신과 정산 처리, Discord·Telegram 알림
  • 기능마다 API와 DTO가 늘던 문제를 줄이려고 GraphQL 도입. FE와 언어를 맞추려고 NestJS 선택

서울대학교병원 연구단 통합 관리 백오피스 외주 · 풀스택 1인 개발

2023. 08 - 2023. 12 개발 (5개월) / 이후 현재까지 유지보수

연구팀의 인사, 연구비, 과제, 계약, 납품 업무가 5개의 레거시 사이트로 나뉘어 있던 것을 하나의 백오피스로 통합했습니다. 이전 개발자의 인수인계 없이, 실무 담당 간호사와의 소통만으로 요구사항을 정리했습니다. 누적 사용자는 내부 임직원 232명, 고객사 191곳, 참여 외부 병원 127곳입니다. 도입 이후 3년간 기관 연구비 지급 259건(약 26억 원), 업체 납품 결제 요청 약 6,200건(약 29억 원)을 이 시스템으로 처리했습니다.

인수인계 없는 레거시 5개 통합: 비개발자와 요구사항 정의

  • 문제: 5개 사이트로 흩어진 레거시를 통합해야 했지만, 이전 개발자의 인수인계가 전혀 없었음
  • 기존 사이트의 기능을 실무 담당 간호사의 업무 흐름과 하나씩 맞춰 보며 요구사항 정리
  • 개발 중 바뀌는 요구사항은 비개발자도 이해할 수 있는 말로 영향 범위를 설명하고, 합의한 뒤 반영
  • 결과: 5개 사이트의 데이터 약 2.9만 건(2006년 이후 연구비 내역 포함)을 이관해 하나의 백오피스로 통합. 2023년 납품 이후 현재까지 운영 중

권한 60여 개를 28개로: 실무자와 권한 모델 정리, 비트필드로 단순화블로그: 비트필드 권한 설계

  • 문제: 15개 이상 모듈마다 읽기·쓰기·삭제·승인으로 권한이 잘게 나뉘어, 관리자가 직원마다 권한 60여 개를 설정해야 하는 구조였음
  • 실무 담당자와 실제 업무를 확인해 쓰기·삭제는 '관리' 하나로 묶고, 세분화가 필요 없는 모듈은 '접근' 하나로 줄여 28개로 정리
  • 28개 권한을 64비트 정수 하나에 저장해 권한 테이블 없이 유저 컬럼 하나로 관리. 상위 권한을 주면 하위 비트도 함께 켜서 계층 표현
  • 한계: 권한별 검색 시 Full Scan, 낮은 가독성. 성능 이점은 측정하지 않았고, 이 규모에서는 RBAC + 세션 캐싱으로도 충분했을 것으로 판단
  • 결과: 권한 설정 화면과 검사 로직이 숫자 하나로 단순해짐

그 외

  • 고객용·직원용 도메인을 분리하고, 공통 코드를 NPM 패키지로 배포
  • EC2를 1년 예약 인스턴스(전체 선결제)로 전환해 서버 비용 약 40% 절감
  • SES 이메일 알림, S3 + CloudFront 배포 구성

Runeterras.com – 서버리스 레전드 오브 룬테라 메타 분석 사이트 개인

2023. 01 - 2023. 05

마스터 티어 랭크 매치를 자동 수집·분석해 덱별 승률과 상성을 보여주는 서비스입니다. 유지비를 줄이려고 DB를 뺀 전체를 서버리스로 구성했습니다.

  • EventBridge → Lambda → SQS → Lambda로 1시간 주기 수집 파이프라인 구성
  • Riot API 제한(시간당 30,000회)을 넘지 않도록 요청량을 미리 계산하고 2주간 실측으로 검증
  • 원본 매치는 CSV + GZip으로 S3에 두고 Athena로 조회. 분석 결과만 RDS에 저장해 비용과 응답 속도를 함께 잡음
  • 문제: Lambda 동시 실행으로 RDS 연결 수 초과 → RDS Proxy, 커넥션 풀러, pool size 1 중 비용을 기준으로 pool size 1 선택

Vellox – GCP Cloud Functions용 ASGI 어댑터 오픈소스 · PyPI 배포

2024. 11

FastAPI, Django 같은 ASGI 앱을 GCP Cloud Functions에서 실행하게 해주는 라이브러리입니다.

  • 문제: Lambda용 어댑터(mangum)는 있지만, Cloud Functions는 flask.Request만 넘겨줘 ASGI 앱을 바로 올릴 수 없음
  • mangum 내부를 분석해 flask.Request를 scope/receive/send로 바꾸는 핸들러 구현, Lifespan 이벤트 지원
  • 결과: PyPI에 vellox로 배포

재단법인 미래의학연구재단 웹사이트 외주 · 풀스택 1인 개발

2023. 01 - 2023. 04 (4개월)

Activities

Education

2024. 03 - 재학 중StonyBrook University (SUNY Korea) 컴퓨터과학과 / 학점 3.82 / 4.00
언어영어 일상 회화 가능