전체 글 103

Redis RPUSH + LTRIM으로 LLM 대화 이력 관리하기 — 별도 삭제 로직 없이 최근 5턴만 유지하는 슬라이딩 윈도우

WithBuddy 연재 10편이자 시즌 3의 마지막 글이다. LLM 대화가 길어질수록 프롬프트에 포함되는 히스토리와 토큰 비용도 함께 증가한다. WithBuddy에서는 Redis List의 RPUSH + LTRIM을 이용해 최근 5턴만 유지하고, EXPIRE로 오래된 세션까지 자동 정리했다. 별도의 이력 정리 배치나 삭제 대상 탐색 없이 대화 맥락을 일정한 크기로 제한한 방법을 정리한다.이 글에서 다루는 내용전체 대화 이력을 매번 LLM에 전달하면 비용이 커지는 이유RPUSH + LTRIM으로 최근 N개의 메시지만 유지하는 원리별도의 조회·삭제 로직보다 Redis List를 활용한 이유TTL 30분으로 유휴 세션을 자동 정리하는 방법턴 기반 슬라이딩 윈도우의 한계와 보완 방법문제 — 대화가 길어질수록 L..

IT 개발 2026.08.30

정책 문서 변경에 대응하는 캐시 무효화 전략 — ChromaDB 멀티테넌시 네이밍과 formVersion 자연 소멸

WithBuddy 연재 9편. 여러 회사가 함께 사용하는 RAG 서비스에서 회사별 문서를 ChromaDB 컬렉션 단위로 어떻게 격리했는지, 그리고 정책 문서가 변경됐을 때 Redis의 구버전 캐시를 일괄 삭제하지 않고 activeVersion 하나만 변경해 자연스럽게 무효화한 전략을 정리한다. 이 글에서 다루는 내용여러 회사의 문서가 검색 과정에서 섞이지 않도록 만든 ChromaDB 컬렉션 네이밍 규칙컬렉션 이름을 애플리케이션에서 정규화해야 하는 이유정책 문서가 변경됐을 때 기존 캐시를 무효화하는 두 가지 방법SCAN + DEL 방식 대신 버전 기반 캐시 무효화를 선택한 이유formVersion을 캐시 키에 포함해 삭제 없이 구버전 캐시를 자연 소멸시키는 방법 문제는 두 가지였다 — 격리와 갱신8편에서는..

IT 개발 2026.08.26

LangGraph로 온보딩 RAG 에이전트 만들기 — SCOPE 라우팅부터 3단 가드레일까지

WithBuddy 연재 8편이자 시즌 3의 시작이다. FastAPI + LangGraph 위에서 사내 문서를 기반으로 답변하는 온보딩 RAG 에이전트를 어떻게 구성했는지 정리한다. 사용자의 질문이 SCOPE 판정, ChromaDB 검색, Claude 답변 생성, 가드레일을 거쳐 최종 응답이 되기까지의 전체 흐름을 살펴본다.이 글에서 다루는 내용단일 LLM 호출이 아니라 노드 그래프로 RAG 파이프라인을 구성한 이유회사 업무 범위를 벗어난 질문을 걸러내는 SCOPE 라우터ChromaDB 컬렉션 단위로 멀티테넌트 데이터를 격리한 방법잘못된 정책 답변과 과도한 확정 표현을 줄이는 3단 가드레일검색에 실패했을 때 추측하지 않고 안전하게 폴백하는 방식왜 단순 챗봇이 아니라 에이전트였나WithBuddy가 해결하려는..

IT 개발 2026.08.24

RabbitMQ로 AI 응답을 비동기 전환하고 DLQ로 메시지 유실 막기 — Spring Boot 메시징 신뢰성 설계

WithBuddy 연재 7편이자 시즌 2의 마지막 글이다. 반복적인 폴링 구조를 걷어내고 RabbitMQ 기반 비동기 처리 구조로 전환한 과정, 그리고 실패한 메시지가 유실되지 않도록 DLQ(Dead Letter Queue), 멱등성, 재시도 정책을 설계한 과정을 실제 설정과 검증 결과를 바탕으로 정리한다. 이 글에서 다루는 내용왜 Redis 기반 폴링 구조를 줄이고 RabbitMQ 비동기 처리로 전환했는지알림 큐와 분석 큐의 TTL·prefetch를 다르게 설정한 이유실패한 메시지를 유실하지 않는 DLQ 격리 구조와 적용 방법Redis SETNX + DB UNIQUE 제약으로 중복 처리를 막는 방법1,000건 부하 검증 결과와 DRY_RUN 테스트가 가진 한계왜 비동기였나 — 폴링에서 발생하는 불필요..

