COMPLETED · 2026.04 — 2026.06

MoneyLog

청년 맞춤형 금융 생활 관리 플랫폼
소비 기록을 콘텐츠로 공유하고, AI 기반 금융 분석 및 맞춤형 정책 정보를 제공하는 금융 생활 관리 서비스

Period 2026.04 — 2026.06 (약 8주)
Team 5명 (Backend · Infrastructure · Frontend 공동 수행)
Role Backend · Infrastructure · DevOps · Monitoring

왜 MoneyLog를 만들었는가

기존 금융 앱은 단순 지출 기록에 그치고, 청년층이 필요로 하는 정책·혜택 정보는 여러 사이트에 흩어져 있었습니다. MoneyLog는 소비 데이터를 시각적 콘텐츠로 전환하고, AI 분석과 커뮤니티를 결합해 금융 생활의 진입 장벽을 낮추는 것을 목표로 기획했습니다.

기존 금융 서비스와의 차별점
기존 가계부 앱이 "지출 기록 → 통계"에 머무르는 것과 달리, MoneyLog는 소비 데이터를 금융 피드 콘텐츠로 변환하여 공유하고, 또래 사용자와 비교·피드백을 주고받을 수 있는 금융 SNS 환경을 제공했습니다.
AI 기반 금융 분석
월별 소비 패턴을 AI가 분석하여 리포트를 생성하고, 불필요한 지출 패턴과 절약 포인트를 시각적으로 제시하도록 구현했습니다.
금융 SNS
소비 기록을 피드 형태로 공유하고, 또래의 소비 습관을 참고하며, 금융 관련 팁과 경험을 교류할 수 있는 커뮤니티를 제공했습니다.
청년 정책 추천
사용자 조건(나이, 소득, 지역 등)에 맞는 청년 정책, 복지, 카드 혜택, 보험 정보를 한곳에서 탐색하고 추천받을 수 있습니다.
스마트 가계부
카테고리별 예산 설정, 자동 분류, 월간 리포트를 통해 체계적인 재정 관리를 지원합니다.

서비스 화면

MoneyLog의 주요 화면을 소개합니다.

금융 피드 화면
금융 피드
소비를 공유하는 새로운 금융 SNS
소비 기록을 카드 형태의 피드로 변환하여 타임라인에 게시합니다. 또래 사용자의 소비 패턴을 자연스럽게 참고하고, 좋아요·댓글로 피드백을 주고받을 수 있습니다.
가계부 화면
가계부
카테고리별 예산 관리와 시각화
수입·지출을 카테고리별로 분류하고, 월간 예산 대비 사용 현황을 차트로 확인합니다. 자동 분류 기능으로 반복적인 입력 부담을 줄였습니다.
AI 리포트 화면
AI 리포트
AI가 분석하는 나의 소비 습관
월별 소비 데이터를 AI가 분석하여 절약 포인트, 소비 트렌드, 또래 대비 지출 수준을 시각적으로 정리한 맞춤형 리포트를 제공합니다.
혜택 추천 화면
혜택 추천
조건에 맞는 금융·정책 정보 한 곳에서
사용자의 나이, 소득, 지역 등 조건을 기반으로 청년 정책, 카드 혜택, 보험 정보를 자동으로 필터링하고 추천합니다.
관리자 페이지 화면
관리자 페이지
서비스 운영을 위한 백오피스 대시보드
사용자 관리, 콘텐츠 모니터링, 정책 데이터 관리, 서비스 통계 확인 등 운영에 필요한 기능을 제공하는 관리자 전용 대시보드입니다. 온프레미스 환경에 별도로 배치하여 내부 운영 도구로 활용합니다.

시스템 아키텍처

AWS EKS와 온프레미스 VMware ESXi 기반 Kubernetes를 Site-to-Site VPN으로 연결한 하이브리드 클라우드 아키텍처

MoneyLog Hybrid Cloud Architecture

