경력기술서
큐피스트
2024.06 ~ 재직 중
[케밋] 한·일 크로스리전 매칭 시스템 설계·구축
NestJS · PostgreSQL · Kafka · Redis · DeepL · ECS/Fargate
2026.06 ~ 진행 중
배경 · 문제
- 일본 서비스의 여성 유입·리텐션이 현지 경쟁 서비스 대비 부진한 상황에서, 광고 테스트로 '한국 남성' 소재의 유저 획득 비용(CPI·CAC)이 유의미하게 낮다는 수요가 선검증된 상태였습니다. 검증된 소재를 실제 매칭 기능으로 전환하는 것이 목표였습니다
- 한국·일본이 같은 인스턴스의 서로 다른 논리 DB로 분리돼 있어 리전 간 JOIN·외래키·단일 트랜잭션이 모두 불가능했고, 기존 국내 매칭 코드를 그대로 재사용할 수 없는 구조적 제약이 있었습니다
접근 · 의사결정
- 리전 간 통신을 서버 간 내부 API로 단일화하고, 내부 토큰 검증을 실패 시 차단(fail-closed)으로 두고 재시도 대상 응답 코드를 제한해 한쪽 리전의 장애가 반대편으로 전파되지 않도록 격리
- 크로스리전 데이터는 한 리전을 마스터로 두고 전용 테이블에 (리전, 프로필 ID) 복합 키로 적재 → 리전 간 ID 충돌 없이 단일 DB 조회로 관계를 다룰 수 있게 설계
- 타 리전 재화 차감처럼 단일 트랜잭션이 성립하지 않는 흐름은 Saga 보상 트랜잭션으로 처리해 부분 실패 시 원복을 보장
- 푸시는 수신자 리전 기준 토픽으로 발행해 발신 리전의 지연·장애가 수신 리전의 알림 품질에 영향을 주지 않도록 분리
- 상대 프로필 조회는 리전 한정 키로 자기 리전 Redis에 캐시해 리전 간 왕복 비용을 제거
결과 · 성과
- 프로필·추천·관계(좋아요/커넥션)·알림·번역·채팅·탈퇴 정리·어드민 분석까지 15개 이상 도메인을 순차 배송
- 프로필 번역 파이프라인 구축 — 사전(Redis Hash) 우선 조회 → 미스 시 DeepL 폴백(3초 타임아웃 · 백그라운드 반영) → Kafka 컨슈머가 변경된 필드만 재번역해 저장하고, 원문이 사라지면 번역본도 함께 정리
- 설계 대안과 선택 근거를 문서로 남겨 후속 작업자가 같은 논의를 반복하지 않도록 정리
트러블슈팅 · 배운 점
- 두 리전의 질문 ID가 정렬돼 있다고 가정하고 설계했으나, dev 실측에서 서로 다르다는 것을 확인했습니다 → 답변을 소유 리전 기준 ID로만 키잉하도록 변경했습니다. 리전별 데이터는 '같아 보여도 같지 않다'를 기본 전제로 두게 됐습니다
- 상대 프로필 캐시에 무효화 경로가 없어 프로필 수정이 최대 5분간 반영되지 않는 문제를 발견했습니다 → 자기 리전은 저장 시점에 즉시 삭제하고, 리전 간 전파가 필요한 쪽은 범위를 분리해 후속 과제로 넘겨 릴리스 일정을 지켰습니다
[케밋] 알림·스케줄 Worker 아키텍처 재편 및 플랫폼 인프라 고도화
NestJS · Kafka · ECS/Fargate · EventBridge · Datadog · Redis · AWS CDK
2026.03 ~ 2026.05
배경 · 문제
42개 Worker가 단일 ECS Task(4vCPU/16GB)에 묶여 운영되며 다음 문제가 누적된 상태였습니다.
- 모든 워커가 한 Task에서 동시에 부팅돼 기동이 오래 걸리고, 메모리가 부족해 일부 워커가 아예 실행되지 못하는 문제
- Consumer를
cron_restart로 주기마다 강제 재시작해 시간당 약 40회 리밸런싱·메시지 중복이 발생하고, 재시작 시점마다 CPU가 90%까지 치솟는 문제
- 푸시 알림 컨슈머가 단일 인스턴스로만 동작해, 피크 시간대 알림이 몰리면 Consumer LAG가 수만 건까지 쌓이고 해소에 6시간 넘게 걸리는 처리 지연
- idle Batch 프로세스가 약 7.7GB를 상시 점유하는 자원 낭비
접근 · 의사결정
cron_restart 제거 + Graceful Shutdown 래퍼로 Consumer 13개 교체 → 리밸런싱·메시지 중복 해소
- 단일 push consumer에 몰리던 알림을 도메인별(추천/채팅/기타) 전용 ECS 서비스·Kafka 토픽으로 분리 → 도메인 간 간섭 제거, 도메인별 독립 스케일링
- 관계 알림을 CDC 우회 경로에서 Kafka 직접 발행으로 전환 → 불필요한 우회 제거·실시간성 향상
- Batch를 PM2 cron에서 EventBridge + ECS RunTask로 분리, 실행 이력·DLQ·실패 알림 확보
- 알림 Worker에 Consumer LAG 기반 ECS Auto Scaling 적용, 기존 방식에서 새 방식으로의 전환은 롤백을 대비하여 feature flag 기반 무중단 cutover로 진행
결과 · 성과
- 피크 Consumer LAG 37,402 → 778건(약 48배↓), 해소 시간 389분 → 9분
- 리밸런싱 시간당 약 40회 → 0회
- 실측 기반 Worker Task 4vCPU/16GB → 1vCPU/6GB 축소, idle 약 7.7GB 해소
- 인프라 비용 연 약 USD 2,800 절감
- 공통 Worker 운영 구조로 일반화 → 케밋에서 검증 후 타 서비스로 확장 적용 가능한 기반 마련
트러블슈팅 · 배운 점
- push 분리 작업의 무중단 롤백을 위해 둔 feature flag가, 조회될 때마다 설정을 매번 직렬화하면서 CPU를 끌어올려 피크 시간 API latency가 20초까지 치솟던 문제를 발견했습니다 → 즉시 서버 수를 늘려 피크를 넘긴 뒤, 전환이 끝난 flag를 제거해 직렬화 비용을 없애 근본 해결했습니다. 무중단을 위한 안전장치가 역으로 비용이 될 수 있음을 확인했습니다
- Batch command가 완료돼도 커넥션 풀이 이벤트 루프를 붙잡아 ECS task가 종료되지 않고 10분 이상 RUNNING으로 남는 문제를 발견했습니다 → 완료 시 명시적으로 프로세스를 종료하도록 전환하고, at-least-once 트리거에 대비해 중복 실행 방지 락을 함께 적용했습니다
- 배포 중 Batch 종료 로직과 잔존 PM2 cron 설정이 충돌해 재시작 루프가 발생했습니다 → 코드 변경과 운영 설정 변경을 같은 배포 단위로 묶어야 한다는 기준을 세워 재발을 방지했습니다
[케밋] Google·Apple 기반 구독 정기권 시스템 구축
NestJS · PostgreSQL · Redis · Kafka(MSK) · Google Play / App Store API
2025.10 ~ 2025.11
배경 · 문제
일본 진출용 로컬 BM이자 한국에도 공통 적용할 수 있도록, Google·Apple 스토어 기반 월 단위 자동갱신 구독 정기권 시스템을 신규 구축했습니다. 결제 성공·실패·유예·일시중지·만료·취소·환불 등 다양한 구독 상태를 처리하고, 무제한 대화·프로필 보기·좋아요 지급 등 혜택의 지급·동기화를 자동화했습니다.
접근 · 의사결정
- 스토어 실시간 알림(Google RTDN(Pub/Sub), Apple Server Notification·JWS)을 Webhook으로 수신 → MSK publish → Validation Worker가 영수증 검증 후 상태 반영하는 비동기 구조 설계
- Google·Apple의 인증·알림 포맷 차이(Apple JWT(ES256) 직접 생성, JWS의 x5c 인증서 체인을 Apple Root CA까지 검증 후 payload 파싱, Google Pub/Sub push 인증)를 전략 패턴 기반 인터페이스로 분리해 스토어별 정책 변경에 대응
- 알림 중복은 notification 단위 유니크 제약으로, 순서 역전은 이벤트 타임스탬프 비교로 최신 상태만 반영하도록 분리 처리하고, Validation Worker에 멱등성 검증을 적용해 구독 상태 정합성 확보
- Webhook 수신 후 내부 처리 구간은 Outbox로 발행 정합성을 보장하고, 스토어→서버 인바운드 알림 유실은 1일 1회 주기 재검증 Worker로 보완해 이중 안전장치 구성
- 혜택 지급·회수를 자동화하고, 중복 지급은 지급 단위 유니크 제약을 최종 방어선으로 두고 Redis SETNX 분산 락으로 경합을 1차 차단
- 결제 실패 grace 처리와 환불 시 즉시 혜택 종료·소모성 아이템 회수, 사용 후 환불 악용은 이용정지로 대응
결과 · 성과
- Google·Apple 양 스토어 결제·혜택 지급 기반을 신규 구축해 한국·일본 구독 정기권 출시 지원
- Webhook + 주기 재검증 이중화로 스토어 알림 누락 상황에서도 구독 상태 동기화 보장
- 혜택 지급·회수 자동화로 수동 운영 개입을 제거하고, 혜택 누락·중복 지급으로 인한 CS 리스크 감소
트러블슈팅 · 배운 점
- 다운그레이드는 두 가지 이유로 구현이 까다로웠습니다.
- 즉시 적용되는 업그레이드와 달리 다운그레이드는 다음 갱신부터 적용되는 예약 상태를 유지해야 하는데, 두 스토어의 표현 방식이 근본적으로 달랐음 — Apple은 알림 subtype(또는 플랜 tier 비교)으로, Google은 linkedPurchaseToken과 lineItems의 이전 항목 유무로 판정 → 스토어별 신호를
DOWNGRADE/UPGRADE 공통 이벤트 타입으로 변환하고, 다운그레이드는 현재 플랜은 두고 예약 플랜에만 반영해 상위 혜택을 현재 주기 끝까지 유지
- 구독 갱신 주기(샌드박스도 수 시간 단위)를 기다려야 하고 상태 조합이 많은 데다 검증이 Validation Worker에서 비동기로 일어나 자동 재현이 어려웠음 → dev 서버에서 실제 스토어 알림을 흘리며 상태 전이를 로그로 추적해 케이스별로 검증
[케밋] 일본 서비스 출시를 위한 18+ 본인·나이 인증 시스템 구축
NestJS · Redis · PostgreSQL · Kafka(MSK) · Amazon Rekognition · Liquid eKYC API
2025.09 ~ 2025.10
배경 · 문제
일본은 데이팅 앱 이용에 18세 이상 본인·나이 인증을 규제로 요구합니다. 일본 서비스 출시를 위해 Liquid eKYC 기반 인증 결과 조회, 프로필 이미지 비교, 인증 상태 반영으로 이어지는 인증 플로우와, 인증 이벤트 비동기 처리 및 인증 수단·이미지의 완전 삭제까지 포함한 규제 대응 구조를 설계했습니다.
접근 · 의사결정
- 인증 요청 → eKYC 결과 조회 워커 → Amazon Rekognition 기반 프로필·인증 이미지 비교 워커 → 인증 상태 반영·알림으로 이어지는 단계를 MSK 토픽으로 분리한 비동기 파이프라인으로 설계
- 검증된 생년월일로 만 18세 미만을 차단하고, 인증 미완료 유저에게는 채팅 발신 알림을 제어해 규제 요건 충족
- 기존 메시지 처리 구조의 이벤트 유실 가능성을 발견해 Outbox 패턴으로 인증 이벤트 처리 정합성을 확보 — 발행 방식은 사내 CDC 인프라와 Polling Publisher를 비교한 뒤, 인증 이벤트는 빈도가 낮아 CDC 운영 부담 대비 이득이 적다고 판단하여 앱 스케줄러 기반 Polling Publisher로 단순하게 구현
- Liquid 기밀 데이터 삭제 API latency(5~30초)를 고려해 탈퇴 로직과 분리한 비동기 삭제 워커를 두고, Liquid·S3에 저장된 PII를 자동 삭제
- 일본 외 국가 확장을 대비해 country-restricted 가드로 국가별 게이트를 두고, 알림·에러 메시지를 i18n으로 처리
결과 · 성과
- 일본 18세 본인인증 요건을 충족해 서비스 정식 심사 통과에 기여
- Outbox 기반 이벤트 처리 구조로 인증 이벤트 유실 가능성을 제거하고, 운영 기간 내 미처리 이벤트 0건 유지
- 기밀 데이터 자동 삭제 구조를 구축해 일본 규제·감사 대응 체계 마련
[케밋] 관심사 태그 기반 친구 추천 시스템 구현
NestJS · Redis · PostgreSQL · Elasticsearch
2025.05 ~ 2025.06
배경 · 문제
프로필 기반 탐색의 한계를 보완하고 취향 기반 매칭 경험을 강화하기 위해, 관심사·라이프스타일·MBTI·연애성향 등 프로필 태그를 기반으로 친구를 추천하는 탐색 탭을 구현했습니다. 인기 태그 랭킹과 태그별 사용자 추천을 제공해 태그 기반 탐색·매칭 경험을 개선했습니다.
접근 · 의사결정
- 태그 등록·리뷰 카운트를 Redis ZSET(ZINCRBY)으로 실시간 누적하고, 주기 배치 워커가 카테고리별 랭킹을 ZUNIONSTORE로 머지해 인기 태그 목록을 산정
- 태그별 사용자 추천은 매력점수·성별(키)·거리·공통 관심사 등 서로 다른 조건의 후보를 Elasticsearch msearch로 묶어 단일 요청으로 처리
- 추천 결과는 변동이 잦고 캐시 적중률이 낮아 Redis 캐시 대신 Elasticsearch 직접 조회로 단순화
- 일본 진출을 고려해 태그 데이터를 언어별로 분리 관리할 수 있도록 설계
결과 · 성과
- 태그 카운트는 실시간으로 누적하고 랭킹은 주기 배치로 산정하는 구조로, 서로 다른 추천 조건을 단일 요청으로 처리
- Elasticsearch msearch 기반 복합 쿼리로 P95 500ms 달성
- 추천 정확도 개선 A/B 테스트 결과, 추천 경로 좋아요 전송 수 +7%, ARPDAU +12%
트러블슈팅 · 배운 점
- 여러 태그 쿼리를 msearch로 합산할 때 같은 유저가 중복 노출돼 Set으로 중복을 제거했는데, 중복 제거 후 개수로 다음 페이지 존재 여부를 판정하던 탓에 수천 명 규모의 태그에서도 페이지네이션이 조기 종료되는 문제를 발견 → 다음 페이지 판정을 중복 제거 전 원본 쿼리 합계 기준으로 바꿔 해결
[케밋] 위치 기반 동네 탐색 개발
NestJS · Redis · PostgreSQL · Elasticsearch · H3
2025.02 ~ 2025.03
배경 · 문제
지역 기반 만남 수요에 대응하고 가까운 친구 탐색 경험을 제공하기 위해 위치 기반 동네 친구 추천 기능을 구축했습니다. H3 기반 geosharding과 Redis 캐싱으로 위치 데이터를 효율적으로 관리하는 추천 구조를 설계했습니다.
접근 · 의사결정
- 위경도를 H3 hex 셀로 변환해 성별 Redis sorted set에 저장하고, 지역 밀집도에 따라 셀 크기를 분기해 추천 풀의 크기를 조절
- 추천은 Redis에서 인접 hex 후보를 1차로 좁힌 뒤 Elasticsearch에서 선호설정·차단·연결·like 관계를 필터링하는 2단계 구조로 설계
- 이미 추천한 유저는 72시간 동안 재추천에서 제외하고, 정규 추천과 섞이지 않도록 추천 이력을 별도 테이블로 분리
- 추가 추천은 재화 소비로 제공하고, 소비·추천 이력 기록을 트랜잭션으로 묶어 정합성 확보
결과 · 성과
- H3 geosharding과 Redis 캐싱으로 P95 250ms 이하 응답 속도 달성
- A/B 테스트 결과 결제 +12%(p=0.02), D+1 리텐션 +0.7%, 신규 남성 LTV day6 기준 +26.6%
- 위치 기반 동네 탐색 출시 후 DAU 대비 해당 기능 일간 사용률 40% 기록
사내 공통 재화 관리 시스템 재구축
NestJS · Redis · PostgreSQL · S3
2025.04
배경 · 문제
기존 재화 시스템은 유저별 잔액 합계만 보유해 지급 단위별 추적이 불가능했고, 사용 순서·소멸 정책이 없어 미사용 재화가 무한정 쌓이는 회계 리스크가 있었습니다. 적립·사용·소멸 이력을 추적할 수 있는 공통 재화 관리 시스템으로 전면 재구축했습니다.
접근 · 의사결정
- 지급 단위별로 잔여량을 추적하는 상세 이력 테이블을 신설하고, 먼저 지급된 재화부터 차감하는 FIFO 사용 로직을 핵심 도메인 규칙으로 설계(동시간 지급 시 유료 우선)
- 유료 5년·무료 3개월의 소멸 정책을 정책 적용일자를 키로 관리해 향후 정책 변경에 대응하고, 보상 지급 시 만료 시각이 리셋되도록 처리
- 만료 재화 처리는 커서 페이지네이션 기반 배치 워커로 구현하고, 소멸 내역도 사용 이력에 함께 기록해 감사 추적성 확보
- 소멸 사전 고지를 위해 대상 유저를 Redis Set으로 수집하고, 캐시 장애를 대비해 S3로 이중화
- 기존 데이터는 잔액 유무로 분리해 청크 단위로 마이그레이션하고, 잔액이 없는 유저도 빈 이력을 남겨 마이그레이션 누락과 구분할 수 있게 한 뒤 전후 잔액을 검증
결과 · 성과
- FIFO 기반 사용·소멸 정책과 이력 추적 구조를 도입해 감사 대응이 가능한 재화 관리 체계 구축
- 소멸 알림 도입 후 4주간 재화 사용률 약 +15% (도입 직전 동기간 대비)
- 공통 라이브러리로 구현해 멀티 브랜드에서 동일 구조를 재사용할 수 있는 기반 마련
트러블슈팅 · 배운 점
- 잔액이 있어도 소비가 실패하는 정합성 문제가 두 가지 원인으로 발생했습니다.
- 트랜잭션 누락 — 일부 무료 재화 지급 경로에서 합계 증가와 상세 생성이 한 트랜잭션으로 묶이지 않아, 중간 실패 시 합계는 늘었지만 상세가 생성되지 않았습니다 → 지급 경로를 트랜잭션으로 묶어 원자적으로 커밋되게 하고, 상세 생성 함수의 트랜잭션 인자를 필수로 변경해 누락을 차단했습니다
- read replica 지연 — 차감 시 상세를 읽는 조회가 트랜잭션 밖에서는 복제본으로 향해, 지급 직후 소비하면 복제 지연으로 방금 만든 상세가 아직 보이지 않아 차감에 실패했습니다 → 소비 흐름을 트랜잭션 경계로 묶어 같은 커넥션에서 조회와 차감이 일관되게 일어나도록 수정했습니다
[케밋] 반복되는 API 지연 장애 원인 규명 및 관측 지표 재정립
Node.js · Datadog APM/Profiler · Kafka · ECS/Fargate · Athena
2026.06 ~ 진행 중
배경 · 문제
피크 시간 API 응답이 20초까지 치솟는 장애가 반복됐고, 매번 '이벤트 루프 포화'로 결론을 냈지만 같은 처방이 다음 장애를 막지 못했습니다. 원인을 하나로 뭉뚱그린 것이 문제라고 보고, 서로 다른 실패 방식으로 나눠 규명했습니다.
규명한 실패 유형
- 동기 직렬화로 인한 이벤트 루프 포화 — Datadog Continuous Profiler로 추적해 유저 수만큼 증폭되던 동기 JSON 딥클론·설정 재파싱을 원인으로 규명하고 제거 → 이벤트 루프 지연 71ms → 0.2ms(약 350배↓) · 처리량 +14.5% 확보
- 헬스체크가 장애를 증폭 — 로드밸런서 헬스체크가 DB·Redis·Kafka·검색엔진을 순차 확인하는 깊은 검사에 연결돼 있어, 의존성 지연 하나가 정상 task까지 교체 대상으로 만들고 트래픽이 남은 소수에 몰리는 연쇄를 유발 → 인스턴스 자체만 확인하는 경로로 교체해 연쇄를 차단하고, 배포마다 반복되던 알림 노이즈도 함께 해소
- GC 정지 — stop-the-world 정지가 최대 3.13초, 이벤트 루프 지연이 6.88초까지 오른 장애에서 이벤트 루프 이용률(ELU)은 0.845에 그쳐 탐지에 실패 → ELU는 지속 포화에만 유효하고 순간 정지는 GC 정지 시간·이벤트 루프 지연 분위수로 봐야 함을 확인해 지표를 유형별로 분리
- 메시지 발행 직렬화 — 전역 프로듀서가 동시 전송 1건 + 멱등 옵션으로 동작해 프로세스 내 모든 발행이 한 줄로 직렬화되고, 요청 핸들러가 이를 그대로 대기하면서 API가 최대 209초까지 멈추던 문제를 규명 → 브로커 중단을 재현한 로컬 A/B로 40초 → 3.02초 개선을 검증
결과 · 성과
- 프로덕션과 같은 2vCPU 조건을 재현하는 로컬 측정 환경을 구축해, 추정 대신 A/B 수치로 개선 여부를 판단하는 절차를 확보
- 요청 스코프 read 캐시(처리량 +12.4% · 요청당 Redis 호출 208 → 118회), 응답 딥클론 제거(+10%), 카탈로그 메모이제이션(CPU −88.6%) 등 개선안을 실측 기반으로 도출
- 컨슈머가 축소 배포 중 비정상 종료돼 생존 인스턴스가 멈춘 채 살아 있고, 지연량이 알람 임계 사이 구간에 갇혀 자가 복구되지 않던 문제를 규명해 임계값 조정으로 해소
트러블슈팅 · 배운 점
- CPU 절감이 곧 지연 개선은 아니었습니다. 프로덕션 CPU를 약 10% 줄였지만 같은 시간대 지연은 움직이지 않았고, 피크는 이벤트 루프 포화이고 상위 지연은 I/O 대기라 CPU 여유가 체감으로 이어지지 않음을 확인했습니다 → 이후 성능 작업은 무엇을 개선하는지를 지표와 함께 먼저 정의하고 착수합니다
- 팀 문서에 기록해둔 원인이 실제 코드와 맞지 않는 것을 확인하고 정정했습니다. 축적된 장애 기록도 주기적으로 코드와 대조해야 한다는 기준을 세웠습니다
AI 개발 워크플로우 설계 및 팀 내재화
Claude Code · MCP · Datadog · Sentry · Notion
2026.02 ~ 진행 중
배경 · 문제
- 배포·마이그레이션·코드리뷰·장애 조사처럼 반복되지만 실수 비용이 큰 작업이 개인 숙련도에 의존하고 있었습니다
- AI 도구를 그대로 쓰면 프로덕션 DB·배포를 건드릴 수 있어, 안전장치 없이는 팀에 권하기 어려운 상태였습니다
접근 · 의사결정
- 개인 설정이 아니라 레포에 체크인해 팀 공용 자산화 — 배포·마이그레이션·리뷰·테스트·장애 조사용 에이전트 20여 개를 버전 관리 대상으로 운영하고, 작업 난이도에 따라 모델 등급을 나눠 비용을 배분
- 프로덕션 경로에 안전 게이트를 설계해 내장 — 테스트는 로컬 DB 대상임을 검증해야 실행되고, 프로덕션 DB 권한은 읽기 전용으로 고정하며, 마이그레이션은 적용 대상 확인 → 명시적 승인 → 사후 검증 순서를 강제
- AI 코드리뷰의 오탐을 구조로 제거 — 찬성·반대 두 에이전트가 각 지적을 검증하고 남은 것만 반영하도록 절차화
- 결정론적으로 생성 가능한 부분은 스크립트에 위임하고 AI는 오케스트레이션만 담당하도록 역할을 분리
- Datadog·Sentry·Notion·DB를 MCP로 연결해 관측 → 원인 분석 → 티켓화를 한 흐름으로 처리
결과 · 성과
- 배포·검증·리뷰 절차가 문서가 아닌 실행 가능한 형태로 남아, 담당자가 달라도 같은 순서로 수행할 수 있는 기반을 마련
- 장애 원인·아키텍처 결정을 90여 개의 상호 링크 문서로 축적해 같은 조사를 반복하는 비용을 절감
- 실제로 이 구조 위에서 프로덕션 장애 원인 분석과 크로스리전 매칭 설계를 수행
트러블슈팅 · 배운 점
- AI 결과를 그대로 신뢰하지 않고 실측·코드 재확인으로 검증하는 절차를 함께 둬야 실효가 있었습니다. 실제로 이전에 기록해둔 장애 원인이 틀렸음을 후속 검증에서 발견하고 정정했습니다
- 도구가 반복적으로 틀리는 지점은 그때마다 규칙 문서로 환류해, 같은 실수가 재발하지 않도록 관리하고 있습니다
[케밋] 서비스 안정화 및 글로벌 확장 대응을 위한 백엔드 개선
NestJS · Redis · PostgreSQL · Elasticsearch · ECS/Fargate · Kafka
2024.06 ~ 진행 중
배경 · 문제
단독 백엔드로 케밋을 운영하며 성능·정합성·악성유저 대응·해외 확장 등 안정화 과제를 지속적으로 처리했습니다. 트래픽 증가와 일본 진출에 맞춰 병목과 운영 리스크를 발견하는 대로 개선했습니다.
성능 · 동시성
- 태그 랭킹 조회를 Redis pipeline으로 묶어 라운드트립을 280회에서 4회로 줄여 p50 응답을 약 11배(481ms → 42ms) 단축
- 알림 전송 로직을 개선해 메시지당 DB 호출을 약 400회에서 수 회로(약 98%↓) 줄이고 Worker 메모리 사용을 낮춤
- 좋아요 전송·성향 테스트 저장 등 동시성 이슈를 Redis 분산 락과 원자적 upsert로 해결해 중복 처리·정합성 오류 제거
악성유저 대응
- 악성유저 등록 시 기기 식별자·전화번호를 함께 차단하고 재가입·재로그인 시점에 검증해 번호 변경 우회를 차단
- 피해 유저 보상을 일정 기간 내 상호작용으로 한정하고 지급 이력 플래그로 중복 지급을 제거해 보상 누수를 차단
글로벌 확장 (일본 진출)
- 하드코딩된 리소스를 제거하고 언어코드 기반 리소스 로딩 + 템플릿 치환 구조로 리팩터링해 다국어 처리를 일반화
- 국가별 운영 환경(DB·SMS 전송·리소스)을 분리해 한국·일본을 동시에 서비스할 수 있는 구조 확보
Dev 인프라 (EC2 → ECS)
- 수동 git pull·재기동에 의존하고 API·워커가 한 EC2에 묶여 메모리가 부족하던 dev 환경을, 7개 서비스를 ECS로 옮겨 배포를 자동화하고 리소스를 격리
- 수동 재기동이 사라지면서 백엔드·프론트엔드 모두 서버 접속 없이 배포할 수 있게 되어 팀 배포 편의성과 생산성 개선
포커스미디어코리아
2022.07 ~ 2024.05
엘리베이터 TV 광고 플랫폼 백엔드 시스템 개발 및 운영
Node.js · Spring Boot · DynamoDB · PostgreSQL · Redis
엘리베이터 TV 광고 플랫폼 내재화
- 엘리베이터 TV 광고 송출 플랫폼의 백엔드 시스템을 개발하고, 메시지 큐 기반 Event-Driven 아키텍처로 점진적 전환
- 광고 캠페인 관리 및 송출 API 개발
- 광고 도메인 특성에 맞게 읽기/쓰기 분리 구조를 설계하고, DynamoDB 기반 데이터 모델링으로 잦은 요구사항 변경에 대응
- 외부 업체에 의존하던 엘리베이터 TV 광고 송출 시스템을 사내 내재화하여 플랫폼 개발·운영 주도권 확보
사용자 인증·인가 시스템 개발
- 외부·내부 시스템을 위한 사용자 인증·인가 시스템을 Redis를 주 저장소로 사용하여 구현
- RBAC(Role-Based Access Control)를 직접 구현하여 권한 체계 세분화
- 다중 IdP 연동을 위한 Strategy 패턴 적용
- Redis 휘발성 리스크를 고려한 비동기 데이터 동기화 및 복구 메커니즘 구현
- IdP 인스턴스 싱글톤화 및 Redis 캐시 도입으로 인증 서버 통신 지연 P95 10ms 유지
프로모션 관리 시스템 리뉴얼
- 기존 PHP 기반 이벤트 관리 시스템을 서버리스·이벤트 기반 아키텍처로 전면 리뉴얼
- TypeScript 기반 Command API 및 Spring Cloud Function 기반 Consumer 개발
- React 기반으로 프로모션 관리 페이지와 엔드유저 프로모션 페이지 개발
- 프로모션 관리 자동화로 운영 및 개발 업무 부담 감소