TroubleShooting & Study 31

[AWS] EC2 Key Pair 다른 Region으로 옮기기 (feat. Value for parameter PublicKeyMaterial is invalid. Length exceeds maximum of 2048)

EC2의 Key Pair는 다른 리전으로 복사할 수가 없다.하지만 Key Pair Import 기능이 있으니, 기존의 Key Pair를 직접 까서 값을 복사한 후 import 해주는 방법을 사용해 보자. 이때 Key Pair Import시에 private key가 아닌 public key만을 import 할 수 있으므로, 다음 절차를 잘 따라서 진행하자.  1. Key-Pair가 저장된 디렉터리로 이동 2. 다음 명령어를 사용하여 private key에서 public key를 추출ssh-keygen -y -f Key이름.pem  3. AWS EC2 -> Network & Security -> Key Pair로 이동해서 "키 페어 가져오기"  4. 이름 & 추출한 public key 붙여 넣고 생성   5..

[RabbitMQ] RabbitMQ Management 접속 에러 해결하기

Problem: aws ec2에서 RabbitMQ를 docker-compose로 실행시켰는데 RabbitMQ Management인 'ec2 ip:15672'에 접속하면, 'ec2 ip에서 접근을 거부하였습니다' 에러 발생  Environment - aws ec2- docker-compose에서 포트 포워딩 설정 완료- 인바운드 규칙에서 15672 포트 설정 완료 DOCKER-COMPOSE.YMLDOCKER-COMPOSE.YML-----------------------------version: "3"networks: # network를 먼저 정의해줘야 services에서 붙일 수 있다 my-network: # 네트워크 이름 external: true # 이미 생성되어있는 네트워크 사용# docker..

[RabbitMQ] docker-compose 실행시 오류 해결

ec2에서 docker-compose를 사용하여 rabbitmq를 실행할 때 발생했던 오류들의 해결과정을 정리해보았다docker로 실행시킨 rabbitmq 컨테이너 로그는 "docker logs 컨테이너이름" 으로 확인할 수 있으니 확인해보자 origin - Infoserveraws ec2ubuntu 22.04.5 LTSdocker-composeversion-3RabbitMQrabbitmq: image: rabbitmq:3-management-alpine container_name: rabbitmq ports: - "5672:5672" # default - "15672:15672" # management plugin volumes: - ./.docker/rabbitmq/data..

[RabbitMQ] RabbitMQ를 사용한 분산 서버 간 데이터 동기화

현재 우리 회사의 서비스는 Untitled와 Titled 두 개가 존재한다. 이 서비스들에서 통합 계정을 사용하기 위해서는 인증/인가를 담당할 Auth 서버가 필요해서 총 세 개의 분산된 서버를 운용하게 된다. 문제는 이 서버들이 사용하는 DB 또한 다르기 때문에, 분산된 서버들에서 공통적으로 사용되는 유저 데이터가 동기화될 필요가 있다는 것이다. 이번 글에서는 내가 어떤 식으로 분산 서비스간 데이터 동기화를 구상했는지 알아보겠다      현재 상황 및 방법 선택에 있어서의 기준 정의   먼저, 여러 방법들 중에 우리 서비스에 적용할 방식을 고르기 위해 내가 중요하게 생각했던 기준은 다음과 같다문제를 효율적으로 해결할 수 있어야 한다: 당연하겠지만, 분산 서비스간 데이터를 실시간으로 동기화 할 수 있어야..

[Github] Issue와 Pull Requests 연동하기

팀 프로젝트를 진행하다 보면 PR (Pull Requests)는 필수적으로 사용하게 된다. 그리고 PR은 코드 리뷰어를 위해 최소한의 단위로 만들게 되는데, 이렇게 되면 하나의 전체적인 기능을 위해 여러 가지 PR이 생기게 된다.(ex. 회원가입에 필요한 기능: 이메일 중복확인 API, 인증 이메일 전송 API, 인증번호 확인 API, 닉네임 중복확인 API ... 수많은 기능이 필요하다 )  문제는 개발을 진행하다보면 PR들이 섞이면서 이 PR이 어떤 도메인, 어떤 기능을 위한 PR인지 한눈에 알아보기가 힘들어진다따라서 오늘은 이런 문제를 해결하기 위해 하나의 전체적인 기능을 Issue로 등록하고, 거기에 작은 기능의 PR들을 연결시켜 서로 연관된 PR을 모아서 관리할 수 있도록 해보겠다.       ..

[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..