[Redis] redis로 동시접속자 표기하기

김지원·2022년 5월 21일
0

redis

목록 보기
1/3
post-thumbnail

🤸‍♂️ Init

가끔 앱이나 웹을 보다보면 N명이 이 화면을 보고 있습니다! 라는 문구가 있는 것을 볼 수 있다.

필자도 간단하게 이 기능을 구현해볼까 한다.

🤔 생각해본 구현 방법

1. 첫 번째로 개발자의 기본인 구글 검색부터 시작해보았다.

서버를 띄우고 있는 Tomcat이나 Apache로 서버에 몇 명이 들어와 있는지 확인하는 방법이 가장 대중적으로 사용하고 있는 것 같았다. 하지만 필자는 서버의 전체 사람이 아닌 한 화면에 들어와있는 사용자를 카운팅하는 것이 목적이기 때문에 간단하게 넘어가기로 한다.

2. 두 번째로 생각해본 것은 웹소켓이었다.

사실상 웹소켓을 이용해 세션을 이어간다면 그게 진정한 동시접속자가 아닐까라는 생각에서 시작하였다.
하지만.. 이 조그만 기능때문에 양방향 통신을 이어준다? 이건 너무 큰 부하이다.. 정확하지만 효율성이 떨어진다
( 그리고 사용자가 많아보여야 좋지 않을까..? 읍읍)

3. 마지막 방법이 redis를 사용하는 방법이었다.

redis에는 SORTED SETS이라는 기능이 있다. 리스트와 개념은 비슷한데 야무진 놈이라 도입해보기로 했다.

📃 풀어 써보는 로직

  1. 화면에 들어갈 때 프런트에서 api를 쏴준다. (api의 파라미터에는 사용자를 판단할 수 있는 고유값과 어떤 화면인지 나타내는 값이 필요하다)
  2. 그 값들을 받아와 REDIS에 저장한다.
  3. 여기서 필자가 사용할 SORTED SETS는 KEY 하나에 여러 member, score가 저장된다.
  4. 보고 있는 사람 카운팅은 5분을 기준으로 하여 5분이 지난 사용자는 카운팅에서 제외하도록 한다.
  5. 3을 하기 위해 score에 timestamp를 저장한다.
  6. 카운팅할 때 SORTED SETS의 SCORE를 판단하여 3분이 지난 member와 score는 삭제한다.
  7. 삭제하고 나머지 값들로 카운팅하여 클라이언트에게 전달한다.

👨‍💻 구현해보기

  • redis관련 코드
import Redis = require('ioredis');

// 지금 시간부터 5분 전까지의 시간을 계산하여 count 조회
public static getListByScoreRedisData: Promise<number | null> (key: string, score: number) {
  const lastTime = score - 300000;
  // 미리 연결해둔 redis에 연결
  const redis = Redis.getRoRedis();
  return redis.zcount(key, lastTime, score);
}

// 5분이 지난 시간들은 삭제해준다.
public static removeListByScoreRedisData: Promise<void | number> (key: string, score: number) {
  const lastTime = score - 300000;
  // 미리 연결해둔 redis에 연결
  const redis = Redis.getRedis();
  return redis.zremrangebyscore(key, 0, lastTime);
}

// 유저가 들어오면 redis에 저장시켜준다.
public static setListRedisData: Promise<string | number> (key: string, score: number, member: string) {
  // 미리 연결해둔 redis에 연결
  const redis = Redis.getRedis();
  return redis.zadd(key, score, member);
}
  • 여기서 중요한 점은 score는 Date.now()을 이용하여 timestamp 형식으로 들어가게 해야된다는 점이다.

RESULT

{
	count: 5
}

다음에는 소켓을 이용해 보다 정확하게 사용자 수를 카운트하는 것을 공부해봐야겠다!

profile
backend-developer

0개의 댓글