PGVector Window 설치 방법
·
Spring Boot/LLM
https://kimfishes.tistory.com/17 LLM (Ollama) RAG 구현 전 pgvector VS Qdrant 중 무엇이 좋을까https://kimfishes.tistory.com/3 SpringAI 사용해서 LLM (Ollama) 연결 + Resilience4j 도입 (Spring Boot)고객센터에 사용자가 문의 게시물을 작성하면 관리자에게 디스코드로 알림이 가고, 관리자가 답변을 달아주기kimfishes.tistory.com 구현하려는 전체 구조 [사용자] → [백엔드 (Spring)] ↓ [Embedding 생성 (Ollama)] ↓ [PostgreSQL + pgvector] ..
RAG 구현 전 Vector DB 선택 (PGVector VS Qdrant 중 무엇이 좋을까?)
·
Spring Boot/LLM
https://kimfishes.tistory.com/3 SpringAI 사용해서 LLM (Ollama) 연결 + Resilience4j 도입 (Spring Boot)고객센터에 사용자가 문의 게시물을 작성하면 관리자에게 디스코드로 알림이 가고, 관리자가 답변을 달아주기 전 AI가 먼저 문의글에 맞게 답변을 달아주는 기능을 구현하려고 한다.디스코드(Dikimfishes.tistory.com 기존 Ollama로 LLM을 사용하던 상황에서도 기본적인 대화는 가능하다.하지만 예를 들어:“고객센터 몇 시에 종료되나요?”“환불은 언제까지 가능하죠?”“구독 해지는 바로 되나요?”이 질문들은 정확한 정책/운영 정보를 요구한다.LLM은:일반적인 지식은 잘 답하지만우리 회사의 최신 정책은 모른다잘못된 정보를 그럴듯하..
Spring Boot 4에서 외부 API 호출 무엇을 선택해야 할까?
·
Spring Boot
Spring Boot에서 외부 API를 호출해야 하는 경우 RestClient vs WebClient vs Feign Client vs WebFlux 중 무엇을 선택해야 좋을지 궁금해서 끄적여 보았습니다. 1. RestTemplate은 왜 고려하지 않는지?과거에는 RestTemplate이 기본 선택이었습니다. 하지만 현재는 유지보수 모드이며, Spring 공식 문서에서도 신규 프로젝트에서는 사용을 권장하지 않음따라서 Boot 4 기준에서는:RestTemplate → 구버전RestClient / WebClient / Feign Client / WebFlux → 사용 권장 2. RestClient란?RestClient는 Spring Framework 6.1부터 도입된 최신 동기 HTTP 클라이언트..
왜 UUID v7을 선택했는가? (Snowflake와 비교까지)
·
Spring Boot
대부분의 프로젝트는 기본 키로 다음 중 하나를 사용한다.AUTO_INCREMENT (Long)UUID v4 (랜덤)Snowflake (시간 기반 64bit ID)이번 프로젝트에서는 Postgres + Hibernate 환경에서 UUID v7을 선택했다.왜 굳이 v7을 선택했는지, 그리고 Snowflake와는 무엇이 다른지 정리해본다. 기존 UUID v4의 문제점 UUID v4는 완전 랜덤이다.550e8400-e29b-41d4-a716-446655440000장점충돌 확률 거의 없음분산 환경에서 안전중앙 서버 불필요단점완전 랜덤 → B-Tree 인덱스에 불리insert 시 page split 빈번인덱스 단편화 발생대량 트래픽 환경에서 성능 저하Postgres나 MySql 기본 인덱스는 B-Tree라 ..
Lettuce VS Redisson 분산 락
·
Spring Boot
https://kimfishes.tistory.com/13 🚚 허브 간 최단 경로 탐색 캐시 스탬피드 (Cache Stampede) 발생+해결이전 문제 상황출발지와 목적지 사이 허브 간 경로를 다익스트라 알고리즘으로 선정 후, Kakao Api를 호출해 허브 간 소요 시간 산출이때 Kakao Api 응답을 기다리는 방식의 경우 16 ~ 20 초의 많은 시kimfishes.tistory.com 나의 상황1명만 refresh lock → Kakao Api를 호출하여 값 갱신 시도나머지는 Redis 재조회 2~3회 후 없으면 TTL 시간이 지난 값이라도 반환성공 시 DB upsert + Redis set- 허브 간 소요시간 저장 시 Redis에 분산락을 사용하여 하나의 요청만 Kakao에 요청하여 값이..
🚚 허브 간 최단 경로 탐색 캐시 스탬피드 (Cache Stampede) 발생+해결
·
Spring Boot
이전 문제 상황출발지와 목적지 사이 허브 간 경로를 다익스트라 알고리즘으로 선정 후, Kakao Api를 호출해 허브 간 소요 시간 산출이때 Kakao Api 응답을 기다리는 방식의 경우 16 ~ 20 초의 많은 시간이 걸림 첫 번째 해결- Redis를 도입하여 TTL 5분이 지나지 않은 값은 Redis에 값을 꺼내 사용 (Redis TTL 5분, DB TTL 10분)- Redis TTL 5분이 지난 경우 DB 조회 후 Redis에 값 갱신 (이때 우선 Redis에 갱신 후 Kakao Api를 호출하여 최신 값으로 갱신)- Redis와 DB 모두 값이 없는 Cold Start의 경우 Kakao Api 호출 후 값 갱신 RedisHubEdgeCache@Component@RequiredArgsConstr..
🚚 허브 간 최단 경로 탐색 알고리즘 구현 + Kakao Map Api 연동 (Spring Boot)
·
Spring Boot
물류 관리 및 배송 시스템을 위한 MSA 기반 플랫폼 개발 프로젝트로 물류 관리 및 배송 시스템을 만들게 되었다. 그중 hub 파트를 맡게 되어 사용자가 주문을 완료하여 배송이 시작되면 특정 허브에서 도착 허브까지 가장 빠르고 효율적인 경로를 찾아 응답해 주는 코드를 구현해야 한다.처음에는 거리만 기준으로 정렬하는 단순 탐색을 고려했지만, 실제 배송에서는 다음 요소들을 모두 고려해야 했다. 즉 가중치 기반 최단 경로 문제였고, 자연스럽게 다익스트라(Dijkstra) 알고리즘을 채택하게 되었다.이동 거리 (distance)소요 시간 (duration)출발지의 위도 경도값, 도착지의 위도 경도값을 Kakao Map Api에 경로 탐색을 요청해 응답을 받아오며, 해당 결과가 있는 상태에서 동일 경로 탐색이 ..
DDD의 페이징 로직 (Spring Boot)
·
Spring Boot
문제 발생 - 헥사고날 아키텍처와 DDD 기반으로 허브 서버를 개발하면서, 페이징 로직을 어떻게 가져가야 할지에 대한 고민이 생겼다.- Spring Data JPA가 제공하는 Pageable, PageRequest, Page 같은 페이징 타입들은 매우 강력하고 편리하지만, 도메인 계층에 노출시키기에는 기술 의존성이 크다는 문제가 있다.- 도메인 계층에 그대로 사용하기에는 기술 의존성이 크다. 문제 예시- 헥사고날 아키텍처에서 도메인은 비즈니스 규칙만 알고 있어야 하고, 프레임워크나 기술에 종속되면 안되지만 페이징을 구현하려다 보니 자연스럽게 아래와 같은 코드가 만들어졌다.- Hub Repository 인터페이스에서 Page를 사용하게 된다면 도메인 부분이지만 Jpa에 의존하는 문제가 됨- 도메인은..
특정 이벤트 발생 시 Discord 실시간 알림 시스템 (Spring Boot)
·
Spring Boot
문제 발생특정 사용자가 질문을 위해 고객센터에 문의 게시물이 작성한다면 빠른 답변을 위해 관리자에게 알리는 알람을 울리는 알람 기능이 필요했다. 처음에는 웹 안에서 로그인 한 관리자에게 알림이 발생되게 구현했지만, 관리자가 페이지에 접속해야 알림을 확인해야만 하는 단점이 있어 실시간 모니터링이 불가능해 답변 지연이 잦아졌다. 원인 분석 관리자 접속 흐름의 비효율성 - 관리자는 페이지에 항상 접속해야만 문의 여부를 파악할 수 있음- 문의 답변을 위해서 24시간 모니터링은 사실상 불가능 관리자 알림 시스템 부재- 문의가 생성되었을 때 핸드폰으로 알림이 가는 기능이 없음- 이메일 기반 알림만으로는 반응 속도가 느리고 실시간성이 떨어짐 해결책 문제를 해결하기 위해 다음과 같은 방법들은 고민했다.방식..
LLM (Ollama) + Resilience4j 재시도 처리 (Spring Boot)
·
Spring Boot/LLM
본문LLM (Ollama)가 동작하지 않을 때 Resilience4j를 사용하여 재시도 처리 로직을 추가했지만 DLQ 로직은 구현되지 않았었다. DLQ (Dead Letter Queue)메시지 큐 시스템(Kafka, RabbitMQ, SQS 등)이나 이벤트 기반 아키텍처에서 처리 실패한 메시지를 따로 보관하는 큐로 장애나 외로 인해 메시지가 실패했을 때 재시도해도 계속 실패하는 메시지들을 나중에 재처리(reprocess)하거나 분석하기 위해 DLQ에 보관운영자는 DLQ에 쌓인 메시지를 모니터링 / 복구 / 재처리 DLQ가 해결하는 점1. 실패 메시지를 격리시켜 서비스 정상화2. DLQ에 보관해 나중에 로그·데이터 분석 가능3. DLQ로 분리해서 다른 메시지 처리는 정상 진행DLQ를 Kafka로 구현..