이미지를 클릭하면 확대됩니다

Hybrid Cloud
사용자 트래픽을 직접 받는 주요 서비스는 AWS 클라우드에, 내부 운영 도구와 외부 API 수집은 온프레미스에 배치하여 운영성·보안·확장성을 함께 고려한 구조로 설계했습니다.
AWS (EKS)
Gateway, Config, Auth, Feed/Social, Budget, AI Recommend 등 핵심 서비스를 AWS EKS에 배치했습니다. Route 53, Shield, WAF, ALB, RDS, ElastiCache, SQS/SNS 등 관리형 서비스를 활용해 가용성과 운영 부담을 고려했습니다.
On-premise (VMware ESXi)
알림 서비스, 관리자 대시보드, 외부 API 수집 컴포넌트를 온프레미스 Kubernetes에 배치했습니다. pfSense와 WireGuard를 통해 접근 경로를 통제하는 구조로 설계했습니다.
MSA (Microservices Architecture)
Auth, AI Recommend, API Connector, Budget, Alarm, Social 서비스를 분리하고, 각 서비스가 자신의 DB를 소유하도록 설계해 배포와 장애 범위를 독립적으로 관리했습니다.
Redis Sentinel 기반 이중화
세션 캐시와 실시간 데이터를 처리하는 Redis를 Sentinel 구성으로 이중화하여, Primary 장애 시 자동 Failover가 이루어지도록 설계했습니다. 서비스 가용성을 높이고 단일 장애 지점을 제거하는 데 초점을 두었습니다.
Kubernetes Control Plane 이중화
온프레미스 Kubernetes 클러스터의 Control Plane을 다중 노드로 구성하여 etcd와 API Server의 고가용성을 확보했습니다. 단일 마스터 노드 장애 시에도 클러스터 운영이 중단되지 않도록 설계했습니다.
CQRS
다른 서비스의 테이블을 직접 조회하지 않도록, 필요한 데이터만 서비스별 읽기 모델로 복제해 보관했습니다. 원천 데이터 변경은 SQS와 NATS JetStream 이벤트로 전파하고, 구독 서비스가 자신의 복제 DB를 비동기로 갱신하도록 구성했습니다.
VPN (pfSense + WireGuard)
AWS와 온프레미스 환경 사이의 통신 경로를 Site-to-Site VPN으로 제한하고, 장애가 한쪽 환경에 머물도록 배치하면서도 필요한 이벤트와 API 호출은 명확한 경로로만 오가도록 설계했습니다.

사용 기술

프로젝트에 사용된 기술을 영역별로 정리했습니다.

Backend
Java Spring Boot Spring Cloud Spring Security GraphQL Debezium JPA / Hibernate
Frontend
Next.js React TypeScript Tailwind CSS
Infrastructure
Kubernetes VMware ESXi Istio Helm pfSense WireGuard
Cloud
AWS EKS AWS RDS (Aurora) AWS ElastiCache AWS SQS / SNS AWS CloudFront AWS S3 AWS WAF / Shield
DevOps
Jenkins Argo CD SonarQube Docker GitHub
Monitoring
Prometheus Grafana Grafana Faro Grafana Alloy Loki Tempo AlertManager
AI
AWS Bedrock Claude LangChain Python FastAPI

담당 영역

프로젝트에서 직접 설계하고 구현한 영역을 정리했습니다.

