분류 전체보기
-
토큰 라운드 로빈문제공부일기장 2026. 6. 18. 09:46
ASIS:한국투자증권 Open API는 appKey/token 기준으로 초당 요청 제한이 있어, 단일 서버 내에서는 KisTokenDispatchService에서 KIS-V1/V2/V3 키를 라운드로빈으로 선택하고, key별 windowStartMillis, usedInWindow, lastReservedAtMillis, cooldownUntilMillis 상태를 메모리에서 관리하여 초당 요청 수를 제한하고 있었다.문제발생:단일 JVM에서는 해당 로컬 카운터로 어느 정도 제어가 가능하지만, api/batch/worker처럼 여러 서버 인스턴스가 동시에 같은 KIS appKey/token을 사용할 경우 각 서버가 요청 카운터와 윈도우 시간을 별도로 관리한다. 따라서 전체 합산 요청 수가 한국투자증권의 초당..
-
SSE 기반 AI 스트리밍에서 성능을 제대로 측정하는 방법 (TTFT, Duration, Active Stream 설계)카테고리 없음 2026. 3. 26. 11:32
🚀 WebFlux SSE 스트리밍 성능 메트릭 완전 분석 (코드 기반)이 글은 단순 개념 설명이 아니라, 실제 코드 기준으로성능 메트릭이 어디서 어떻게 측정되고 왜 그렇게 설계되었는지를 하나씩 분해해서 설명합니다.📌 핵심 코드return Flux.defer(() -> { metrics.streamStarted.increment(); metrics.incActive(); Timer.Sample total = Timer.start(); final boolean[] ttftDone = {false}; Timer.Sample ttft = Timer.start(); return openRouterClient.chatCompletionStream(req) .d..
-
spring security oauth2 (vscode,web) 로그인 환경 구축카테고리 없음 2026. 3. 26. 09:59
1.용어 정리(중요)Authorization Server: 구글Client(또는 RP): 스프링 기반 웹 앱 (로그인 시작/콜백 처리 주체)Resource Server: 여러분 API 서버(액세스 토큰으로 보호 자원 제공). 실서비스에선 Client와 Resource Server가 같은 앱일 수도 있지만 역할은 구분해서 생각하세요.OIDC(OpenID Connect): “로그인(신원)”을 다루는 확장 규격. 구글 로그인은 사실상 OIDC 사용이 표준입니다. 2. oauth2 로그인 전체 플로우 [브라우저] │ 1. GET /oauth2/authorization/{registrationId} ← 로그인 버튼/링크 ▼[Spring Security Filter Chain] │ │ (A) O..
-
계층형 아키텍처에서 정책 변경이 왜 점점 버거워 질까?시스템설계 2026. 3. 23. 16:54
계층형 아키텍처에서 정책 변경이 왜 점점 버거워질까?주문 취소 정책 변경 예제로 보는 20단계 분석좋아요. 이 글에서는 아래와 같은 주문 취소 정책 변경이 왜 단순한 조건 수정이 아니라 시스템 전체에 연쇄 영향을 주는 일이 되는지, 실제 코드 예제를 통해 단계별로 살펴봅니다.변경된 취소 정책배송 시작 전까지 취소 가능디지털 상품은 결제 후 즉시 취소 불가쿠폰 사용 주문은 취소 시 쿠폰 복구 필요처음 보면 단순한 정책 추가처럼 보입니다. 하지만 프로젝트가 커지고 계층형 구조에서 정책이 여러 계층에 흩어지기 시작하면, 이 작은 변경 하나가 Controller, Service, Repository, 외부 시스템 연동, 이벤트 처리, 테스트까지 모두 흔들게 됩니다.1단계. 처음에는 취소 규칙이 아주 단순하다처음..
-
왜 우리는 Service를 new 하지 않을까? — DI의 진짜 이유( DIP를 했다고 착각하기 쉬운 지점 알아보기 )시스템설계 2026. 2. 25. 09:34
💡 왜 우리는 Service를 new 하지 않을까? — DI의 진짜 이유 ? 그리고 “DIP를 했다고 착각하기 쉬운 지점(패키지/모듈 의존성)”까지 한 번에 정리“구현을 직접 주입하는 것” vs “인터페이스 + 외부 주입” 완전 쉽게 이해하기스프링을 공부하다 보면 항상 나오는 말이 있다. “구현체에 직접 의존하지 말고, 인터페이스에 의존하라.” 그런데 막상 보면 이런 생각이 든다.🤔 TossPaymentClient 고치면 되는 거 아니야?🤔 왜 OrderService까지 수정해야 한다는 거지?🤔 mock으로 바꾸기 어렵다는 건 무슨 의미야?이 글에서는 아주 단순한 코드 예시로 이 차이를 정리해본다.1️⃣ 직접 구현을 박아버린 경우 (new로 연결)class TossPaymentClient { ..
-
실무에서 Service → Manager → Processor 구조로 설계하는 이유시스템설계 2026. 2. 5. 21:58
들어가며실무에서 코드를 작성하다 보면 이런 고민을 하게 된다.Service가 점점 커진다로직이 한 메서드에 몰린다테스트하기가 점점 힘들어진다“이 로직 어디까지가 한 작업이지?”가 헷갈린다나도 비슷한 문제를 겪었고, 그 과정에서Service → Manager → Processor 구조로 점진적으로 정리하게 되었다.이 글에서는 다음을 아주 쉽게 설명해보려고 한다.유스케이스란 무엇인가트랜잭션 경계는 왜 필요한가Service / Manager / Processor는 각각 무슨 역할인가실제 코드 예제1. 유스케이스란 무엇인가?한 줄 정의유스케이스 = 사용자가 의도를 가지고 한 번 행동하는 것예시 (우리 서비스 기준)백테스트를 실행한다백테스트를 공유한다공유된 백테스트를 구매한다구매한 백테스트를 조회한다👉 이 중 ..
-
SSE 스트리밍 응답이 20분 걸린 이유를 p95 메트릭으로 추적해본 기록 - 1개발회고 2026. 1. 28. 19:16
SSE 스트리밍이 15~20분 걸린다고 했을 때, 내가 했던 것들 (Prometheus/Grafana 회고)AI 응답을 SSE로 스트리밍하는 구조를 운영하다 보니 “응답이 너무 오래 걸린다”는 피드백이 들어왔다.특이한 점은 아예 응답이 없는 게 아니라, 응답은 오는데 전체가 끝나기까지 15~20분이 걸린다는 것.처음엔 막연히 “네트워크가 느린가?”, “OpenRouter가 밀리나?”, “소켓이 안 닫히나?” 같은 생각부터 들었다.근데 이건 추측일 뿐이라, 결국 결론은 하나였다.감으로 추측하지 말고, 숫자로 갈라보자.지금 구조에서 “관측 포인트”를 잡은 위치내 서비스는 AiProxyService.relayChatStream()에서 OpenRouter의 스트림을 그대로 릴레이한다.이때 Reactor Flux..
-
Tomcat,Spring Boot에서 GET,POST 요청은 어떻게 처리될까?카테고리 없음 2026. 1. 2. 08:16
Tomcat → Spring MVC → Controller → Response 전체 흐름 완전 해부 1️⃣ 들어가며Spring Boot로 개발하다 보면 우리는 보통 이렇게만 생각한다. 브라우저 → @GetMapping → 응답하지만 실제로는 이 한 줄의 요청이 처리되기까지Tomcat, Servlet Container, Filter, DispatcherServlet, HandlerMapping, MessageConverter 등수많은 컴포넌트와 메소드 호출을 거친다.이 글에서는 GET 요청(@GetMapping) 을 기준으로Tomcat에서 시작해 → Spring MVC 내부를 통과 → 다시 Tomcat을 통해 응답이 반환되는 전체 흐름을메소드 단위까지 내려가며 정리한다. [ Browser ] | ..