Rails에서 다중 브랜드 관리: RobinReach의 멀티 테넌트 패턴
Source: Dev.to

도전 과제: 멀티‑브랜드 관리
플랫폼에서 사용자가 세 개의 서로 다른 회사를 관리한다고 상상해 보세요. 각 회사는:
- 자체 소셜 미디어 프로필
- 예약된 게시물
- 팀 멤버와 역할
- 분석 및 성과 데이터
적절한 격리가 없으면 테넌트 간 데이터 누수가 악몽이 됩니다. 멀티‑테넌시는 단순히 데이터베이스 패턴이 아니라 애플리케이션 모든 계층에 적용되는 사고방식입니다.
워크스페이스 기반 멀티‑테넌시
RobinReach에서는 각 브랜드 또는 워크스페이스를 테넌트로 모델링했습니다. Post, SocialProfile, Member와 같은 모든 핵심 모델은 테넌트에 스코프됩니다. 우리는 스레드‑안전한 Current 객체를 사용해 테넌트 컨텍스트를 보관합니다:
# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
attribute :company
end
이렇게 하면 모든 모델이 현재 테넌트를 쉽게 참조할 수 있습니다:
# app/models/post.rb
class Post < ApplicationRecord
belongs_to :company
default_scope { where(company_id: Current.company.id) }
end
이 패턴을 사용하면 모든 쿼리가 자동으로 테넌트 경계를 준수합니다.
원활한 워크스페이스 전환
사용자는 로그아웃 없이 워크스페이스를 전환하기를 기대합니다. 우리는 현재 워크스페이스를 세션에 저장합니다:
def switch_workspace(company_id)
session[:current_company_id] = company_id
Current.company = Company.find(company_id)
end
이제 게시물 보기, 콘텐츠 예약, 멤버 관리와 같은 모든 작업이 선택된 워크스페이스에 자동으로 스코프됩니다.
멀티‑테넌트 환경에서의 백그라운드 작업
멀티‑테넌시는 데이터베이스 쿼리뿐만 아니라 백그라운드 작업에서도 테넌트 경계를 지켜야 합니다.
배운 교훈
- 항상 테넌트 ID를 백그라운드 작업에 전달합니다.
- 작업을 멱등(idempotent)하게 만들어 테넌트 간 부작용을 방지합니다.
- Sidekiq 큐를 전략적으로 사용합니다; 트래픽이 많은 테넌트는 별도 큐가 필요할 수 있습니다.
워크스페이스 멀티‑테넌시를 위한 모범 사례
- 모델, 서비스, 작업, 컨트롤러 등 모든 계층에서 테넌트 격리를 강제합니다.
- 테넌트 정보를 위해 스레드‑안전 컨텍스트 객체(
Current)를 사용합니다. - 빠른 워크스페이스 전환을 위한 UI를 설계합니다.
- 백그라운드 작업은 멱등하고 테넌트를 인식하도록 유지합니다.
- 필요에 따라 테넌트별 캐시를 사용해 데이터베이스 부하를 줄입니다.
- 워크스페이스별 성능을 모니터링해 무거운 테넌트를 조기에 감지합니다.
결론
Rails에서 멀티‑브랜드 SaaS를 구축하는 것은 단순한 기술적 과제가 아니라 설계 사고방식입니다. RobinReach는 신중한 스코핑, 백그라운드 작업 설계, 워크스페이스 격리를 통해 원활한 멀티‑테넌트 경험을 제공할 수 있음을 보여줍니다.
SaaS 플랫폼을 만드는 Rails 개발자라면, 이 패턴들을 적용해 미래의 골칫거리를 예방하고 앱을 확장 가능한 상태로 만들 수 있습니다.