Backend
Social Service
금융 피드 CRUD, 좋아요/댓글, 팔로우 기능을 구현한 소셜 서비스를 설계하고 개발했습니다.
소비 기록을 콘텐츠로 전환하여 사용자 간 공유와 상호작용을 가능하게 하기 위해 독립적인 소셜 서비스를 분리했습니다.
Alarm Service
이벤트 기반 알림 처리 서비스를 구현하고, NATS JetStream을 통한 비동기 알림 파이프라인을 구축했습니다.
주요 서비스의 처리 흐름에 알림 로직이 결합되지 않도록, 온프레미스에 독립 배치하여 서비스 간 결합도를 낮추었습니다.
GraphQL BFF
프론트엔드와 백엔드 사이에 GraphQL BFF(Backend for Frontend) 레이어를 설계하고 구현했습니다.
프론트엔드의 다양한 데이터 요구를 하나의 진입점으로 통합하고, 여러 마이크로서비스 호출을 BFF에서 조합하여 클라이언트 복잡도를 줄이기 위함입니다.
CDC (Change Data Capture)
Debezium을 활용한 CDC 파이프라인을 구축하고, CQRS 읽기 모델 동기화를 구현했습니다.
서비스 간 직접 DB 접근 없이 데이터 변경을 전파하여, Database-per-service 원칙을 유지하면서도 필요한 데이터를 조회할 수 있도록 했습니다.
Infrastructure
AWS CloudFront + S3
정적 자산 배포를 위한 CloudFront + S3 파이프라인을 구성하고, 캐시 무효화 자동화를 설정했습니다.
프론트엔드 빌드 결과물을 CDN으로 제공하여 응답 속도를 개선하고, EKS 클러스터의 정적 파일 서빙 부담을 제거하기 위함입니다.
pfSense / WireGuard
pfSense 방화벽과 WireGuard VPN을 통한 Site-to-Site 터널을 구성하고, 접근 제어 정책을 설계했습니다.
AWS와 온프레미스 간 보안 통신 경로를 확보하고, 팀원들의 내부망 접속 환경을 제공하기 위함입니다.
Jenkins Agent
온프레미스 Jenkins Agent를 Kubernetes Pod로 동적 프로비저닝하도록 구성했습니다.
빌드 요청에 따라 Agent가 자동 생성·삭제되어 리소스를 효율적으로 사용하고, 빌드 환경 일관성을 보장하기 위함입니다.
Monitoring
Grafana Faro
프론트엔드 RUM(Real User Monitoring) 수집을 위해 Grafana Faro SDK를 통합하고, 사용자 세션 추적 대시보드를 구성했습니다.
서버 메트릭만으로는 파악하기 어려운 프론트엔드 성능 병목과 사용자 경험 이슈를 가시화하기 위함입니다.
CDC Metrics
NATS JetStream 파이프라인의 지연 시간, 처리량, 오류율을 수집하는 커스텀 메트릭과 대시보드를 구성했습니다.
CDC 파이프라인 장애를 사전에 감지하고, 데이터 동기화 지연을 모니터링하여 CQRS 읽기 모델의 정합성을 보장하기 위함입니다.
DevOps
Jenkins Pipeline
멀티 브랜치 Jenkins Pipeline을 설계하고, 빌드·테스트·이미지 빌드·배포까지의 전체 CI/CD 흐름을 구축했습니다.
수동 배포로 인한 휴먼 에러를 제거하고, 코드 변경부터 운영 환경 반영까지의 리드 타임을 단축하기 위함입니다.
SonarQube
SonarQube를 CI 파이프라인에 통합하여 코드 품질 게이트를 구성하고, 정적 분석 결과를 PR에 자동 리포팅하도록 설정했습니다.
코드 리뷰 전에 정적 분석을 통해 잠재적 버그와 코드 스멜을 자동으로 탐지하여 코드 품질을 일관되게 유지하기 위함입니다.
LLM-as-a-Judge
Jenkins CI 환경에 LLM-as-a-Judge 기반 자동 평가를 도입하여, LLM 응답 품질이 기준 점수 미달 시 배포를 차단하도록 구축했습니다.
LLM 프롬프트 변경이나 모델 업데이트로 인한 예상치 못한 서비스 품질 저하 문제를 사전에 방지하기 위함입니다.
CI/CD 설계
Jenkins(CI) → Argo CD(CD)로 이어지는 GitOps 기반 배포 파이프라인을 설계하고, 카나리 배포 전략을 적용했습니다.
배포 안정성을 확보하고, 문제 발생 시 빠른 롤백이 가능한 구조를 통해 서비스 가용성을 유지하기 위함입니다.