IT 개발 2026.08.22

Spring Boot 캐시 히트 p95를 1,643ms에서 263ms로 — Caffeine + Redis 2단 캐시 설계와 검증

WithBuddy 연재 6편. L1(Caffeine) + L2(Redis) 하이브리드 캐시를 적용해 캐시 히트 경로의 p95를 1,643ms에서 263ms까지 줄였다. 이번 글에서는 왜 Redis 단독 구성이 아니라 2단 캐시를 선택했는지, 캐시에서 발생할 수 있는 장애를 어떻게 방어했는지, 그리고 “6.2배 빨라졌다”는 결과를 어디까지 신뢰할 수 있는지 함께 정리한다. 이 글에서 다루는 내용Redis 단독 대신 Caffeine + Redis 2단 캐시를 선택한 이유Cache Stampede, Penetration, 연쇄 장애와 이를 막기 위한 방어 장치캐시 히트 경로 p95를 약 84% 단축한 측정 결과“6.2배 개선”이라는 수치를 해석할 때 반드시 함께 봐야 할 검증의 한계 Redis만으로는 부족했던..

IT 개발 2026.08.20

CPU는 멀쩡한데 SSE 실패율이 65%였다 — HikariCP 커넥션 풀 고갈 진단기

WithBuddy 연재 5편, 시즌 2의 시작. SSE 채팅 부하테스트에서 실패율 65%가 나왔는데 CPU는 놀고 있었다. 이 모순을 추적해 HikariCP 커넥션 풀 고갈을 범인으로 특정하고, p95를 67초에서 9.94초로 되돌린 진단 과정을 처음부터 끝까지 기록한다. 이 글에서 다루는 것"CPU가 낮은데 요청이 실패한다"는 모순을 어떻게 추적했는지HikariCP 지표(active/idle/waiting)로 커넥션 풀 고갈을 특정하는 법SSE + 비동기 AI 응답이 왜 커넥션을 오래 점유하는지풀 크기를 키우되 그것을 Golden Image에 영구 반영해야 하는 이유시작은 오토스케일링 검증이었다4편에서 온디맨드 오토스케일링을 붙였다. 이제 이게 실제로 부하를 견디는지 검증할 차례였다. k6로 SSE..

IT 개발 2026.08.19

평상시 서버 비용 0원, Grafana 알람으로 OCI 인스턴스를 자동 확장하기 — 온디맨드 오토스케일링 구축기

\WithBuddy 연재 4편. CPU 임계값이 아니라 Grafana 알람을 트리거로 OCI Instance Pool을 켜고, Load Balancer로 트래픽을 분산한 온디맨드 오토스케일링을 만든 과정. 그리고 CPU 기반 스케일링만으로는 절대 못 잡는 병목을 실측으로 확인한 이야기. 이 글에서 다루는 것평상시 추가 서버 비용을 0원으로 유지하는 온디맨드 스케일링 설계Golden Image → Instance Configuration → Instance Pool로 이어지는 자동 확장 파이프라인Grafana 알람 → Webhook → OCI CLI로 Pool을 켜는 구조CPU는 멀쩡한데 SSE 실패율이 65%였던 이유 — HikariCP 커넥션 풀 병목문제 — 부하가 와도 수동 대응만 가능했다3편까지..

IT 개발 2026.08.19

클라우드플레어(Cloudflare) Tunnel로 SSH 22포트 완전 차단하기 — Zero Open Ports 배포 아키텍처 3단계

WithBuddy 연재 2편. CI/CD 배포를 위해 열어둔 SSH 22번 포트를 단계적으로 없애고, 최종적으로 SSH 키까지 제거한 과정을 실제 설정과 함께 정리한다. 이 글에서 다루는 것GitHub Actions 배포에서 SSH 22포트가 왜 공격 표면이 되는지Cloudflare Tunnel로 인바운드 포트를 0개로 만드는 구체적 설정GitHub OIDC로 SSH 개인키를 Secrets에서 완전히 없애는 방법실무에서 놓치면 다시 Permission Denied / Timeout을 만나는 3가지 함정왜 22포트를 닫아야 했나WithBuddy는 OCI Free Tier 서버 위에서 돌아간다(1편 참고). 배포는 GitHub Actions에서 SSH/SCP로 JAR을 밀어넣는 방식이었다. 그런데 GitHu..

