🎯 CircuitBreaker와 Retry가 뭘까? 프로젝트를 진행하면서 주문 서버에 재고 관리 로직이 함께 들어가 있었다. 재고 관리 로직은 주문, 결제, 상품 관리 등 다양한 로직에 사용되어 트래픽이 많을 것으로 예상되어 확장성을 가지면 좋겠다고 생각하였고, 각 기능별로 유지보수를 위하여 서버를 분리해 보는 학습을 해보면 좋겠다고 생각하였다. 회복탄력성은 Open Feign의 resilience4j-circuitbreaker 와 resilience4j-retry를 사용하였다. MSA 학습을 위하여 뉴스피드 도메인을 간단히 설계하였다. https://topaz-raincoat-203.notion.site/65cae744cebd44cbabc3771e222e3737?pvs=4 위와 같이 분리된 서버 간에 ..
프로젝트
🎯 한 사람에 대한 여러 요청을 어떻게 제한할 수 있을까? 예약 상품 프로젝트는 특정 시간에 상품이 오픈되고, 많은 사용자가 짧은 시간에 주문 요청을 할 것이라고 가정한다. 위의 그림에서 고려사항1이 생겼다. 한명의 사용자가 여러 PC에서 로그인하여 동시 요청하는것을 방지하려면 어떻게해야할까? 고민해본 해결방법은 아래와 같다. 1. 로그인할 수 있는 기기 개수에 제한을 건다. 2. Gateway에서 RateLimit을 구현하여 많은 요청을 막는다. 🎯 [프로젝트에 적용] 로그인 기기 개수에 제한 걸기 로그인 할 수 있는 기기 개수에 제한을 두어 많은 PC에서 같은 ID로 주문 요청 하는것에 제한을 두려고 한다. 현재 로그아웃 구현 상태는? 현재 로그아웃 방식을 활용하기 위하여 redis를 활용하고 있다..
📌 서버를 확장한다면 synchronized를 사용하면 안 될까? 이 전에 단일 서버 환경에서 synchronized를 활용하여 동시성 문제해결에 접근해 보았다. 만약 현재 상태에서 서버를 확장한다면 어떻게 될까? 아래와 같이 하나의 프로세스 내에서는 synchronized로 인해서 1개의 스레드만 redis에 접근할 수 있다. 그러나 여러 프로세스 상에서는 동시에 redis에 접근할 수 있기 때문에 redis와 관련된 연산을 원자적으로 처리할 수 있도록 해줘야 한다. 만약 아래와 같이 redis가 아니라 MySQL과 같은 Database로 바로 접근하는 경우라면 synchronized와 MySQL의 테이블락을 활용하여 시스템을 구성해 볼 수 있을 것 같다. 이런 경우에는 각 서버에서 synchroniz..
📌 고민사항 이전에 재고의 동시성 문제를 해결하기 위하여 synchronized를 활용하여 재고수량 변경 부분에 락킹 처리를 해주었다. 그리고 단일서버 synchronized의 임계영역을 최소화 하기위해서 상품 판매 오픈전에 미리 특정상품 A에 해당하는 재고 수량정보를 로컬서버에 캐싱해 온 후 수량정보를 변경하는 방식을 생각했었다. 이러한 상황에서 아래와 같이 크게 3가지 고민사항이 생겼다. 1. 캐싱을 한다면 로컬 서버(메모리)에 캐싱할 것인가? 아니면 redis와 같은 global캐시를 활용할 것인가? 2. 상품 판매 오픈전 캐싱해올 때 어떤방식으로 캐싱해 올 것인가?(판매자의 수동처리 or 배치처리) 3. 캐시의 경우 서버가 다운되는 순간 날아가 버리고, 재고수량 관리에 문제가 생길 것이다. 이러한..
📌 고민사항 재고 증가/감소 로직에서 동시성 문제가 발생하였고, 해당문제를 해결하기 위해서 뮤텍스, 세마포어, 원자적연산등의 방법들을 고려하였다. 자바에서 뮤텍스 방식을 활용하기 위해 synchronized를 지원하는데, 동시성 문제가 발생할 수 있는 임계영역에 락을 걸어서 다른 스레드가 접근하지 못하도록 막는 방식이다. 락 방식을 사용할 때 가장 생각해봐야 할 점은 하나의 스레드에서 락을 걸어버리는 순간 다른 스레드는 해당 자원에 접근하지 못하기 때문에 대기를 하게되고, 병목현상이 발생될 수 있다는 점이다. 그래서 synchronized를 적용시킬 때에는 적용시킬 영역을 최소화 하는것이 중요하다. 📌 기존의 재고 감소 로직 아래는 동시성 문제가 발생할 수 있는 재고 수량 감소 메서드이다. @Transa..
📌 목표 3주 차는 실제로 계획한 테이블을 생성하고, 데이터를 옮기는 작업을 수행하는 것이었다. 테이블의 데이터를 새로운 테이블로 옮기기 위하여 옮길 새로운 데이터베이스를 연결하고, 데이터를 옮긴 후 테스트까지 작성해 보는 것이 목표였다. 4주 차 과제의 목표는 하나의 채팅서버에 API와 소켓서버가 통합되어 있어서 API 배포 시 소켓 서버의 세션이 끊기는 문제가 있는데, 이를 해결해 나가는 과제였다. 📌 데이터베이스 dual update 먼저 서버에 새로운 Database를 연결하여 하나의 서버에 2개의 데이터 베이스를 연결하는 것이 목표였다. NestJS에 PostgreSQL을 연결하는 방법은 2가지를 고려하였다. 1. ts-postgres 2. typeORM Spring 환경에서 JDBC를 사용할지..
📌 직무부트캠프 채팅 마이그레이션 백엔드 직무 체험 2주차 회고 2주차 부터는 본격적으로 프로젝트를 분석하고, 마이그레이션 계획을 세우는 것 이었다.(두근두근) 📌 어떤 테이블을 마이그레이션 해야할까? # 마이그레이션 테이블 선정 마이그레이션 테이블 선정함에 있어서 말도 안되는 실수를 저질렀다. "그냥 데이터 많이 쌓이는 테이블을 옮기면 되는거 아니야?" 부끄러운 수준의 생각이다.. 그냥 같은 건 없다. "데이터가 많이 쌓이는 테이블을 옮겨야한다" 라는건 맞는 말이겠지만 조금 더 구체적인 기준과 이유가 정리되어야 한다. 최종적으로 나는 chat, chat_like, user 테이블을 선정하였고, chat과의 연관관계(join을 통한 결합 등)를 근거로 제시하였다. chat데이터 응답이 user, chat..
📌 직무부트캠프 채팅 마이그레이션 백엔드 직무 체험 1주차 회고 채팅프로젝트 마이그레이션이라는 주제로 직무 체험에 참여했다. 주차별로 과제를 수행하고 제출 후 피드백을 받으며 진행된다. 과제를 수행하며 고민했던 내용들, 그리고 배웠던 점을 남겨놓으려고 한다. 📌 새로운 환경과 기술에 빠르게 적응하는 연습 # NestJs와 PostgreSQL 개발환경 세팅 프로젝트를 분석하고 앞으로의 마이그레이션 계획을 세우기 위해서는, 프로젝트를 내 로컬 환경에 세팅하고 프로젝트에 적응된 기술을 빠르게 습득해야 했다. 앞으로 개발자를 하면서 수많은 기술을 새로 접하게 될 것이고, 취업 후 직무에 투입된다면 빠르게 적응해 나가야 할 것이니, 이번 직무를 실전이라고 생각하고 수행하였다. 현재 나는 Java/Spring 환경..
📌 1. 문제상황 주문API에 대해 검토하던 중, 주문 상태 변경에 대해 데이터 경쟁 문제가 발생할 수 있다고 판단하였다. 마치 멀티쓰레드 환경에서 동시성 문제가 발생하는 것 처럼, 주문수락과 주문취소가 동시에 발생했을 때 운이 좋지 않으면 사용자에게는 주문 취소 요청이 되었다고 응답될 것이고, 음식점은 주문 취소된지 모르고 수락하여 처리해버리는 사태가 발생할 수 있다. 📌 2. 분석 실제로 이러한 데이터 경쟁문제가 발생하는지 확인하는 과정이 필요했다. 그래서 아래와 같이 주문수락 요청 후 10초정도 대기하면서, 주문 취소요청을 수행하도록 하였다. 1. 판매점 계정으로 주문 수락 하기 -> 2. 주문 수락 요청 후 10초안에 주문 요청자 계정으로 주문 취소하기 @Transactional public Or..
Security의 crypto라이브러리 사용하기 비밀번호 암호화를 위한 라이브러리 추가 회원 도메인의 회원가입 기능을 구현할 때, 비밀번호를 그냥 저장하기보다는 암호화를 해서 저장하면 보안성이 더 뛰어날 것이다. 암호화를 위해서 제공되는 여러 라이브러리들이 있는 것 같다. 대표적으로 crpto라이브러리가 있는데, spring-security모듈에도 포함되어있기 때문에, spring-security 의존성을 추가하였다. 우선 spring-security라는 모듈을 추가할 때, spring-boot의 자동설정 기능이 적용이 된다. 나는 여기서 암호화 기능만을 우선 적용하고 싶고, 별도의 security기능을 적용시키지 않을 예정이므로, 자동으로 설정되어있는 기능들중 필요없는 기능은 초기화해주던가 새로 설정을..