서비스 아키텍처

Frontend부터 각 마이크로서비스, CDC, 데이터베이스까지의 전체 서비스 흐름을 나타낸 구조입니다.

서비스별 Repository 구조

이미지를 클릭하면 확대됩니다

문제 해결

프로젝트를 진행하며 마주한 기술적 문제와 해결 과정을 정리했습니다.

Dual Write 문제 해결
Problem
MSA 환경에서 로컬 DB 트랜잭션을 커밋한 후 다른 서비스로 이벤트를 발행(Event Publish)하는 두 가지 작업을 원자적으로 보장할 수 없는 'Dual Write' 문제에 직면했습니다.
Background
MoneyLog는 사용자의 결제 및 소비 내역을 금융 피드로 공유하는 서비스이기 때문에 거래 내역이 저장되면 곧바로 피드 서비스로 이벤트를 전파해야 했습니다.
초기에는 애플리케이션 레벨에서 로컬 DB에 커밋한 직후 AWS SQS에 이벤트를 발행하도록 구현했습니다.
Cause
로컬 DB 커밋은 성공했으나 네트워크 지연이나 브로커 장애로 인해 메시지 발행에 실패할 경우, 서비스 간 데이터 불일치가 발생하는 문제가 있었고, 반대로 메시지를 먼저 발행하고 DB에 커밋할 경우, DB 커밋이 실패하면 다른 서비스에 잘못된 데이터가 전파되는 치명적인 문제가 발생할 수 있었습니다.
Alternatives Considered
가장 먼저 Outbox 패턴을 고려했습니다. 하지만 Polling 주기에 따른 지연 시간과 DB 부하 증가가 우려되었고, 실시간 피드 업데이트가 중요한 도메인 특성상 적합하지 않다고 판단했습니다.
Why This Solution
최종적으로 NATS JetStream을 활용한 Event-Driven 아키텍처를 선택했습니다.
트랜잭션 완료 후 NATS JetStream을 통해 즉시 이벤트를 발행하므로 애플리케이션 비즈니스 로직과 이벤트 발행 로직을 완전히 분리할 수 있습니다.
또한 Polling 방식이 아니므로 실시간성이 높고 추가적인 부하를 주지 않을 수 있었습니다.
Implementation
NATS JetStream 기반의 Event Publisher를 배포했습니다.
소비 내역이 기록되면 즉시 NATS JetStream 스트림으로 이벤트를 발행하고, 피드 서비스는 CQRS 패턴의 읽기 모델을 동기화하기 위해 해당 스트림을 구독하여 실시간으로 피드 데이터를 업데이트하도록 파이프라인을 구축했습니다.
Result
애플리케이션 장애나 네트워크 단절 시에도 데이터베이스의 로그를 기반으로 이벤트를 발행하므로 메시지 유실을 없앨 수 있었습니다.
결과적으로 서비스 간 데이터 정합성을 완벽하게 보장하면서도 피드 업데이트의 지연 시간을 최소화할 수 있었습니다.
Lessons Learned
분산 시스템에서 '데이터 정합성 보장'이 얼마나 까다롭고 중요한 과제인지 체감했습니다.
Event-Driven 아키텍처를 설계할 때는 항상 시스템의 부분적 실패를 염두에 두어야 함을 깨달았습니다.
데이터 신뢰성을 이벤트 스트리밍 레벨에서 보장하는 방식이 비즈니스 로직을 얼마나 간결하게 만들어주는지 깊이 이해하게 되었습니다.
GraphQL BFF 도입과 설계
Problem
MSA 환경에서 프론트엔드가 화면을 렌더링하기 위해 수많은 개별 마이크로서비스(유저, 결제, 피드, 혜택 등)를 직접 호출해야 하는 Over-fetching과 Under-fetching 문제가 발생했습니다.
Background
클라이언트가 직접 각 서비스를 호출하게 되면서 네트워크 통신 횟수가 급증하였고, 리스트 뷰를 구성할 때 다건의 데이터를 반복적으로 조회하는 과정에서 N+1 문제가 발생하여 화면 로딩 속도가 크게 저하되었습니다.
Cause
각 마이크로서비스는 자신의 도메인에 속한 API만 제공하기 때문에, UI에서 요구하는 복합적인 데이터를 한 번에 제공하지 못했습니다.
결국 프론트엔드가 필요한 데이터를 조립하기 위해 API Aggregation 로직을 떠안게 된 것이 주된 원인이었습니다.
Alternatives Considered
REST API 기반의 API Gateway에서 Aggregation을 수행하거나 전용 BFF(Backend For Frontend) 서버를 두는 방안을 검토했습니다.
그러나 REST API 방식은 화면 요구사항이 변경될 때마다 BFF의 API 응답 구조도 함께 수정해야 하는 강한 결합 문제가 존재했습니다.
Why This Solution
이러한 한계를 극복하기 위해 GraphQL 기반의 BFF를 도입했습니다.
GraphQL은 클라이언트가 필요한 데이터만 쿼리할 수 있는 유연성을 제공하며, 여러 서비스의 데이터를 한 번의 요청으로 Aggregation 할 수 있어 통신 효율을 극대화할 수 있었기 때문입니다.
기술 스택으로는 클라이언트와 백엔드 간의 효율적인 통신이 가능한 GraphQL을 선택했습니다.
Implementation
GraphQL 스키마를 정의하고 GraphQL Resolver를 통해 데이터를 매핑했습니다.
특히 N+1 문제를 근본적으로 해결하기 위해 DataLoader 패턴을 적극 도입했습니다.
개별적인 조회 요청들을 모아 하위 서비스에 Bulk Query를 날리도록 설계하여 병목 현상을 제거했습니다.
Result
프론트엔드의 네트워크 요청 횟수가 획기적으로 감소했고, 필요한 데이터만 전송받아 페이로드 크기가 대폭 줄어들었습니다.
DataLoader 적용을 통해 백엔드 내부 통신에서 발생하던 N+1 문제를 해소하여, 전반적인 API 응답 속도와 사용자 체감 성능을 크게 개선했습니다.
Lessons Learned
GraphQL은 유연성을 제공하지만 쿼리 최적화 없이 사용하면 오히려 백엔드에 부하를 줄 수 있다는 점을 배웠습니다.
DataLoader를 활용한 Batch 처리의 중요성을 깨달았으며, 백엔드와 프론트엔드 간의 효율적인 '데이터 계약' 설계가 서비스 성능에 얼마나 큰 영향을 미치는지 체감했습니다.
Canary Deployment 전략
Problem
기존 배포 방식에서는 새로운 버전의 애플리케이션을 배포할 때, 문제가 포함되어 있을 경우 전체 사용자가 장애에 즉각적으로 노출되는 리스크가 존재했습니다.
Background
초기에는 쿠버네티스의 기본 Rolling Update 방식을 사용하여 배포를 진행했습니다.
이 방식은 무중단 배포를 지원하지만, 트래픽을 세밀하게 제어할 수 없어 신규 버전에 트래픽이 인입되는 순간부터 예상치 못한 이슈가 전체 서비스로 확산될 수 있었습니다.
Cause
Rolling Update는 Pod 개수 기준으로 점진적 교체를 수행할 뿐, 실제 인입되는 네트워크 트래픽의 비율은 제어하지 못했습니다.
이로 인해 문제 발생 시 이전 버전으로 롤백하는 데에도 긴 시간이 소요되어 장애 시간이 길어지는 원인이 되었습니다.
Alternatives Considered
Istio와 같은 Service Mesh를 활용하여 트래픽의 흐름을 네트워크 레이어에서 제어하는 방안을 검토했습니다.
이 과정에서 버전을 스위칭하는 Blue/Green 배포 방식도 고려했으나, 인프라 리소스를 2배로 유지해야 하는 비용적 부담이 컸습니다.
결과적으로 Istio의 세밀한 라우팅 기능을 활용해 리소스 효율성을 챙기면서도 배포 안정성을 높이는 방법이 필요했습니다.
Why This Solution
소수의 트래픽만 신규 버전에 흘려보내어 점진적으로 안전성을 검증하는 Canary Deployment 전략을 선택했습니다.
이를 구현하기 위해 트래픽 라우팅을 정밀하게 제어할 수 있는 Istio와 배포 자동화를 지원하는 Argo Rollouts를 결합하여 아키텍처를 구성했습니다.
Implementation
Argo Rollouts의 Rollout 리소스를 정의하고 Istio의 VirtualService를 연동했습니다.
새 버전 배포 시 트래픽의 10%만 Canary 파드로 라우팅하고, 일정 시간 동안 에러율 등 메트릭을 관찰한 후 이상이 없으면 50%, 100%로 점진적 승격을 진행하도록 파이프라인을 자동화했습니다.
Result
신규 배포된 버전에 치명적인 버그가 있더라도 최대 10%의 사용자에게만 영향을 미치게 되며, 즉각적으로 이전 버전으로 100% 트래픽을 원복시키는 롤백이 가능해졌습니다.
이를 통해 운영 환경의 배포 리스크를 획기적으로 낮출 수 있었습니다.
Lessons Learned
무중단 배포를 넘어 '안전한 배포' 파이프라인을 갖추는 것이 서비스 신뢰성에 얼마나 기여하는지 배웠습니다.
단순히 코드를 서버에 올리는 것을 넘어 트래픽 제어, 모니터링, 자동 롤백을 하나로 엮는 운영 노하우를 습득했습니다.
Alert Fatigue 해결
Problem
모니터링 시스템 구축 후, 하루에도 수십 건씩 발생하는 의미 없는 경고 알람으로 인해 정작 중요한 장애 알람을 놓칠 뻔하는 '알림 피로' 문제가 발생했습니다.
Background
초기에는 Prometheus와 AlertManager를 도입하면서, CPU나 메모리 사용률이 일시적으로 상승하는 단순 임계치 초과 이벤트에도 모두 Slack 알람이 발생하도록 기본 설정 위주로 룰을 구성했습니다.
Cause
사용자에게 영향을 주지 않는 단순 인프라 메트릭(예: 순간적인 CPU 스파이크)의 변화까지 경보의 대상으로 삼았기 때문입니다.
알람이 너무 빈번하게 울리자 개발 팀 내에서 경보에 대한 민감도가 떨어지고, 실제 중요한 알람마저 무시하게 되는 알림 피로 현상이 발생했습니다.
Alternatives Considered
단순히 알람의 발생 임계치를 높이거나 지속 시간을 늘리는 방법을 고려했습니다.
하지만 이는 일시적인 미봉책일 뿐, 실제 서비스 품질 저하를 조기에 감지하지 못하게 만드는 부작용이 있었습니다.
Why This Solution
결국 인프라 중심의 모니터링에서 사용자 중심의 모니터링으로 관점을 전환했습니다.
SLI/SLO 기반으로 알람 체계를 전면 재설계하고, RED Metrics를 활용하여 실제 서비스에 영향이 있을 때만 알람을 보내도록 구조를 개편했습니다.
Implementation
CPU나 메모리 단일 지표 알람을 대폭 줄이고, 대신 'API 에러율 급증(Errors)', '응답 지연 시간 임계치 초과(Duration)'와 같이 실제 사용자 경험과 직결된 RED 메트릭 기반의 Prometheus Alerting Rule을 작성했습니다.
또한 AlertManager의 그룹화와 억제 기능을 활용해 중복 알람을 병합했습니다.
Result
불필요한 노이즈 알람이 90% 이상 감소하였고, 개발자는 알람이 발생했을 때 이것이 실제 조치가 필요한 크리티컬한 장애임을 즉각적으로 신뢰할 수 있게 되었습니다.
결과적으로 피로도가 줄어들고 운영 효율성이 크게 향상되었습니다.
Lessons Learned
모니터링은 단순히 데이터를 수집하는 것이 아니라 '실제로 대응할 수 있는 인사이트를 도출'하는 것이 핵심임을 배웠습니다.
알람 설정 시 항상 "이 알람이 울리면 지금 당장 자다가 깨서 대응해야 하는가?"라는 질문을 바탕으로 SRE 관점의 운영 마인드를 갖추게 되었습니다.
LLM-as-a-Judge 기반 응답 품질 평가
Problem
생성형 AI를 활용하는 기능에서, 프롬프트를 수정하거나 LLM 파라미터를 튜닝할 때마다 AI의 응답 품질이 개선되었는지 혹은 의도치 않게 저하되었는지 정량적으로 검증하기가 매우 어려웠습니다.
Background
MoneyLog는 사용자의 소비 내역을 분석하여 AI 리포트를 제공합니다.
더 나은 리포트를 생성하기 위해 프롬프트를 지속적으로 개선해야 했으나, 비결정론적인 LLM 특성상 기존의 단위 테스트 방식으로는 텍스트의 유용성이나 정확도를 일관되게 평가할 수 없었습니다.
Cause
사람이 직접 다수의 테스트 케이스를 눈으로 확인하며 평가하는 방식(Human Evaluation)에 전적으로 의존하고 있었습니다.
이는 시간이 오래 걸리고 평가자의 주관이 개입되며, 배포 프로세스의 심각한 병목의 원인이 되었습니다.
Alternatives Considered
정규표현식이나 키워드 매칭 기반의 룰 기반 평가를 시도했습니다.
하지만 생성형 텍스트의 다양한 변주를 모두 포괄할 수 없었고, 문맥이나 논리적 일관성을 평가하는 데에는 한계가 명확했습니다.
Why This Solution
보다 강력한 성능을 가진 상위 버전의 LLM(예: GPT-4)을 평가자로 사용하여 생성된 응답의 품질을 채점하는 LLM-as-a-Judge 기법을 도입하기로 결정했습니다.
인간과 유사한 수준의 맥락 이해를 바탕으로 자동화된 정량 평가가 가능해졌기 때문입니다.
Implementation
테스트 데이터셋에 대해 AI가 답변을 생성하면, 평가용 LLM 모델이 '일관성', '유용성', '가독성' 기준에 따라 점수(1~5점)를 매기는 평가 파이프라인을 구축했습니다.
이를 Jenkins CI 단계에 연동하여, 평균 점수가 기준치(예: 70점) 미만일 경우 배포를 자동으로 차단하도록 파이프라인을 구성했습니다.
Result
사람의 개입 없이 CI 파이프라인에서 수십 개의 테스트 케이스를 몇 분 만에 자동으로 평가할 수 있게 되었습니다.
배포 속도가 비약적으로 상승했고, 의도치 않은 프롬프트 성능 저하를 안전하게 방어하여 운영 환경의 AI 서비스 품질을 보장했습니다.
Lessons Learned
전통적인 소프트웨어 테스트와 AI 애플리케이션의 테스트는 접근 방식이 완전히 달라야 함을 깨달았습니다.
AI 서비스의 신뢰성을 확보하기 위해서는 개발 환경뿐만 아니라 파이프라인과 운영 환경 전반에 걸친 지속적인 평가 체계 구축이 필수적이라는 것을 배웠습니다.

