목록사이드 프로젝트 (36)
개발놀이터
기존 ver.2에서 Redis를 도입해 RDBMS의 부하를 30퍼센트 줄여 문제점을 개선하였습니다. 하지만 읽기 요청이 많아지면 Redis에 큰 무리가 가게 되고 Redis가 standalone 상태에서 다운되면 뒤에 있는 RDBMS도 다운될 가능성이 있습니다. 때문에 Redis의 고가용성을 유지하는 것이 새로운 과제가 되었고 이번 ver.6에서 Redis Sentinel을 이용해 문제를 해결하게 되었습니다. 왜 Sentinel이었나?Redis에 고가용성을 위한 옵션으로 Sentinel과 Cluster가 존재합니다. 둘 중 Sharding이 지원되는 Cluster가 상위호환이지만 Sentinel을 선택하게 되었습니다. Sentinel을 선택한 이유는 우선 첫번째로 프로젝트에 Sharding이 필요할..
백엔드에서 가장 난이도 있기로 소문난 특정 지점에 트래픽이 몰리는 상황을 대비하여 Redis를 이용해 대기열을 만들었습니다. https://coding-review.tistory.com/530 Redis로 대기열 구현하기이번 포스팅에선 Redis로 대기열을 구현한 것을 공유하려고 컴퓨터 앞에 앉았습니다. 이번에 주요한 기능은 WebSocket과 Redis의 Sorted Set 자료구조입니다. Sorted Set은 정렬 알고리즘의 시간 복잡도coding-review.tistory.com 제 프로젝트는 온라인 쇼핑몰인만큼 블랙프라이데이나 콜라보 이벤트를 하는 경우 트래픽이 몰리는 것을 대비하여 대기열을 만들었습니다. 이번 대기열을 이용해 애플리케이션 서버 부하와 RDBMS의 부하를 획기적으로 줄일 수..
기존 프로젝트에서 동시성 문제가 발생하였고 이를 JPA의 비관적 락으로 해결하였습니다. 하지만 비관적락이 RDBMS로 하여금 락킹 매커니즘을 관리하기위해 커넥션을 생성하고 이때문에 RDBMS에 부하가 발생한다는 문제가 발생했습니다. 해결방법으로 Redis의 라이브러리인 Redisson을 이용해 분산 락을 구현했습니다. 기존에 사용하던 Lettuce는 스핀락의 개념으로 Redis에 lock을 지속적으로 확인해야 하기 때문에 RDBMS의 부하가 그대로 Redis로 몰린다는 단점이 있었습니다. 때문에 Redisson을 사용하게 되었습니다. wrk2로 부하 테스트를 진행하였고 docker로 컨테이너를 모니터링 하여 테스트를 진행했습니다. 특징RDBMS는 MySQL을 사용하였습니다. 스레드는 8개, 동시 커..
사이드 프로젝트인 온라인 쇼핑몰에 Redis를 이용해 Client Side Caching을 적용했습니다. Redis 6에 추가된 RESP3 프로토콜을 사용했고 Redis Client인 Spring Boot에서 CacheFront 를 이용해 클라이언트 사이드 캐싱을 구현할 수 있었습니다. wrk2를 이용해 API 테스트를 진행했습니다. 스레드 개수 : 8개동시 연결 : 50개지속 시간 : 60초초당 요청 수 : 1000개 성능 개선동일한 기준에서 테스트를 진행했을 때 Redis를 순수하게 이용했을 때와 local caching을 이용했고, 이로인해 Latency는 평균 80% 최대 130% 개선하였고, throughput은 평균 4% 최대 250% 개선하였습니다. 이로 인해 얻은 것기존 프로젝트에서..
코드를 리팩토링 하는 과정에서 Collection에 담긴 내용을 if문 두개로 중첩해서 걸러내는 로직이 있었습니다. 로직을 간단하게 설명하자면 사용자가 장바구니에 담은 상품의 사이즈와 데이터베이스에 존재하는 상품의 사이즈 중 같은 것을 찾고 (ex. 장바구니에 105사이즈를 담았다면 데이터베이스에 105사이즈를 검사함) 찾은 것 중에 재고를 비교해서 장바구니에 선택한 수량이 데이터베이스에 남아있는 수량보다 많은 경우 (ex. 장바구니에 2개를 넣고 결제하려는데 데이터베이스엔 1개밖에 없는 경우) 를 비교해서 만약 그런 상황이라면 재고가 남아있지 않는다는 메시지를 띄워주기위해 설계한 로직입니다. 들여쓰기가 세번 이상 되었기 때문에 리팩토링 해야겠다고 생각했고 StreamAPI를 이용해서 깔끔하게 리팩..
오늘도 사이드 프로젝트를 리팩토링하면서 시간을 보내고 있었습니다. 얼마전 if-else 블록의 중복으로인해 추상화하는 방법을 깨달아서 이 방법으로 추상화를 진행했습니다. 그 결과 이렇게 코드를 줄일 수 있었죠. 이랬던 코드들이 이렇게 바뀌었습니다. https://coding-review.tistory.com/487 다형성을 이용해 if else 블럭 추상화하기취준때 개발했던 온라인쇼핑몰 프로젝트는 약 2년전에 개발한만큼 돌아가게만 만든 경향이 있는 코드들입니다. 읽기 힘든 코드는 물론이고 확장성을 고려하지않은 구조가 많았습니다. 제 프로coding-review.tistory.com 리팩토링 방법은 위의 링크와 같은 방식으로 처리했습니다. 리팩토링으로 SRP와 OCP를 동시에 지킬 수 있게 되었..
취준때 개발했던 온라인쇼핑몰 프로젝트는 약 2년전에 개발한만큼 돌아가게만 만든 경향이 있는 코드들입니다. 읽기 힘든 코드는 물론이고 확장성을 고려하지않은 구조가 많았습니다. 제 프로젝트에서 문제가 된 부분을 단순화해서 보여드리고 어떻게 리팩토링 하였는지 포스팅해보려고합니다. if else 블럭을 추상화? 한번 이런 상황을 가정해보도록 하겠습니다. 우리 프로젝트는 관리자 (ADMIN), 매니저 (MANAGER), 일반회원 (MEMBER)에 따라 할인이나 결제에 대한 정책이 다르게 설정되어있습니다. 때문에, 할인정책에서도 관리자, 매니저, 일반회원인지를 확인하고 정책을 적용해야하고 결제정책 또한 마찬가지입니다. 그 결과 제 코드는 이런 방식으로 짜게되었습니다. @Service public class Paym..
이번에 눈에 들어온 그지같은 코드는 바로 이중 for문입니다. 우선 리팩토링 전 코드부터 보시죠. package com.hello.capston.service; import com.hello.capston.entity.*; import com.hello.capston.repository.ItemDetailRepository; import com.hello.capston.repository.OrderItemRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.TransactionException; import org.springframework.security.core.p..
요즘 공부할게 딱히 없을 때 포트폴리오로 작성했던 사이드프로젝트 온라인 쇼핑몰의 고도화를 진행하고 있습니다. 고도화라고 해봐야 별게 없지만... 버전을 4버전까지 업그레이드 하면서 대부분 성능개선 혹은 인프라적인 개선이 이루어졌습니다. 블로그 카테고리 "사이드 프로젝트" 부분을 참고해주세요! 하지만 코드는 2년전에 작성한 그대로 유지하고 있어서 굉장히 비효율적인 코드라던가 확장에 유연하지 않다던가하는 문제가 있었습니다. 이번 리팩토링은 세션 관리를 Authentication 객체를 이용해서 관리하도록 변경하였습니다. 기존 코드를 먼저 보시죠! if (loginId == null)) { User findUser = cacheRepository.findUserAtCache(username); Comment ..
우리는 앞서 private subnet에 접근하는데 성공했습니다. 이제 여기에 도커와 MySQL을 설치하고 외부 연결 서비스인 DBeaver에 연결해보도록 하겠습니다. 이전 포스팅과 이어지는 포스팅입니다. https://coding-review.tistory.com/454 데이터베이스 서버와 애플리케이션 서버를 분리해보자 : 실전3 (EC2 연결) 앞선 포스팅에서 우리는 EC2 인스턴스를 생성했습니다. 이제 우리는 EC2 인스턴스에 접속해보도록 하겠습니다. 이전 포스팅과 연결되는 포스팅입니다. https://coding-review.tistory.com/453 데이터베이스 coding-review.tistory.com 도커로 MySQL 띄우기 우선 도커와 도커 컴포즈를 다운받습니다. $ sudo apt-..