서버 개발 2026.08.13

인프라 비용 0원으로 프로덕션을 배포한 이야기 — OCI Free Tier가 만든 아키텍처

WithBuddy 연재를 시작한다. 첫 편은 아키텍처 다이어그램이 아니라, 그 다이어그램이 왜 그 모양이 될 수밖에 없었는지에 대한 이야기다.발표 자료에는 "의도적으로 설계된 Modular Monolith"라고 적혀 있었다. 틀린 말은 아니지만, 정확한 말도 아니다. 실제로는 예산이 없어서 시작된 구조였다. 그리고 나는 그 사실을 숨기는 것보다 그대로 쓰는 편이 더 설득력 있다고 생각한다.50만 원을 어디에 쓸 것인가팀 자체 예산은 0원이었다. 빌더스리그에서 지원되는 50만 원이 우리가 쓸 수 있는 전부였다.이 돈을 어디에 쓸지가 첫 번째 의사결정이었다. 팀원 전체가 Claude, ChatGPT 같은 AI 개발 도구를 구독하면 생산성이 확실히 올라간다. 하지만 인프라에 돈이 나가기 시작하면 그만큼 구독 ..

IT 개발 2026.08.13

[구름] 바쁜 직장인·취준생을 위한 AI 입문 — '구름 AI기초체력훈련' 솔직 수강 후기

본 콘텐츠는 구름 서포터즈 활동의 지원을 받아 작성된 실제 경험 후기입니다.왜 'AI기초체력훈련'을 선택했는가AI를 배워야 한다는 건 누구나 알고 있다. 문제는 어디서부터 시작하느냐다.이론만 가득한 강의는 듣다 지치고, 그렇다고 처음부터 LLM 파인튜닝이나 프롬프트 엔지니어링 프로젝트에 뛰어들기엔 진입 장벽이 높다. 나 역시 같은 고민을 안고 있었고, 그때 눈에 들어온 게 '구름 AI기초체력훈련'이었다.국민내일배움카드로 90% 지원을 받으면 자비 부담금이 42,880원이다. 8주(67일) 동안 AI 윤리 기초부터 실제 동작하는 웹앱 완성까지 단계별로 밟아갈 수 있는 구성인데, 이 가격이면 솔직히 부담이랄 게 없었다. 일단 신청부터 했다.100% 온라인 자율 학습 — 이게 진짜 편했다수강하면서 가장 좋았던..

IT 개발 2026.08.07

[구름부트캠프] 빌더스리그 Final Expo 후기 — 최우수상 수상, 그리고 '상용화 SaaS'를 위한 마지막 교훈

본 콘텐츠는 구름 서포터즈 활동의 지원을 받아 작성된 교육생의 실제 경험 후기입니다.1. ZEP과 Zoom을 넘나들었던 파이널 엑스포의 열기2026년 7월 14일부터 16일까지, 5개월간의 결실을 맺는 BUILDERS LEAGUE Final Round: Final Expo가 열렸다. 총 17개 팀이 배정된 ZEP 메타버스 공간에서 결과물을 게시하고, 자유 관람과 함께 강사님 및 심사위원들의 질의응답이 이어졌다.우리 3팀 일단모여(WithBuddy) 부스에도 수많은 훈련생과 심사위원들이 찾아왔다. 신입사원 온보딩 AI 코치 서비스로서 그동안 구축해 온 LangGraph 기반 RAG 파이프라인, Claude Haiku 비용 최적화, Redis/RabbitMQ/SSE 스트리밍 기반의 백엔드 아키텍처를 가감 없..

IT 개발 2026.07.26

[구름부트캠프] 빌더스리그 9회차 Round 2 후기, 두 번째 수상과 시장성을 배운 WithBuddy 피벗 데이

본 콘텐츠는 구름 서포터즈 활동의 지원을 받아 작성된 교육생의 실제 경험 후기입니다.구름 부트캠프 빌더스리그 9회차에 참여하며 약 3개월 동안 팀 프로젝트를 진행했다. 우리 팀 이름은 ‘일단모여’이고, 프로젝트 이름은 ‘WithBuddy’이다.WithBuddy는 신입 사원이 입사 초기에 반복적으로 묻게 되는 질문을 사내 문서를 기반으로 답변해 주는 AI 온보딩 서비스이다.처음에는 신입 사원이 사수의 눈치를 보지 않고 편하게 질문할 수 있도록 돕는 서비스로 시작했다. 그러나 MVP 개발, 사용자 인터뷰, Round 2 고도화, 6월 26일 피벗 데이 발표를 거치면서 우리가 해결해야 할 문제와 서비스의 방향도 조금씩 달라졌다.이번 글에서는 빌더스리그를 진행하며 경험한 개발 과정과 협업, Round 2 심사 ..