운영 환경

CI/CD 파이프라인, 모니터링, 코드 품질 관리 등 운영 환경의 주요 구성 요소입니다.

Grafana Dashboard
Grafana Dashboard
Prometheus 메트릭, Loki 로그, Tempo 트레이스를 통합한 Grafana 대시보드입니다. 서비스별 요청률, 에러율, 레이턴시(RED Metrics)를 실시간으로 모니터링하고, Grafana Faro를 통해 프론트엔드 사용자 경험 지표도 함께 확인했습니다.
SonarQube Dashboard
SonarQube
Jenkins CI 파이프라인에 통합된 SonarQube 정적 분석 결과입니다. 코드 커버리지, 코드 스멜, 보안 취약점을 자동으로 검사하고, 품질 게이트 통과 여부에 따라 배포 파이프라인의 진행을 제어합니다.
LLM Evaluation Dashboard
LLM Evaluation
LLM-as-a-Judge 기반 서비스 품질 자동 평가 시스템의 결과입니다. LLM 응답의 일관성, 유용성 등을 CI 단계에서 평가하고, 기준 점수 미달 시 배포를 차단하여 운영 환경의 품질을 보장했습니다.
Event Stream Dashboard
Event Stream Dashboard
NATS JetStream 파이프라인의 운영 상태를 보여주는 대시보드입니다. 데이터 변경 이벤트의 처리량, 지연 시간, 오류율을 실시간으로 모니터링하고, CQRS 읽기 모델의 데이터 정합성 상태를 모니터링했습니다.

