재고 관리 문제 해결(동시성 및 DB 동기화 전략에 대해)
·
Back-End
쇼핑몰, 이커머스 서비스 등에서 상품에 대한 재고 관리는 아주 중요한 기능이다. 또한, 이 기능은 백엔드 개발자로써 동시성 문제와 성능 개선 등에 대해서 많이 다뤄볼 수 있는 적합한 주제라고도 생각할 수 있다. 프로젝트를 진행하며, 단순히 DB에서 재고 개수를 차감시키던 기능이 어떤 문제들을 가져올 수 있었으며, 이를 해결하기 위해 어떤 방법들을 적용했는지를 작성해보려 한다.동시성 문제(Lost update)먼저 코드를 보자@Transactionalpublic void deductUnsafe(UUID productId, int quantity) { // 재고 조회 Inventory inventory = inventoryJpaRepository.findByProductId(productId) ..
MSA 학습 - API Gateway
·
Back-End
이번에는 MSA 환경에서 클라이언트와 서비스 간의 통신을 관리하는 핵심 컴포넌트인 API Gateway에 대해 학습해보려 한다.우리는 MSA를 구성하면서 여러 개의 포트로 여러 개의 서비스를 관리한다. 하지만 사용자는 auth, user, product, order 등 다양한 서비스에 접근할 수 있는데, 접근하기 위해서는 각각 서비스의 포트를 미리 알고 접근해야하는 상황이 생길 수 있다. AWS 환경에서 여러 개의 인스턴스를 로드 밸런서를 통해 사용하면 로드밸런서만 알고 있어도 여러 서비스를 이용할 수 있듯이, 중앙에서 이를 관리하고 클라이언트와 통신을 하는 역할을 하는 서버가 필요하다. API GatewayAPI Gateway는 마이크로서비스 아키텍처에서 모든 클라이언트 요청의 단일 진입점 역할을 하는..
MSA 학습 - 서킷 브레이커
·
Back-End
이번에는 MSA 서비스를 운영하면서 발생할 수 있는 장애 상황 대한 방법을 학습해봤다. 이전에 FeignClient를 이용한 로드밸런싱에 대해서 다뤘는데, MSA 환경에서는 로드밸런싱만큼이나 중요한 것이 바로 `장애 전파 방지`이다. 아무리 로드밸런싱을 잘 구성해도 특정 서비스가 장애가 나면 연쇄적으로 다른 서비스들까지 영향을 받을 수 있기 때문이다. 이런 상황에서 서킷 브레이커 패턴이 필요한 이유와 Spring Cloud에서 제공하는 Resilience4j를 이용한 구현 방법을 정리해보려고 한다. 서킷 브레이커란?서킷 브레이커는 전기의 회로 차단기에서 착안한 개념이다. 전기 회로에서 과부하가 걸리면 차단기가 작동해서 전체 시스템을 보호하는 것처럼, 마이크로서비스에서도 특정 서비스에 장애가 발생했을 때 ..
MSA 학습 - 로드밸런싱(FeignClient, Ribbon)
·
Back-End
기본적으로 백엔드에서 로드 밸런서를 적용한다고 하면 하나의 인스턴스가 아니라 여러 인스턴스로 트래픽을 분산시켜 서버의 부담을 줄이는 기술이다. 나도 이전 프로젝트를 학습하면서 AWS 로드밸런서를 이용해서 2개의 인스턴스에 라운드 로빈 방식으로 부하를 분산 시키는 방법으로 적용해본 적은 있다. Spring Cloud에서 제공하는 FeignClient 등을 이용하면, MSA 환경에서도 여러 대의 서비스 인스턴스에 부하를 분산할 수 있다고 한다. FeignClientFeignClient란 Netflix에서 개발한 선언적 웹 서비스 클라이언트이다. 기본적으로 Spring 프레임워크에서는 RestTemplate을 이용해서 다른 서비스를 호출할 수 있는데, FeignClient는 이러한 보일러플레이트 코드를 대폭 ..
MSA 학습 - Spring Cloud와 Eureka
·
Back-End
혼자서 공부하기에는 현재 진행중인 프로젝트도 이슈로 인해 조금 늘어지고, 어떠한 것을 공부하면 좋을 지 모르겠어서 방향성을 잃고 있던 상황에서 시간을 헛되이 보내는 것 같다고 생각해 내일배움캠프를 듣게 되었다.다행히 완전 자바스프링 기초부터 진행하는 것은 아니고 기본적인 지식이 있는 상태에서 msa관련된 학습을 하는 내용으로 진행되기 때문에 내가 열심히만 하면 충분히 만족스러운 결과를 얻어갈 수 있을 것 같았다. 실제로 1주일 정도 진행을 했는데, 뭐랄까.. 무기력증에 빠져있던 시간이 후회될 정도로 의욕이 생겨나게 되었다. 추가로 CS관련 스터디도 진행하면서 조금 더 시간을 알차게 활용한다는 느낌이 들고 좋은 사람들을 만난 것 같아서 다행이라고 생각하고 있다. 따라서, 이번부터는 별도로 작성하고 싶은 내..
비동기 메시징 방식(RabbitMQ vs Kafka)
·
Back-End
내가 처음으로 메시지 브로커라는 키워드를 접하게 된 것은 채팅 시스템을 구현해보는 과정에서 검색을 하던 도중이었다. 채팅 시스템을 구현함에 있어 Pub/Sub 구조로 구독을 통해 메시지를 전달하게 되는데 이 때, 메시지 브로커에 대한 종류를 알게 되었다. 단순 구독 시스템이기 때문에 Spring 내장 메시지 브로커를 사용했지만, Redis, RabbitMQ 등을 더 향상된 기능으로 사용할 수 있다는 것을 알았다.여기서 RabbitMQ라는 것을 알게 되었고, 맨 뒤의 MQ를 보면 알겠지만 Message Queue로 비동기 메시징 큐를 통해 시스템의 부하를 줄이고 성능을 높일 수 있다고 한다.아직까지 적용해볼 기회가 없어서 실제로 적용해본 적은 없지만, 다음 프로젝트에서 사용해볼 생각이며 어떠한 장점이 있길..
@Transactional(readOnly=true)는 왜 써야하는걸까?
·
Back-End
백엔드 학습을 하며 DB에 대한 학습을 진행하면 필수로 익혀야 하는 부분이 바로 트랜잭션이다.`org.springframework.transaction.annotation` 패키지에 속한 `@Transactional` 어노테이션을 이용하면 우리가 원하는 메소드에 트랜잭션을 걸어 영속성 컨텍스트를 활용할 수 있다. 파일을 수정, 삭제를 할 때 일관성과 정합성을 위해 `@Transactional` 어노테이션을 사용하는 것은 이제는 너무 당연하게 느껴지는 사항이다. 그런데 트랜잭션의 옵션에 보면 readOnly 라는 옵션이 존재한다.트랜잭션을 사용하는 가장 단순한 이유에서 생각해본다면, 수정 혹은 삭제 등의 변경사항이 일어났을 때 오류가 발생해 하나의 연결된 로직이 부분 수정이 되는 현상을 방지하기 위해 트랜..
[JPA] 외래키 주인으로 알아보는 엔티티 연관관계
·
Back-End
우리는 프로젝트를 진행하며 DB 스키마 구조에 따른 많은 연관관계를 맺는다. 일대일, 다대일, 다대다 등 현실에서 맺어지는 관계성을 DB의 연관관계로 매핑하여 데이터를 정규화해 효율적으로 관리할 수 있다. 자바/스프링 프로젝트를 하게 되면 Spring Data JPA를 주로 사용하는 경우에는, 엔티티레벨에서 연관관계를 매핑하고 이에 따라 단방향, 양방향 등의 구성을 하게 된다. 그런데, 책을 보거나 강의를 듣게 되면 외래키 주인이라는 키워드가 나오게 된다. 실제 프로젝트를 진행하면서 한번도 고려해보지 않던 부분들을 한 번 생각해보려 한다. 외래키 주인(연관관계의 주인)JPA에서 연관관계의 주인이라고 불리는 외래키 주인은 양방향 연관관계에서 실제로 외래키를 관리하는 테이블(엔티티)를 의미한다. 예를 들어..
테스트 코드 작성 전략
·
Back-End
초기 기능 구현 시, 테스트 코드를 함께 작성하면 기능이 적을 때는 얼마 걸리지 않던 부분이 개발이 진행되고 기능이 누적됨에 따라 테스트 코드도 함께 누적되고 의존성도 복잡해지며 테스트 자체의 시간이 오래 걸리는 경우를 확인할 수 있다. 돌이켜보면 분명 초 단위로 금방 끝나던 테스트들이 2~3분을 넘기게 되고 점점 기능이 개발됨에 따라 계속해서 테스트 시간이 늘어감을 확인할 수 있다. 물론, 정말 필요한 테스트가 오래 걸릴 수는 있지만, 테스트 시간은 동일 커버리지라면 짧을 수록 더 좋다고 생각한다. 내가 주로 진행한 프로젝트 테스트 코드의 대부분이 통합 테스트 기반이기 때문에 테스트 컨테이너.. DB 연동.. 등의 과정이 들어가며 불필요한 시간 소모가 많다고 생각했고, 리팩토링을 통해 단위테스트로 분리..
이메일 인증 기능 비동기 적용 과정
·
Project/PickLab
회원 기능이 존재하는 서비스의 경우, 이 회원이 정상적인지를 판별하기 위해 인증 서비스를 적용하게 된다.주로 pass 인증, 문자, 이메일 등 프로젝트의 기획에 맞춰서 필요한 인증 서비스를 사용한다.우리 프로젝트의 경우 소셜 회원가입 이후에, 마케팅 광고 등의 알림 메일을 받는 메일 주소를 변경하는 기능이 존재한다.따라서, 유저가 변경하고자 하는 이메일이 본인의 이메일이 맞는지 확인을 하기 위한 인증 과정이 필요하다. 기본적인 흐름의 경우, JavaMailSender을 이용해서 구현하였으며, 다음과 같이 구성하였다.인증하기 버튼을 누를 경우, 6자리의 무작위 코드를 생성한다.expired_at이라는 컬럼을 현재 시간 기준 5분 후로 설정하여 DB에 저장한다.유저에게 이메일을 보낸다.이제 조금씩 개선을 진..