IT 개발 2026.06.29

[구름부트캠프] MVP 중간 점검 이후, WithBuddy 팀이 실제로 달라진 것들

본 콘텐츠는 구름 서포터즈 활동의 지원을 받아 작성된 교육생의 실제 경험 후기입니다.1. 탄탄한 기술 베이스 위에 '진짜 에이전트'의 조건을 더하다MVP 중간 점검이 끝난 뒤, 우리 팀이 받아든 피드백은 예상보다 구체적이었다. 기능 자체에 대한 지적은 거의 없었다. 심사위원들이 주목한 건 그 기능들이 얼마나 에이전트답게, 비즈니스 흐름 위에서 작동하느냐였다."리서치부터 가설 검증까지 이어지는 개연성과 논리성이 탄탄하다." 당시 WithBuddy는 문서 업로드, 한국어 특화 임베딩 모델(jhgan/ko-sroberta-multitask)과 Kiwi 형태소 분석기를 활용한 쿼리 확장까지 핵심 RAG 파이프라인이 이미 안정적으로 올라와 있는 상태였다. 기술 이해도와 문서 완성도에서 좋은 평가를 받은 건 그 결..

IT 개발 2026.05.26

Flyway 실무 적용 가이드 — 데이터베이스 형상 관리부터 운영 전략까지

백엔드 프로젝트에서 소스 코드는 Git으로 관리한다. 하지만 데이터베이스 구조 변경 이력은 제대로 관리되지 않는 경우가 많다.초기에는 개발자가 직접 SQL을 실행하거나, 로컬 환경에서 ddl-auto=update에 의존해도 큰 문제가 없어 보인다. 그러나 프로젝트 규모가 커지고 협업 인원이 늘어나면 다음과 같은 문제가 반복적으로 발생한다.개발자마다 DB 스키마 상태가 다르고, 운영 서버 SQL 반영이 누락되며, 컬럼 추가 순서가 충돌한다. 배포 후 DDL 실행 오류, 운영 DB와 로컬 DB 구조 불일치, 그리고 롤백 불가능 상태까지. 한 번쯤은 겪어봤을 풍경이다.이러한 문제를 해결하기 위해 사용하는 대표적인 도구가 Flyway다.이 글에서는 Spring Boot 환경에서 Flyway를 어떻게 적용하고, ..

Spring Boot 2026.05.19

[구름부트캠프] MVP Checkpoint Day - 가볍게, 핵심만, 확실하게

본 콘텐츠는 구름(goorm) 서포터즈 활동 지원을 받아 작성된 실제 참여 후기입니다 솔직히 말하면, 체크포인트 당일 아침은 긴장을 했다.지금까지 쌓아온 것들이 강사님들의 눈앞에 펼쳐지는 순간이었으니까. '우리가 방향을 제대로 잡고 있는 걸까?' 그 질문이 머릿속을 계속 맴돌았다. 하지만 ZEP 구름스퀘어에 접속하는 순간, 그 긴장감은 에너지로 바뀌었다. 화면 너머로 분주하게 움직이는 15개 팀의 아바타들을 보는 것만으로도, 이게 단순한 수업이 아니라는 걸 다시 한번 실감했다. 01. ZEP 구름스퀘어에서 펼쳐진 온택트 열기비대면 메타버스 플랫폼 ZEP 구름스퀘어 JOBS 룸. 오전 9시, Sprint Time이 시작되자마자 각 팀의 분위기가 달라졌다.발표 자료를 마지막으로 점검하는 팀, 시뮬레이션을..

IT 개발 2026.04.28

[구름부트캠프] 빌더스리그 시작 후기