프로젝트 회고

배운 점
  • MSA 설계 및 하이브리드 클라우드 운영:
    EKS와 온프레미스 VMware 환경을 넘나들며 시스템을 설계하면서, 분산 환경에서의 네트워크 토폴로지와 보안 아키텍처를 깊이 이해하게 되었습니다.
  • 데이터 정합성 및 이벤트 주도 구조:
    서비스 간 분리된 데이터베이스 환경에서 발생할 수 있는 문제들을 NATS JetStream 기반의 비동기 메시징과 CQRS 패턴을 도입하여 실질적으로 해결하는 경험을 쌓았습니다.
  • Observability 기반의 DevOps 파이프라인:
    단순히 코드를 배포하는 것을 넘어, Prometheus RED Metrics 기반의 견고한 모니터링 환경을 구축하고 Argo Rollouts을 통한 안전한 Canary 배포를 구현하며 SRE 관점의 운영 노하우를 체득했습니다.
  • AI 기반 서비스 운영:
    LLM-as-a-Judge 파이프라인을 CI에 통합하여, 비결정론적인 생성형 AI 서비스의 품질을 자동화된 방식으로 정량 평가하고 배포 안정성을 확보하는 방안을 터득했습니다.
아쉬운 점
  • 물리 장비 한계로 인한 고가용성 구성 제약:
    MSA 복잡성과 트래픽 확장에 대비하기 위해 무중단 배포와 오토스케일링 등을 구성했으나, 온프레미스 인프라를 구성하는 물리 장비 리소스의 한계로 인해 완전한 Fault Tolerance 및 데이터베이스 고가용성 클러스터를 구성하지 못했습니다.
  • 특히 장애 발생 시의 장애 조치 시나리오를 물리적으로 완벽하게 검증하지 못한 것이 큰 아쉬움으로 남습니다.
향후 개선
  • 인프라 운영 경험 확장과 고가용성 검증:
    MoneyLog 프로젝트에서는 물리 장비 제약이 있었으나, 현재 진행 중인 OpenStack 기반 Private Cloud 구축 프로젝트를 통해 다양한 가상화 플랫폼 위에서 리소스 제약을 극복하는 경험을 확장하고 있습니다.
  • 이를 바탕으로 Kubernetes 환경과 분산 데이터베이스 환경을 다시 구축하고, 완벽한 고가용성 아키텍처를 설계하여 노드 장애나 네트워크 단절 시나리오에서도 서비스 가용성을 100% 보장하는 견고한 인프라 운영 역량을 갖추고자 합니다.