1. 쿠폰 발급 동시성 문제 발생 쿠폰 발급 데드락 문제 발생 (이전 글) 이전에 쿠폰 발급 동시성 테스트 중 데드락과 동시성 문제가 발생하였다!그런데 내가 처음에 집중하려던 것은 동시성 문제이기에 일단 `flush()`로 임시조치를 하고 다시 테스트를 실행해보았다. 실행 결과, 동시성 문제가 발생하였다! 발급된 쿠폰(`IssuedCoupon`)은 100개가 생성됐지만 쿠폰(`Coupon`)의 수량은 정상적으로 감소하지 않았다.이를 해결하기 위해 `비관적 락`을 도입하기로 했다. 1-1. 비관적 락을 선택한 이유락에는 `비관적 락`과 `낙관적 락`이 있다.`낙관적 락` 동시성 문제가 발생하지 않을 것이라 가정하여 동시성 문제가 발생했을 때 이를 처리하는 방식`비관적 락` 트랜잭션 충돌이 잦을 것이라 가..
공부/Project
1. 쿠폰 발급 로직과 데드락 문제 발생팀 프로젝트가 끝난 후 아쉬움이 남아, 쿠폰 기능을 따로 추출해 혼자 개발해보기로 했다.MySQL을 데이터베이스로 사용하고, 별다른 락을 걸지 않은 상태에서 쿠폰 발급 로직을 구현했다. 1-1. 쿠폰 발급 로직쿠폰 발급 로직은 다음과 같은 방식으로 작성했다.@Transactionalpublic Long issue(Long couponId, Long userId) { final Coupon coupon = validateCoupon(couponId); coupon.issue(QUANTITY_TO_ISSUE_COUPON); // TODO User 검증, 중복 검사 필요 final IssuedCoupon issuedCoupon = IssuedCoup..
작업 환경이 데스크탑에서 노트북으로 바뀌었다. 기존에 진행하던 작업을 이어가기 위해 임시 커밋을 만들어 원격 저장소에 푸시를 했다. 이후 노트북에서 푸시된 브랜치를 받아 작업을 이어갔지만, 임시 커밋은 더 이상 필요하지 않았다. 그래서 커밋 내역만 깔끔하게 제거하고 변경 사항은 유지하는 방법을 사용했다. 1. 임시 커밋 후 푸시 기존 작업을 잃지 않기 위해 모든 변경 사항을 임시로 커밋하고, 원격 저장소에 푸시를 했다. git add .git commit -m "temp: 임시 커밋"git push origin [브랜치명] 2. 다른 컴퓨터에서 브랜치 가져오기 노트북으로 작업 환경을 전환한 뒤, 푸시한 브랜치를 가져왔다. git pull origin [브랜치명] 이 과정을 통해 데스크탑에서 하던 작업..
프로젝트를 진행하면서 우리는 MSA 아키텍처 기반의 프로젝트이므로 다른 모듈에서 DTO를 참조할 수 있도록 각 서비스마다 DTO 모듈을 따로 만들어서 참조하도록 하였다. 그런데 order 서비스의 server 모듈과 dto 모듈에서 서로를 참조하게 되었는데, 오류가 났다! `순환 종속성` 때문에 난 오류였다. 이를 해결하기 위해 서로에 대한 의존성을 제거해야 했다. 서로를 참조하게 된 이유는, 이런 식으로 dto 모듈에 있는 DTO들을 Order 객체를 받아서 만들기 위해 참조한 것이었다. public static NotificationOrderDto from(Order order, String displayProductName) { return new NotificationOrderDto(ord..
배포 흐름도 코드 작성개발자가 로컬에서 애플리케이션 코드 작성 및 수정코드 푸시코드를 GitHub 리포지토리의 특정 브랜치에 푸시GitHub Actions 트리거코드 푸시 시 GitHub Actions가 자동으로 트리거됨CI/CD 파이프라인 실행 (GitHub Actions)빌드 단계애플리케이션 빌드자코코 테스트 커버리지 측정자코코를 사용하여 테스트 코드의 커버리지 측정커버리지 리포트를 생성하여 품질 확인테스트 실행빌드 아티팩트 생성Docker 이미지 빌드Dockerfile을 사용해 애플리케이션의 Docker 이미지 생성ECR에 Docker 이미지 푸시 (도커 허브 개념)빌드된 Docker 이미지를 AWS Elastic Container Registry (ECR)로 푸시ECS에 배포 - 컨테이너 관리, ..
이번에 MSA 프로젝트를 진행하면서 각 서비스끼리 `FeignClient`를 통해 호출하는 경우가 많았다. 그 중 배송담당자 CRUD 기능을 구현하는 과정에서 FeignClient의 N+1 호출 문제가 발생하게 되었다. 이를 해결한 방법을 기록해보려고 한다. 1. 배송담당자 전체 조회 기능 구현마스터 관리자는 배송담당자 목록을 전체 조회할 수 있어야 했다.1.1 배송담당자 도메인 설계배송담당자는 특정 허브에 속할 수 있기 때문에, 배송담당자와 허브는 `다대일 관계`로 설계했다. 하지만 MSA 아키텍처를 사용하므로, 객체 자체로 연관관계를 매핑하는 대신 `간접 참조`를 사용해 Hub ID만 Shipper 도메인에 넣어주었다.@Getter@Entity@Table(name = "p_shipper")@NoArg..
이번에 두 번째 프로젝트인 AI B2B 프로젝트를 진행하면서, Gateway에서 사용자 인증 및 인가 처리를 구현하게 되었다. 나는 기존에 회원가입과 로그인을 구현할 때 사용하던 방식을 그대로 적용하기로 했다. 1.1 각 MSA 서비스로 사용자 인증 정보가 전달되지 않는 문제그래서 Gateway에서 JWT 토큰을 헤더에서 추출한 뒤, 이를 검증하고 사용자 정보를 `SecurityContextHolder`에 저장하는 방식으로 접근했다. 처음에는 이 방법이 잘 작동할 것이라고 생각했지만, MSA 아키텍처 환경에서 문제가 발생했다. 각 서비스 간에 사용자 정보가 공유되지 않는 상황이 발생한 것이다.일일이 로그를 통해 하나씩 확인해 본 결과, Gateway에서 `SecurityContextHolder`에 저장..
배달 레전드 프로젝트가 끝이 났다아쉬운 점도 많지만! 팀원들과 협업하면서 배우고 얻은 것이 많기에 회고하면서 정리하고자 한다.1. 협업협업은 기존대로 디스코드와 깃허브를 활용하여 진행했다.깃허브에 issue, PR 을 발행하면 디스코드에 메시지가 오도록 설정하였다. Github를 사용하여 프로젝트를 체계적으로 관리하고, 효율적으로 협업할 수 있도록 하였다.`Project Board`를 통해 이슈들에 대한 전체적인 진행 상황을 파악하고 컨트롤할 수 있었다. 또 팀원 간 적극적인 코드 리뷰를 통해 코드 품질을 높이고 팀원 간 지식을 공유하였다. 2. 디자인 패턴팀에 엄청난 실력자 분이 계셔서 다양한 디자인 패턴도 배울 수 있었다!정적 팩토리 메서드`정적 팩토리 메서드`는 객체 생성을 위해 정적(static)..