TroubleShooting & Study 34

[Domain Model Pattern] 도메인 모델 패턴에서 테스트코드 작성에 대한 고찰

최근 'DDD'와 '도메인 모델 패턴'에 관심을 보이신 스터디원께 이런 질문을 받았다"DDD를 적용하면 비즈니스 로직이 도메인 모델에 위치하는 거라 이해했는데, 그렇다면 테스트코드는 어떤 방식으로 작성하나요? 그냥 하면 되는 건가요?" 최근에는 테스트코드를 작성한 적도 잘 없었고, 있더라도 그냥 기계적으로 작성하다 보니 한 번쯤은 정리해 보면 좋을 것 같아서 '도메인 모델 패턴에서의 테스트코드'에 대해 생각해 보게 됐다 작성하고보니 'DDD'나 '도메인 모델 패턴'에 국한된 게 아니라, 어떤 형태로 프로젝트를 구성하든 테스트코드를 작성할 때 고민해 보면 좋은 것이라 생각된다어쨌든 오늘은 이 질문을 바탕으로, 테스트코드에 대해 내가 어떤 방식으로 접근하고 있는지를 이야기해 보겠다 첫 테스트코드 ..

[TOCTOU] 사용자 경험을 고려한, 회원가입시 중복체크 플로우 개선

현재 서비스에서 soft delete 정책을 도입하면서 회원가입 플로우에 예상치 못한 문제가 발생했다. 기존에는 DB의 unique 제약조건으로 간단하게 해결되던 중복 방지 로직이, soft delete 환경에서는 더 이상 작동하지 않게 된 것이다 또한 여러 사용자가 겹치는 시간대에 회원가입을 진행할 때 발생하는 TOCTOU(Time-of-Check to Time-of-Use) 문제와 더불어, 사용자가 회원가입 도중 해당 페이지를 벗어났을 때의 사용자 경험(UX)까지 고려해야 하는 상황이 되었다 따라서 이번 글에서는 'TOCTOU'문제를 해결하되, '사용자 경험'까지 고려한 회원가입 플로우 개선 과정을 소개하려 한다 기존 회원가입 플로우와 TOCTOU 문제 먼저, 변경전 기존 회원가입 플로..

[Task Scheduler] 불규칙적인 task 처리 (동적 스케줄링) + 영속성 처리

불규칙적 상황? 동적 스케줄링?    개발을 진행하다 보면 특정 시점에 기능이 동작해야 하는 경우가 존재한다.trigger가 존재한다면 단순하게 trigger 메서드에서 target 메서드를 실행하면 되지만, trigger가 시간인 경우 어떻게 처리할 수 있을까?  예를 들어 '예약 서비스'에서 사용자가 특정 시간에 예약을 했을 때, 예약 시간 10분 전에 알림을 보내는 기능을 생각해 보자.사용자의 예약 시간은 정기적인 것이 아니라 랜덤 하기 때문에 'cron 식'을 사용한 단순 scheduler'를 사용한다면 상당히 비효율적일 것이다.  사용자 예약 시간을 다음처럼 가정해 보자예약 시간-> 10:30, 12:00, 17:00  이 경우 cron 식을 사용해서 처리하려면 30분 단위로 계속해서 예약이 존..

[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 쿼리라고 생각해서, 이 부분을 없애기로 했다. 그래서 구조 자체를 수정해야 했고, 테이블에 '좋아요 수'를 컬럼으로 저장하기로 했다. 이런 구조에서는 곧바로 '좋아요 수..