본 콘텐츠는 구름 서포터즈 활동으로 지원을 받아 작성된 교육생의 실제 경험 후기입니다.3월 오프닝 세레모니부터 느낀 생생한 첫인상구름이 만든 몰입 경험2026년 3월 17일, 구름이 주최한 빌더스리그 9회차 오프닝 세레모니가 비대면으로 진행되었다.각자의 공간에서 줌(Zoom)에 접속하는 방식이었지만, 막상 참여해보니 일반적인 온라인 행사와는 확연히 다른 분위기였다.접속과 동시에 수많은 팀들이 채팅창을 통해 서로를 응원하기 시작했고,화면에는 완성도 높은 오프닝 연출이 이어졌다.단순히 ‘접속해서 보는 행사’가 아니라, 처음부터 끝까지 참여하게 만드는 구조였다.비대면임에도 불구하고 현장감이 살아 있었고,오히려 더 많은 팀과 동시에 연결되어 있다는 점에서 색다른 긴장감과 설렘을 느낄 수 있었다.이 경험을 통해 ..

IT 개발 2026.03.27

Oracle Cloud 무료 서버로 풀스택 웹 구축 완벽 가이드

완전 무료로 프로덕션급 웹 서비스 만들기1. 전체 아키텍처시스템 구조도데이터 흐름사용자 요청User → Cloudflare CDN → Vite AppAPI 호출Vite App → Nginx (443) → Spring Boot (8080)데이터베이스 조회Spring Boot → MySQL (3306, Private Network)응답MySQL → Spring Boot → Nginx → Vite App → Usermarkdown코드 복사비용 분석서비스스펙비용제한Cloudflare Pages무제한$0500빌드/월Oracle VM #1 (MySQL)1GB/47GB$0영구무료Oracle VM #2 (Boot)1GB/47GB$0영구무료트래픽 (아웃바운드)10TB/월$0-SSL 인증서-$0-총계-$0/월⭐⭐⭐⭐⭐2...

IT 개발 2026.03.04

클라우드플레어(Cloudflare)로 Vite 프로젝트 배포 및 커스텀 도메인 연결 완벽 가이드

최근 웹 프론트엔드 배포의 대세로 자리 잡은 Cloudflare Pages는 GitHub와의 연동성이 뛰어나고, 글로벌 엣지 네트워크를 통해 압도적인 속도를 제공한다. 특히 Vite로 빌드한 React 프로젝트를 배포하고 개인 도메인을 연결하는 과정은 생각보다 직관적이지만, 몇 가지 주의할 점들이 있다. 1. Cloudflare Pages 배포 진행 (Vite 기준)먼저 로컬에서 작업한 프로젝트가 GitHub 저장소에 푸시되어 있어야 한다.배포 프로세스Cloudflare 대시보드 접속: 'Workers & Pages' 메뉴에서 'Create application'을 선택한다.GitHub 연동: 'Continue with GitHub'을 선택하여 계정을 연결한다.GitHub 저장소: 연동후 배포할 파일이..

IT 개발 2026.03.03

vs code 새파일 & 새폴더 단축키(Open Keyboard Shortcuts (JSON))

[ { "key": "ctrl+n", "command": "explorer.newFile", "when": "!editorFocus" }, { "key": "ctrl+shift+n", "command": "explorer.newFolder", "when": "!editorFocus" }]어느덧 백엔드 개발자 부트캠프 3개월 차에 접어들었다. 스프링 부트 프로젝트를 진행하다 보면 도메인별로 패키지를 나누고 클래스 파일을 생성할 일이 정말 많다. 그런데 VS Code에서 새 폴더나 새 파일을 생성할 때마다 마우스를 움직여 아이콘을 클릭하는 것이 생각보다 큰 흐름의 끊김을 만든다.효율적인 코딩을 위해 시간을 내어 단축키 설정을 알아보니, VS Code의 keybindings.j..

IT 개발 2026.02.28

JPA 페이징 성능 최적화 공부 정리: List vs Page vs Slice

오늘은 JPA에서 데이터를 조회할 때 사용하는 List, Page, Slice의 차이점과 성능 최적화 방법에 대해 공부한 내용을 정리해본다. 특히 대용량 데이터 환경에서 왜 성능 문제가 발생하는지, 그리고 어떻게 해결할 수 있는지 알아봤다.List로 조회하기가장 기본적인 방법은 List로 데이터를 가져오는 것이다.List users = userRepository.findByStatus("ACTIVE");List의 특징조회 쿼리 하나만 실행된다조건에 맞는 모든 데이터를 한 번에 가져온다페이징 처리가 없다List의 문제점데이터가 많아지면 모든 데이터를 메모리에 올리기 때문에 OutOfMemoryError가 발생할 수 있다. 따라서 데이터 양이 확실히 적을 때만 사용해야 한다는 것을 배웠다.Page로 조회하기..

Java 2026.02.24
728x90
반응형