안녕하세요 이번글은 Home-Delivery프로젝트에서 주문을 하는과정 중 반복적인 읽기 요청을 하는 부분에 대해서 캐시를 적용하여 성능을 향상시킨 과정을 적었습니다. 문제상황 주문까지의 유저들의 사용과정을 예상한다면 앱에접속 -> 카테고리 선택 -> 매장리스트 조회 -> 매장 상세조회 메뉴,메뉴그룹 조회 -> 메뉴옵션 조회 -> 장바구니담기 -> 주문의 과정이 이루어집니다. 이와같은 작업들은 주문하기전까지 한번에 이루어지는경우도있지만, 여러사이클이 반복될거라 생각됩니다. 동일한 데이터에 대한 반복적인 DB 요청이 발생합니다. DB요청이 많으면 발생하는 문제는 DB접근은 커넥션 뿐만 아니라 DB자체에서의 연산도 느리니 DB요청을 적게하면 좋습니다. 요구사항 - 매장목록, 메뉴목록, 메뉴그룹목록, 메뉴옵션..
이번글은 저희의 home-delivery서비스는 유저 주문이 수락할경우, 주문취소, 라이더가 배달완료, 라이더가 음식픽업 시 알림이 가도록하기위한 알림 서비스를 구현하면서 경험을 작성하였습니다. FCM이란? Firebase 클라우드 메시징(FCM)은 메시지를 안정적으로 무료 전송할 수 있는 크로스 플랫폼 메시징 솔루션(교차 플랫폼)입니다. FCM의 주요 기능으로는 알림 메시지 또는 데이터 메시지 전송, 다양한 메시지 타겟팅, 클라이언트 앱에서 메시지 전송 이있습니다. 이 중 저희가 필요한 부분은 알림 메시지였습니다. FCM의 장점 1) FCM은 교차 플랫폼 메시지 솔루션이기 때문에 FCM을 이용해서 개발을 진행하면, 플랫폼에 종속되지 않고 Push 메시지를 전송할 수 있습니다. -> Web, Androi..
안녕하세요 이번글은 프로젝트 Unit 테스트코드와 Integration 테스트코드 작성시 발생했던 문제에대해서 작성하였습니다. 문제상황 팀원분이 했던 코드를 PULL를 받고 테스트를 돌리던중 발생했던문제가있습니다. - 팀원분의 Redis포트번호가 저와 다르기때문에 발생했습니다. - Redis는 테스트 코드 실행 후 롤백이 불가능하므로 깨지는 테스트가 존재했습니다. 생각한 방법 방법1. Docker컨테이너를 테스트코드를 실행하고 나서 Redis 컨테이너 삭제하자. 왜냐하면 레디스는 롤백이없기때문에 테스트를 종료시키는게 좋다고생각했습니다. 그런데 이 방법은 개발자가 직접 매번 작동해야한다면 이것은 매우 불편한 일입니다. 즉 향후 CI / CD도입을 하는데 도입의 목적은 자동화를 도입시켜 생산성을 향상시키는데..
안녕하세요 이번 주제는 배달 음식을 시킬때 장바구니를 구현을 하면서 겪었던 문제점 입니다. 저희는 배달의 민족 클론코딩이기때문에 아래 사진과 비슷하게 장바구니 UI를 생각했습니다. 지희가 원하는 서비스는 - 장바구니에 같은 매장 음식들만 담을 수 있다. - 같은 메뉴이지만 메뉴옵션이 다르면 다른 메뉴로 장바구니에 담아진다. - 수량은 한번씩만 변경할 수 있다. - 메뉴에서 같은 (메뉴+옵션)을 선택한다면 수량이 증가한다 위와같은 로직을 구현해야했습니다. 저는 레디스 저장소를 사용했습니다. 인메모리저장소를 사용한이유는? 왜냐하면 장바구니 특성상 유저들이 대부분 장바구니에는 담았다 지웠다 많이 조회가 많이 일어나기도 해서 db에 매번 I/O를 것보다 속도가 더 빠르다고 생각하기도 하였고, 추가적으로 장바구니..
이번주차에는 메뉴옵션과 장바구니 기능위해 코딩했던 한주였습니다 메뉴옵션은 메뉴와 비슷하기때문에 큰 어려움은 없었습니다. 그러나 장바구니 기능은 생각할게 많아서 복잡했습니다. 장바구니를 만들면서 고민해야할것은 생각보다 많았던것 같았습니다. 첫번째로 레디스를 사용하기위한 설정부터 시작해서 저장소를 분리해야하나 말아야하나 등 여러가지가 많았습니다. 자세한 내용은 장바구니를 구현한 회고보다 장바구니에 관해 제가 글을 따로 적겠습니다. 1. 이번주의 더 고민점은 rest ful한지 여부인것같습니다. rest ful하게 url을 짜는것이 이번프로젝트의 저의 목표중하나입니다. 그런데 문제점이 이제 로직들이 더 생기는데 GET : /menus 하면 메뉴들을 보여주는것인데 여기서 어떤매장의 메뉴인지 여부였습니다. 그래서..
안녕하세요 이번글은 제가 메뉴리스트를 우선순위별로 불러오면서 겪었던 문제입니다. 메뉴그룹과 메뉴를 불러와야하기때문에 저는 아래 코드와같이 1. 먼저 storeId가 존재하는지 확인하고 2. 매장의 메뉴그룹리스트를 불러옵니다. 3. 메뉴그룹리스트의 메뉴그룹의 아이디를 통해서 menuMapper를 통해 각 메뉴리스트들을 가져옵니다. MenuListResponseDto에는 ( id, List) 를 속성으로 가집니다. 쿼리에서 정렬을 수행해주기때문에 저는 이상이없다고 생각했습니다. 그런데 문제점이있습니다. 위의 코드와 같이 한다면 steam을 돌면서 매장의 메뉴그룹마다 db를 호출해야하기때문에 수가 많아진다면 n번 만큼 호출하게 됩니다. 그래서 다음 작업은 db호출을 줄이고 Map 자료구조를 이용하는방법입니다...
이번주는 메뉴를 만드는 작업을했습니다. 음 가장 고민했던것은 우선순위변경로직이였습니다. 배민에서 화면을 볼때 메뉴 그룹과 메뉴들이 우선순위가 존재합니다. 예를들어 세트메뉴, 단품, 사이드 메뉴와 같이 메뉴그룹이 존재하는데 이 우선순위를 변경할때 작업을 진행했습니다. 첫번째로 우선순위를 변경할때 하나만 변경되면 나머지도 함께 변경하고자했습니다. 그래서 자료구조를 통해 순서대로 넣어서 변경할려고했습니다. 그런데 이 로직에는 문제점이 많았습니다. 바로 하나만변경되는데 나머지들도 바꿔줘야하기때문에 뒤로밀려난다면 하나하나 꺼내서 바꿔주는것도 생각해야하고 로직상으로 많이 복잡했습니다. 그래서 만약 프론트가 데이터를 화면에보이는대로 위에서 아래로 우선순위를 받는다면 한꺼번에 업데이트를 하고자 하는걸로 변경했습니다. ..
이번 글은 성능을 향상시키기 위해서 캐시를 사용할려는데 캐시사용에도 여러 전략이 존재합니다. 그래서 여러전략들을 정리하도록하겠습니다. 캐싱전략이란? 캐싱(Caching)은 애플리케이션의 처리 속도를 높여준다. 이미 가져온 데이터나 계산된 결과값의 복사본을 저장함으로써 처리 속도를 향상시키며, 이를 통해 향후 요청을 더 빠르게 처리할 수 있습니다 로컬 캐싱 vs 글로벌 캐싱 로컬 캐싱은 서버 내부 저장소에 캐시 데이터를 저장하는 것이다. 만약 scacle out을 한다면 데이터가 공유가 안되므로 서버마다 캐시 데이터가 다를수있습니다 그런데 서버내에서 작동하기 때문에 속도가 빠릅니다. 예를 들어, 사용자가 같은 리소스에 대한 요청을 반복해서 보내더라도 A 서버에서는 이전 데이터를, B 서버에서는 최신 데이터..
이번글은 저희가 대용량을 생각하면서 개발을 하자는 목적으로 Delivery프로젝트를 진행했습니다. 저희는 세션을 통한 로그인을 하는데 지금은 애플리케이션이 한개이지만 대용량 처리를 위해 scale-out을 통해서 여러개의 애플리케이션이 존재한다면 발생되는 문제점인 세션 정합성 문제를 해결하기 위한 세션 관리 전략에 대해 알아보겠습니다 정합성이란? 데이터 정합성 : 어떤 데이터들이 값이 서로 일치함. 왜 세션 정합성이 안맞는 문제가 발생할가? 아래와 같이 3대로 scale-out을 진행한다면 유저가 요청마다 Nginx가 요청을 분배해주는데 동일한곳으로 계속 연결을 시켜준다면 이상이없겠지만 요청마다 다른곳으로 요청을 분산시켜준다면 로그인을 했는데 또해야하는 문제가 발생하게될것입니다. 그래서 이러한 문제를 해..