TroubleShooting & Study 34

[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을 그대로 유..

[Docker] ERROR 1045 (28000) : Access denied for user 'root'@'localhost' 해결 방법 총 정리

해커톤 당일 12시가 넘어서 기획이 끝이 나고, 부랴부랴 aws 계정 만들고(몰랐는데 기존에 사용하던 네이버, 구글 계정을 죄다 aws 계정으로 만들었다 삭제해 둔 상태였다. 분명 몇 달 지나면 다시 사용할 수 있다고 들었는데, 이미 사용하고 있는 이메일이라고 사용 거부당했다. 그래서 구글 계정부터 새로 만든다고 한 시간을 날려먹었다. 이런 부분을 미리 확인했어야 했는데.. 나란 놈 멍청한 놈) dockerhub 계정도 만들고, github actions workflows도 작성하고, 마지막으로 ec2에 접속해서 docker-compose.yml를 작성했다. 세팅은 끝이 났고 mysql workbench에 들어가서 db 연결한 후, 열심히 으쌰으쌰 코드 작성하고 push만 하면 끝~~~~인 줄 알았는데...

[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로 백엔드 패키지 구조를 설계했었다. 내가 지금까지 ..

[Architecture] Layered Architecture 탈출기 (feat. Hexagonal, Test Code)

개발을 시작하며 기본적인 MVC 패턴과 Layered 아키텍처를 공부한 이후 줄곧 Layered로 백엔드 패키지 구조를 설계했었다. 내가 지금까지 진행했던 프로젝트들은 대부분 데드라인이 있어서 일정 기간 안에 빠르게 끝내야 했고, 내 실력도 많이 부족했기에 테스트코드나 패키지 구조, 고도화 등은 생각조차 하지 못했다. 그러다 최근에 여유가 좀 생기면서 실제로 서비스를 운영해보고 싶다는 생각이 들었고, 좀 더 견고한 서버를 운영하기 위해 테스트코드 작성에 관심이 생겼다. 열심히 여기저기 구글링을 해보고 깃허브도 뒤져가며 테스트 코드를 작성하려 했지만, 내가 진행하던 프로젝트에서는 테스트 코드가 볼륨이 너무 크고 코드 작성 자체가 너무 어려웠다. 아주 작은 기능 하나를 테스트하려면, 서비스 하나에 묶여있는 ..