光탈페 – Backend Engineer[인원]BE 2, FE 2, Devops 1, Design 1 2025. 04 ~ 2025. 09
광주광역시 교육청과 협력해 진행한 학생 오디션 플랫폼으로, 실시간 투표·좌석 예매·슬로건 공모 기능을 제공했습니다. 행사 당일 DAU 3,000+, Vercel 기준 누적 트래픽 73,000+, GA 기준 이벤트 50,000+를 처리하며 서비스를 안정적으로 운영했습니다.
- 기존 외주 개발 구조를 내부 개발로 전환해 1,000만+원 규모의 외주 비용 절감
- 교육청 및 기획 측과의 지속적인 미팅을 통해 요구사항 구체화 및 기능 기획 참여
- 실시간 투표, 좌석 예매, 슬로건 공모 기능을 통합 제공하는 플랫폼으로 서비스 확장
- Google Sheets API 동기 호출 구조를 Outbox 기반 비동기·배치 처리 구조로 전환
- 외부 API 지연이 사용자 응답에 직접 영향을 주지 않도록 요청 경로에서는 데이터 저장과 Outbox 기록만 수행하도록 분리
- Google Sheets API는 호출 제한이 존재하고, 응모 건마다 개별 호출이 발생하면 요청 수가 급격히 증가할 수 있어 이를 방지하기 위해 배치 처리 구조 적용
- 기존 SQL 추출 → CSV 가공 → 발송으로 이어지던 수동 운영 방식을 단일 API 기반 구조로 전환
- 대상자 선정부터 연락처 및 좌석 매핑 데이터 생성까지 일관되게 처리하도록 구현
- 반복 작업 제거뿐 아니라, 사람이 개입하던 과정에서 발생할 수 있는 운영 오류를 줄이기 위해 자동화 구조 적용
- Ubuntu 기반 서버 환경에 Prometheus·Grafana 모니터링 시스템 구성, 트래픽 집중 시간대 서버 상태를 실시간으로 파악할 수 있는 운영 환경 확보
- 별도 상용 서비스 없이도 자체 서버 환경에서 비용 부담 없이 운영 가능하고, 메트릭 수집 및 대시보드 확장이 용이해 해당 스택 선택
시민화폐 광산 – Backend Engineer[인원]BE 2, FE 2, Devops 1, Design 1 2025. 05 ~ Present
광주광역시 광산구청과 협력해 진행한 지역 화폐 기반 거래 플랫폼으로, 지역 내 가상화폐 '광산'을 활용한 거래 및 채팅 기능을 제공했습니다. 광산구 주민 약 400+명이 사용하는 서비스이며, 향후 광주 전역으로 확장 가능성이 있는 프로젝트입니다.
- 개발 전 프로젝트 회의에 참여해 요구사항을 구체화하고 API 설계 방향 정리
- QA와 지속적으로 소통하며 기능상 문제를 확인하고 개선 사항 반영
- 운영 중 발생한 이슈를 반복적으로 점검하며 서비스 안정성과 완성도 향상
- Redis 기반 Access Token Blacklist 도입으로 로그아웃 이후 토큰 재사용 위험 제거
- JWT는 Stateless 구조라 로그아웃 이후에도 Access Token이 만료 전까지 유효할 수 있어, 서버 단에서 즉시 무효화할 수 있도록 Blacklist 구조 적용
- Refresh Token 삭제와 연계해 세션이 완전히 종료되도록 인증 구조 개선
- 배포 서버 기준 k6 부하 테스트에서 Virtual Users 50, 총 10,000회 요청 환경에서도 Access Token 재사용률 0%와 평균 요청 지연 40ms 내의 처리 성능 검증
- 기존 RDB 기반 인증 상태 관리를 Redis TTL 구조로 전환, 인증번호·시도 횟수·인증 완료 상태를 시간 기반 키로 분리 관리
- SMS 인증 데이터는 짧게 유지되고 빠른 조회가 중요해, 불필요한 DB I/O를 줄이고 만료 처리를 단순화하기 위해 Redis TTL 구조 적용
- 엔티티 전체 조회 구조를 Projection 기반 조회로 전환
- 리스트 조회 API 특성상 화면에 필요한 데이터만 빠르게 반환하는 것이 중요해, 불필요한 엔티티 전체 조회 대신 필요한 컬럼만 조회하도록 개선
- 연관 데이터 개별 조회를 배치 조회 방식으로 변경하고 Index 적용
- 데이터 증가 시 쿼리 수가 함께 증가하지 않도록 배치 조회 구조와 인덱스를 적용해 조회 성능 안정화
- 10,000건 기준 최대 응답시간 10,644ms → 2,718ms (약 74.5% 단축), 평균 응답시간 8,989ms → 870ms (약 90.3% 단축)
- 전체 멤버 조회 API에 Slice 기반 페이징과 DTO Projection 적용
- 무한 스크롤 방식에서는 전체 개수보다 다음 페이지 존재 여부만 중요해, count 쿼리가 필요한 Page 대신 Slice를 적용
- 주요 조회 및 정렬 컬럼에 Index를 적용해 대량 데이터 환경에서의 조회 성능 개선
- 30,000건 기준 최대 응답시간 8,206ms → 1,630ms (약 80.1% 단축), 평균 응답시간 5,712ms → 67ms (약 98.8% 단축)
EXPO – Backend Engineer[인원]BE 2, FE 2, Devops 1, Design 1 2024. 10 ~ Present
광주광역시 교육청과 협력해 진행한 행사 운영 플랫폼으로, 박람회·연수 현장에서의 참가자 관리 및 만족도 조사 절차를 효율화하기 위해 개발했습니다. AI·SW 체험 축전에서는 30,000+명, 미래교육박람회에서는 2,000+명 규모를 안정적으로 처리했습니다.
- JSON 필드 저장 구조를 RDB에서 MongoDB로 이전
- 문서형 데이터 특성상 스키마 변경 가능성이 높고 구조가 유동적이어서, JSON 저장과 조회에 더 적합한 MongoDB 기반 구조로 전환
- 운영 편의성과 확장성을 고려해 데이터 관리 구조 재설계
- 기존 XSSFWorkbook 기반 전체 메모리 적재 구조를 SXSSFWorkbook 기반 스트리밍 처리 구조로 전환
- 대용량 데이터에서는 워크북 전체를 JVM 힙에 적재하는 구조가 메모리 사용량 급증으로 이어질 수 있어, 일정 행만 메모리에 유지하는 스트리밍 방식 적용
- 일정 행만 메모리에 유지하고 나머지는 temp 파일로 처리하도록 개선
- 30,000건 기준 VisualVM 기준 최대 Used Heap 사용량 465MB → 245MB (47.4% 감소) 확인