TroubleShooting & Study/SpringBoot 17

[Annotation] 유효성 검사 어노테이션 여러 개를 합칠 수 있을까? (feat. Custom Annotation, Validation)

Untitled 개발 이후, 회사의 다른 서비스를 만들면서 하나의 계정으로 회사의 모든 서비스들을 이용할 수 있으면 유저들이 편할 것 같다는 생각을 했다. 그래서 대표님게 SSO(Single Sign On)을 건의했고, 그렇게 통합 인증 서버를 만들게 되었다. 통합 인증 서버는 앞으로 회사의 모든 서비스들에서 트래픽이 몰릴 것이므로 좀 더 단단하게 만들고 싶었고, 이전에는 사용하지 않았던 Validation을 적용해보기로 했다.     Validation    먼저 Spring Validation은 @RequestBody, @RequestParam, @PathVariable에 대해 유효성 검증을 수행하고, 유효하지 않는 데이터인 경우 Exception을 발생시키는 라이브러리이다 내가 제일 먼저 적용한 A..

[Spring Cache] 좋아요 기능 설계 & 성능 개선 (feat. Redis)

현재 Untitled의 유저 쇼츠 테이블을 보면, 특정 쇼츠를 조회를 위해 '쇼츠 좋아요 수'가 필요하기 때문에 매번 count 쿼리를 날려야 한다. 또한 단순 쇼츠 조회뿐만 아니라 인기순으로 정렬을 할 때도 '쇼츠 좋아요 수' 가 필요했는데, 이 기능은 '쇼츠 좋아요 수'를 count 하여 정렬하고 page size만큼 shorts를 가져오는 로직이다.  따라서 이러한 구조는 유저가 늘어나면 분명히 성능에 악영향을 끼치리라 판단하여 리팩토링을 시작하게 됐다         Count Query   먼저 가장 큰 영향을 주는 건 count 쿼리라고 생각해서, 이 부분을 없애기로 했다. 그래서 구조 자체를 수정해야 했고, 테이블에 '좋아요 수'를 컬럼으로 저장하기로 했다. 이런 구조에서는 곧바로 '좋아요 수..

[CS지식을 Spring에 접목해보자] JWT는 어디에 저장해야할까? (feat. Cookie, Local Storage)

Spring에서 JWT를 사용한 인증/인가를 진행할 때, Server에서 Client로 AccessToken과 RefreshToken을 발행해줄 것이다. 이때 Cookie에 저장하는 방법과 로컬 스토리지에 저장하는 방법이 있는데, 이번 시간에는 두 방법의 장/단점을 알아보고 어떻게 사용하면 좋을지 고민해보자      Web Browser에 토큰을 저장할 때의 취약점   우리는 성능 향상과 확장성을 위해 세션 대신 JWT를 사용한다. 성능 향상은 메모리 사용량과 DB Connection을 줄일 수 있어서 그렇다 치지만, 확장성은 어떻게 보장해줄까? 그건 바로 서버에서 보내주는 토큰을 브라우저에 저장함으로써 서버에서 사용자의 인증 정보를 기억하지 않아도 되기 때문이다. 그러나 이러한 확장성 때문에 브라우저에..

[SSE] java.io.IOException : Broken pipe

이번에는 Spring에서 SSE를 사용하여 데이터를 전송할 때 발생하는 'java.io.IOException:Broken pipe'를 대응법을 알아보겠다.왜 해결법이 아니라 대응법이라 적었냐면... 진짜 말 그대로 'Broken pipe'가 발생하지 않게끔 해결하는 것이 아니라, 발생했을 때 대응하는 방법을 설명할 것이기 때문이다.       java.io.IOException:Broken pipe   이 Exception은 다음과 같은 상황에서 발생한다데이터 송수신 중 연결이 끊어진 경우: 클라이언트와 서버에서 유지 중인 connection이 끊어졌을 때, 이를 통해 데이터를 전송하려 하면 발생네트워크가 서버 CPU 문제로 송신받은 데이터를 처리하지 못한 경우: 송신받은 데이터를 적절하게 처리하지 못하..

[Rate Limiter] 트래픽 제어를 위한 처리율 제한 기능 (실전편 - Redis, Bucket4j)

이번에는 실제 서비스에서 처리율 제한 기능을 설정해 보겠다 1. Dependencies Sample Code를 작성했던 것처럼 서버 메모리에서 Bucket을 생성해서 관리할 수도 있지만, 서버가 재실행되면 Bucket의 정보가 날아가므로 대체제를 찾아야 한다 먼저 Rate Limit을 걸어줄 API의 특징에 따라 달라지겠지만, 나는 유저마다 Rate Limit을 설정해 줄 것이기 때문에 'User'-'Bucket' 형태로 정보를 저장해야 했고, RDB와 Redis라는 선택지가 있었다 마침 Bucket4j에서 Redis를 지원해주기도 했고, 각 유저가 API를 호출할 때 RDB에서 Bucket을 조회한다면 DB connection이 너무 많이 일어날 것 같기에 Redis를 선택하기로 했다    2. Con..

