Skip to content
himprover
GitHubVelog

[번역] 어디에서든 사용할 수 있는 추천, 좋아요, 리뷰 오픈소스 Clickvote 🔥

Translate8 min read

banner

이 게시물은 원본 아티클인 Clickvote: Open-source upvotes, likes, and reviews to any context 🔥 를 한글로 번역한 게시글입니다. 게시물 내용의 저작권은 원작자 Nevo David 에게 있습니다.

한줄요약

저는 어디에서든 추가 가능한 추천, 좋아요, 리뷰 오픈 소스 앱을 만들었습니다. 듣기에는 쉬워 보이지만, 저는 아키텍처를 구상하다가 머리가 깨지는 것 같았습니다. 좀 더 자세히 얘기해보겠습니다.

대체 뭘 만든 거에요? 🤯

지난 10년간, 저는 "리뷰", "추천", "좋아요" 기능을 여러 곳에서 개발해보는 경험을 가졌습니다. 또한 아래와 같은 다수의 영역에서도 이러한 기능을 보았습니다.

  • Reddit
  • Facebook
  • Instagram
  • Upwork
  • 음식 어플리케이션
  • 프로젝트 관리 도구
  • 고객 피드백 도구
  • 로드맵 도구
  • 등등등..

지금까지 알아본 바로는, 직접 구축하는 것은 꽤 간단한 작업이지만, 그렇지 않을 때도 있었습니다.

여러분은 여기에서 주의할 점이 있습니다.

  • 좋아요, 추천, 리뷰가 클라이언트 간에서 실시간으로 업데이트 되어 보여져야 합니다.
  • 심층 분석을 통해 회원들에 대해 알아갈 수 있습니다.
  • 초당 무한한 수의 클릭을 처리해야 합니다. (규모에 따라)
  • 이 모든것을 관리해야 합니다.

이건 꿈이야 😴

음 이건 말도 안되는 것은 아닙니다... 만약 5분 안에 이 기능을 즉시 추가할 수 있는 매우 간단한 컴포넌트를 제공할 수 있다면 어떨까요.

여기 코드의 일부분이 있습니다.

<ClickVoteProvider value={{ apiUrl, publicKey, userId }}>
<ClickVoteComponent id={voteId} voteTo={voteTo}>
{(props) => <LikeStyle {...props} />}
</ClickVoteComponent>
</ClickVoteProvider>

여러분은 사용자 아이디를 제공하여 ClickVoteProvider로 여러분의 어플리케이션을 감쌀 수 있습니다.

그리고 나서, 투표하고 싶은 동적 아이디 값과 함께 어플리케이션에 다양한 ClickVoteComponent를 분산시킬 수 있습니다.

만약 투표에 상호작용(LikeStyle) 하고 나면, 이는 업데이트되어 모든 다른 사용자들에게 새로운 값의 동일한 컴포넌트를 보게 합니다.

따라서 우리는 Novu에서 간단한 대시보드를 만들 수 있습니다.

5

그리고 1분이 지나면 이렇게 바뀝니다.

6

좋습니다. 이제 우리는 우리가 뭘 만들고자 하는지 전부 이해했습니다.

실제로 어떻게 보이는지 살펴보도록 하죠.


그래프! (내가 색칠했어요)

7

이는 단순한 좋아요에 비해 조금 복잡해 보입니다. 제가 한번 설명해보도록 하겠습니다.

분석 내용

다른 모든 시스템과 마찬가지로 대시보드가 존재합니다. 이는 NextJS(프론트엔드)와 NestJS(백엔드), 그리고 MongoDB를 사용해 만들어졌습니다.

  1. 모니터 하고 싶은 새로운 투표 타입을 추가합니다.
  2. 누가 클릭했는지, 몇 번 클릭했는지, 어느 날 클릭이 가장 많았는지, 어떤 영역이 가장 좋은 성과를 냈는지 등의 분석을 확인합니다.
  3. 고객이 상호 작용이 발생했을 때 알림을 받기 원하는 데이터 소스를 첨부할 수 있는 방법을 제공합니다.

사용자 어플리케이션

여기서부터 조금 복잡해질 수 있습니다.

  1. 모든 클라이언트가 새로운 좋아요 그리고 추천에 대해 즉시 업데이트 받기 위해 연결 할 수 있는 웹 소켓 서버를 만듭니다. (저는 SSE를 확인했지만, 이는 6개의 브라우저가 최대였고 저는 사용하지 않기로 하였습니다.)
  2. 웹소켓 서버는 클릭의 과부화를 처리하면서 투표 수를 조회하고 업데이트해야 합니다. 여기에서는 Redis를 사용했습니다. 이는 WATCH, MULTI 옵션을 제공해 트랜잭션을 추가하고 예상과 다른 횟수가 발생하는 레이스 컨디션을 예방해줍니다.
  3. 다음은 아파치 카프카(Kafka) 입니다. 만약 여러분이 초당 천만건 이상의 계획을 하고 있다면 이는 그저 데이터베이스에 넣는 것 만으로 불가능합니다. (고장날겁니다.) 또한 어떤 정보가 데이터베이스에 실패하지 않고 잘 들어갔는지 보장받고 싶을 것입니다. 저는 Kafka를 선택했습니다. 인기있기 때문이죠. 하지만 여러분은 아파치 펄서(Pulsar)를 사용할 수도 있습니다. 우리는 모든 것을 Kafka로 보냅니다.
  4. NestJS의 MicroService Group Consumers 는 Kafka의 주제(topics)를 수신대기하고 있다가 정보를 가져와서 데이터베이스에 추가합니다.
  5. 저는 시계열 데이터베이스로 Timescale을 선택했습니다. 이외에도 Clickhouse나 RedShift 같은 것을 사용할 수 있었지만, 저는 Timescale을 사용했습니다. 왜냐하면 이는 일부 플러그인을 포함한 Postgres이기 때문입니다. 이는 오픈 소스 커뮤니티가 시계열 데이터베이스 대신에 Postgres를 선택할 수 있다는 것을 의미합니다. (작은 규모일 경우)
  6. 다른 NestJS MicroService Group Consumer는 사용자 어플리케이션에 그들의 설정에 따라 정보를 제공합니다. (API, direct DB insert, Kafka)

이 구성의 호스팅에 얼만큼의 비용이 들었을까요? 🤣

  • Vercel Frontend (NextJS) $20
  • Timescale $31
  • Upstash for serverless Kafka / Redis ~$70
  • Digital Ocean Websockets server $25
  • Digital Ocean Backend $25
  • Digital Ocean 1 Worker (Consumer) $25
  • MongoDB Atlas $20

저는 최소 216$ 이상이라고 믿습니다.

당연히 docker-compose를 사용해 하나의 서버에 배치할 수 있지만, 오래 유지되지는 않을 것입니다.

나중에는 백엔드, 워커, 웹소켓을 Docker 컨테이너화 하고 쿠버네티스로 관리해 AWS의 어딘가에 배치하는 것이 좋을 것으로 생각됩니다.

행운을 빕니다! 🤞