Branch
DEV-72
Description
유저의 게시물 조회시 게시물의 조회수 증가 처리방안
- Post 서비스를 이용하면서 특정 게시물의 details를 접근하면 게시물의 조회수가 1씩 올라가야합니다.
- 이를 HTTP: GET 요청으로 게시물정보를 서버로부터 전달 받으면 서버는 Post Database에 update연산을 실시하여
특정 게시물의 조회수를 1씩 증가시킵니다.
Problem
-
유저가 게시물을 선택하여 상세정보를 조회할 때 마다 게시물의 조회수를 1씩 증가시킨다면, 유저가 조회수를 위하여
새로고침을 계속 하는등 여러 방법으로 조회수를 조작할 수 있습니다.
-
동일한 유저가 단 기간내에 여러번의 요청을 보내는 것으로 DB에 계속 update 연산이 가해지면 부하가 커질 가능성이 있습니다.
Solution
-
유저의 고유 정보와 유저가 조회한 게시물 간의 데이터를 특정 저장소에 저장하여 update 연산이 계속 이루어지지 않도록 합니다.
-
유저의 고유정보와 유저가 조회한 게시물간의 데이터는 키-벨류 형태로 저장합니다.
-
유저가 특정 게시물을 조회한 시간을 기준으로 일정시간 내에 다시 조회를 하면 조회수가 증가되지 않습니다.
-
유저 - 게시물 정보는 1일의 유효기간을 갖습니다.
-
유저 - 게시물 정보는 redis에 저장됩니다.
-
조회수 증가를 검증하는 과정은 유저가 게시물을 조회할 때마다 발생하므로 유저-게시물 정보를 매 요청마다 확인해야합니다.
이는 서비스 흐름에서 매우 빈번하게 일어나는 이벤트입니다. 따라서 RDBMS와 noSql에 비해 비용, 조회시간이 적은 in-memory 캐시 저장소를 이용해 expense와 throughput을 줄이고자 했습니다.
전체적인 로직은 다음과 같습니다.
-
임의의 유저가 특정 게시물을 조회합니다.
-
PostService를 통해 해당 게시물 데이터베이스 조회 및 반환.
-
레디스에 유저 정보 - 조회한게시물id가 존재하는 지 확인.
-
존재하면, 조회수 증가없이 게시물 데이터 반환
-
존재하지 않으면, 조회수 1 증가 및 레디스에 유저-게시물 정보 저장.
- 유효시간(1일)이 지나면 레디스는 해당 유저-게시물 데이터를 삭제
Process
게시글 조회
레디스에 유저 정보 조회
레디스에 유저-포스트 정보 삽입
게시글 조회수 증가
Additional context
Branch
DEV-72Description
유저의 게시물 조회시 게시물의 조회수 증가 처리방안
특정 게시물의 조회수를 1씩 증가시킵니다.
Problem
유저가 게시물을 선택하여 상세정보를 조회할 때 마다 게시물의 조회수를 1씩 증가시킨다면, 유저가 조회수를 위하여
새로고침을 계속 하는등 여러 방법으로 조회수를 조작할 수 있습니다.
동일한 유저가 단 기간내에 여러번의 요청을 보내는 것으로 DB에 계속 update 연산이 가해지면 부하가 커질 가능성이 있습니다.
Solution
유저의 고유 정보와 유저가 조회한 게시물 간의 데이터를 특정 저장소에 저장하여 update 연산이 계속 이루어지지 않도록 합니다.
유저의 고유정보와 유저가 조회한 게시물간의 데이터는 키-벨류 형태로 저장합니다.
유저가 특정 게시물을 조회한 시간을 기준으로 일정시간 내에 다시 조회를 하면 조회수가 증가되지 않습니다.
유저 - 게시물 정보는 1일의 유효기간을 갖습니다.
유저 - 게시물 정보는 redis에 저장됩니다.
조회수 증가를 검증하는 과정은 유저가 게시물을 조회할 때마다 발생하므로 유저-게시물 정보를 매 요청마다 확인해야합니다.
이는 서비스 흐름에서 매우 빈번하게 일어나는 이벤트입니다. 따라서 RDBMS와 noSql에 비해 비용, 조회시간이 적은 in-memory 캐시 저장소를 이용해 expense와 throughput을 줄이고자 했습니다.
전체적인 로직은 다음과 같습니다.
임의의 유저가 특정 게시물을 조회합니다.
PostService를 통해 해당 게시물 데이터베이스 조회 및 반환.
레디스에 유저 정보 - 조회한게시물id가 존재하는 지 확인.
존재하면, 조회수 증가없이 게시물 데이터 반환
존재하지 않으면, 조회수 1 증가 및 레디스에 유저-게시물 정보 저장.
Process
게시글 조회
레디스에 유저 정보 조회
레디스에 유저가 현재 포스트를 알람한 이력이 있는 지 확인한다.
레디스에 유저-포스트 정보 삽입
postController.getTargetPost() 메소드에서 사용자의 IP 주소를 req.headers['x-forwarded-for'] || req.connection.remoteAddress 을 통해 얻는다.
유저 IP주소를 DTO에 담아 서비스 단으로 넘겨준다.
레디스에 들어갈 유저-게시물 정보의 key를 만들고 value는 '' 빈 문자열을 넣어준다.
key의 구조는 이와 같다 : [postId]&[remoteIP]
- 예시 : examplePostId&192.0.0.1
레디스에 유저정보를 조회하고 존재하지 않으면 redisKey-value 데이터를 넣는다.
redis.redisClient.set() 메소드를 통해 레디스에 정보를 삽입한다. 이때 유효시간은 24시간이다.
게시글 조회수 증가
아니라면 Post.updateViewCnt() 메소드를 통해 게시글의 조회수를 증가시키고 조회수가 증가된 게시물을 반환한다.
Additional context