-
Notifications
You must be signed in to change notification settings - Fork 2
Description
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
게시글 조회
- HTTP GET 요청을 받아 게시물 질의에 활용될 DTO에 매핑한다.
- postService의 getTargetPost() 메소드를 통해 게시물 조회
- 게시물이 존재하면 반환, 없다면 E404AF 에러코드 반환
레디스에 유저 정보 조회
- PostService.getTargetPost 의 redis.redisClient.exists(redisKey)를 통해
레디스에 유저가 현재 포스트를 알람한 이력이 있는 지 확인한다.
레디스에 유저-포스트 정보 삽입
-
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.js에 특정 게시물의 조회수를 1씩 증가시키는 updateViewCnt 메소드 추가.
- PostService.getTargetPost 의 isUserAlreadySeen을 통해 유저가 이미 게시물을 조회했는지 확인하고,
아니라면 Post.updateViewCnt() 메소드를 통해 게시글의 조회수를 증가시키고 조회수가 증가된 게시물을 반환한다.
Additional context
Metadata
Metadata
Assignees
Labels
Type
Projects
Status