[Open AI API, Feign Client] Java로 Open AI API 사용하기

OpenAI 홈페이지의 API docs에 들어가면 세 가지 library의 request example을 보여준다  (주소: https://platform.openai.com/docs/api-reference/chat/create)  처음에 'curl, python, node.js' 세 가지만 나오길래 java로는 사용할 수 없나? 라는 생각을 했지만.. 그럴 리가 없지curl은 'Client URL'로, 다양한 통신 프로토콜을 지원해주기에 자신의 서버에서 Http 통신으로 요청을 주고받을 수 있다즉, 그냥 형태만 올바르게 맞춰서 request를 보내면 response를 받아올 수 있다는 것이다 스프링에서는 서버에서 http 통신을 지원해주는 다양한 라이브러리가 존재하는데, 나는 그중에서 Feign Cl..

[WebSocket] WebSocket으로 채팅 구현하기 - 이론편 (특징, 동작과정, STOMP)

WebSocket   WebSocket을 공부하기 전에는, WebSocket이 그저 양방향 통신을 제공하는 특정 기술을 말하는 줄 알았다. 하지만 WebSocket이란 기술을 의미하는 것이 아니라 양방향 통신을 제공하기 위해 개발된 '프로토콜'을 의미한다. 간단하게 설명하자면, WebSocket 통신을 사용하는 URI로 HTTP Request를 보냈을 때 요청이 올바르다면 protocol을 HTTP에서 WS(WebSocket)으로 Upgrade 한다. 그 이후에는 WS 프로토콜을 사용하여 양방향 통신을 진행한다고 생각하면 된다.   WebSocket의 특징과 통신 과정을 자세히 알아보자WebSocket 특징HTTP 통신과 다르게 서버에서 Response를 받고 난 이후에도 Connection을 그대로 유..

[Rate Limiter] 트래픽 제어를 위한 처리율 제한 기능 (실전편-sample code, Bucket4j)

이론 편에서는 Rate Limiter의 다섯 가지 알고리즘을 공부했었다. 이번 글에서는 SpringBoot에서 Rate Limiter를 지원하는 라이브러리를 비교해 보고, 한 가지를 사용해서 샘플 코드를 작성해 보겠다.    Rate Limiting 라이브러리   Spring에서 처리율 제한 기능을 지원하는 라이브러리들의 장단점을 살펴보고, 내 서비스에 어울리는 라이브러리를 골라보자 Guava - Rate Limiter구글이 개발한 오픈소스 라이브러리로, Token Bucket 알고리즘을 기반으로 동작장점사용이 쉽고 직관적이며 안정적임단점동시성 제어가 약하고 분산 시스템에 부적합기본적인 rate limiting 기능만을 제공함RateLimitJSliding Window 알고리즘 기반github readm..

[Rate Limiter] 트래픽 제어를 위한 처리율 제한 기능 (이론편)

Untitled 서비스에서는 request마다 요금을 내야 하는 외부 api를 사용하고 있어서, 이 경우 유저의 무분별한 api 호출 때문에 예상 비용을 초과할 수 있으므로 어느 정도의 제한이 필수적이다. 또한 동일한 짧은 시간 동안 서버에 부하를 가하는 DDos 공격등을 막기 위해서라도 api 호출에 제한을 걸어야만 한다. 이를 위한 방법으로 api 호출에 대한 요청 빈도를 제어하는 Rate Limiter에 대해 알아보자      Rate Limiter   Rate Limitting은 '서버가 특정 임계치까지만 클라이언트의 요청을 허용하는 정책' 으로, Rate Limiter는 유저의 요청이 Rate Limit 값을 초과하면 API 호출을 제한시키는 역할을 한다. 이렇게 API 호출을 우리가 원하는 수..

[Test] DIP 적용시켜서 테스트 코드 시간 단축시키기 - 실전편

이번에는 UserService, AuthService에 DIP를 적용시켜, 기존에 작성했던 AuthServiceTest, RestoreAuthTest, UserServiceTest의 시간을 단축시켜보고자 한다 https://kdh0518.tistory.com/entry/Architecture-Layered-Architecture-%ED%83%88%EC%B6%9C%EA%B8%B0-feat-SOLID-Hexagonal-DDD-Test-Code [Architecture] Layered Architecture 탈출기 (feat. Hexagonal, Test Code)개발을 시작하며 기본적인 MVC 패턴과 Layered 아키텍처를 공부한 이후 줄곧 Layered로 백엔드 패키지 구조를 설계했었다. 내가 지금까지 ..