Skip to content

[ISSUE] 유저의 게시물 조회시 조회수 처리방안 #49

@ekgns33

Description

@ekgns33

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을 줄이고자 했습니다.

전체적인 로직은 다음과 같습니다.

  1. 임의의 유저가 특정 게시물을 조회합니다.

  2. PostService를 통해 해당 게시물 데이터베이스 조회 및 반환.

  3. 레디스에 유저 정보 - 조회한게시물id가 존재하는 지 확인.

  • 존재하면, 조회수 증가없이 게시물 데이터 반환

  • 존재하지 않으면, 조회수 1 증가 및 레디스에 유저-게시물 정보 저장.

  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

No type

Projects

Status

🆕 To Do

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions