어플리케이션은 개발을 제한합니다

이 문서는 GitLab에 어플리케이션 제한을 추가하기 위한 개발 가이드를 제공합니다.

문서화

우선적으로 여러분은 다른 GitLab 티어에 대해 설정된 다양한 제한을 모아 정보를 수집하고 결정해야 합니다. 문서화를 진행하고 그 제한사항을 다른 사람들과 소통하세요.

어플리케이션 제한을 도입하는 방법에 대한 가이드가 있습니다.

계획 제한 구현

데이터베이스 계획 제한 추가

plan_limits 테이블에 새 열을 만들고 제한값을 입력하세요. 두 개의 별도 이관 스크립트 파일을 만드는 것이 좋습니다.

  1. 원하는 제한을 나타내는 기본값이 있는 새 열을 plan_limits 테이블에 추가하세요.

    add_column(:plan_limits, :project_hooks, :integer, default: 100, null: false)
    

    0으로 설정된 Plan limits 항목은 제한이 활성화되지 않음을 의미합니다. 이 설정은 특별하고 문서화된 상황에서만 사용해야 합니다.

  2. (선택사항) create_or_update_plan_limit 마이그레이션 도우미를 사용하여 각 수준을 튜닝하는 데이터베이스 마이그레이션을 만드세요. 이 마이그레이션에서의 계획은 GitLab.com의 계획과 일치해야 합니다. 계획이 빠지면 해당 계획의 고객들은 기본 제한을 받게 되는데, 이는 0(무제한)일 수 있습니다.

    예를 들어,

    class InsertProjectHooksPlanLimits < Gitlab::Database::Migration[2.1]
      def up
        create_or_update_plan_limit('project_hooks', 'default', 0)
        create_or_update_plan_limit('project_hooks', 'free', 10)
        create_or_update_plan_limit('project_hooks', 'bronze', 20)
        create_or_update_plan_limit('project_hooks', 'silver', 30)
        create_or_update_plan_limit('project_hooks', 'premium', 30)
        create_or_update_plan_limit('project_hooks', 'premium_trial', 30)
        create_or_update_plan_limit('project_hooks', 'gold', 100)
        create_or_update_plan_limit('project_hooks', 'ultimate', 100)
        create_or_update_plan_limit('project_hooks', 'ultimate_trial', 100)
        create_or_update_plan_limit('project_hooks', 'ultimate_trial_paid_customer', 100)
        create_or_update_plan_limit('project_hooks', 'opensource', 100)
      end
    
      def down
        create_or_update_plan_limit('project_hooks', 'default', 0)
        create_or_update_plan_limit('project_hooks', 'free', 0)
        create_or_update_plan_limit('project_hooks', 'bronze', 0)
        create_or_update_plan_limit('project_hooks', 'silver', 0)
        create_or_update_plan_limit('project_hooks', 'premium', 0)
        create_or_update_plan_limit('project_hooks', 'premium_trial', 0)
        create_or_update_plan_limit('project_hooks', 'gold', 0)
        create_or_update_plan_limit('project_hooks', 'ultimate', 0)
        create_or_update_plan_limit('project_hooks', 'ultimate_trial', 0)
        create_or_update_plan_limit('project_hooks', 'ultimate_trial_paid_customer', 0)
        create_or_update_plan_limit('project_hooks', 'opensource', 0)
      end
    end
    

    GitLab.com에서만 존재하는 일부 계획이 있습니다. 이는 해당 계획이 존재하지 않는 경우 no-op입니다.

    여러분의 마이그레이션에서 GitLab.com에서만 제한을 설정하고 다른 인스턴스들이 기본 제한을 사용하도록 하려면 각 #up#down 메소드의 시작에 return unless Gitlab.com?을 추가하여 그 마이그레이션을 다른 인스턴스에 대해 no-op으로 만드세요.

계획 제한 유효성 검사

현재 제한 가져오기

프로젝트나 네임스페이스를 통해 현재 제한에 접근할 수 있습니다.

project.actual_limits.project_hooks

현재 제한 확인

현재 제한이 초과되었는지 확인하기 위한 PlanLimits#exceeded? 메소드가 있습니다. ActiveRecord 개체 또는 Integer를 사용할 수 있습니다.

레코드 수가 정의된 제한을 초과하지 않도록 합니다.

project.actual_limits.exceeded?(:project_hooks, ProjectHook.where(project: project))

숫자가 정의된 제한을 초과하지 않도록 합니다.

project.actual_limits.exceeded?(:project_hooks, 10)

Limitable concern

Limitable concern은 모델이 제한을 초과하지 않도록 검증하는 데 사용될 수 있습니다. 현재 모델의 레코드 수가 정의된 제한을 초과하지 않도록 보장합니다.

검증되는 객체의 제한 범위와 복수화된 모델 이름과 다른 경우 그 제한 이름을 지정해야 합니다.

class ProjectHook
  include Limitable

  self.limit_name = 'project_hooks' # ProjectHook이 project_hooks와 일치하는 경우 선택사항
  self.limit_scope = :project
end

모델을 테스트하려면 공유 예제를 포함시킬 수 있습니다.

it_behaves_like 'includes Limitable concern' do
  subject { build(:project_hook, project: create(:project)) }
end

인스턴스 전체 제한 테스트

인스턴스 전체 기능은 라이선스가 할당되지 않으므로 항상 default Plan을 사용합니다.

class InstanceVariable
  include Limitable

  self.limit_name = 'instance_variables' # InstanceVariable이 instance_variables와 일치하는 경우 선택사항
  self.limit_scope = Limitable::GLOBAL_SCOPE
end

구독 플랜

자체 관리:

  • default: 누구나.

GitLab.com:

  • default: 시스템 전체 기능.
  • free: 무료 구독을 한 네임스페이스 및 프로젝트.
  • bronze: Bronze 구독을 한 네임스페이스 및 프로젝트. 이 티어는 더 이상 구매할 수 없습니다.
  • silver: 프리미엄 구독을 한 네임스페이스 및 프로젝트.
  • premium: 프리미엄 구독을 한 네임스페이스 및 프로젝트.
  • premium_trial: 프리미엄 체험 구독을 한 네임스페이스 및 프로젝트.
  • gold: 얼티밋 구독을 한 네임스페이스 및 프로젝트.
  • ultimate: 얼티밋 구독을 한 네임스페이스 및 프로젝트.
  • ultimate_trial: 얼티밋 체험 구독을 한 네임스페이스 및 프로젝트.
  • ultimate_trial_paid_customer: 프리미엄 구독을 한 고객이 30일 동안 얼티밋을 체험하는 경우.
  • opensource: GitLab 오픈 소스 프로그램의 구성원인 네임스페이스 및 프로젝트.

GitLab.com에는 구독이 없는 early_adopter 플랜이 있습니다.

test 환경에는 어떤 플랜도 없습니다.

Rack::Attack을 사용하여 요율 제한 구현

우리는 Rack::Attack 미들웨어를 사용하여 Rack 요청을 조절합니다. 이는 Rails 컨트롤러, Grape 엔드포인트 및 기타 모든 Rack 요청에 적용됩니다.

새로운 쓰로틀을 추가하는 과정은 다음과 같이 대략적으로 진행됩니다.

  1. ApplicationSetting 모델의 rate_limits JSONB column에 새로운 필드를 추가합니다.
  2. rate_limits column에 대한 JSON 스키마 검증기를 업데이트합니다.
  3. 새로운 요율 제한을 구성하고 원하는 요청에 적용하기 위해 Gitlab::RackAttackGitlab::RackAttack::Request를 확장합니다.
  4. app/views/admin/application_settings/_ip_limits.html.hamlAdmin 영역 양식에 새로운 설정을 추가합니다.
  5. User and IP rate limitsApplication settings API에서 새로운 설정을 문서화합니다.
  6. GitLab.com의 요율 제한을 구성하고 GitLab.com-specific rate limits에서 이를 문서화합니다.

구현 세부 정보는 다음 이슈들을 참고하세요.

Gitlab::ApplicationRateLimiter를 사용하여 요율 제한 구현

본 모듈은 특정 작업을 조절할 수 있는 사용자 정의 요율 제한기를 구현합니다. Rack:AttackRack::Throttle과 달리, 미들웨어 수준에서 작동하는 것이 아니라, 컨트롤러 또는 API 수준에서 사용할 수 있습니다.

컨트롤러에서 사용하는 경우 CheckRateLimit concern을 참조하십시오. 코드의 다른 부분에서는 Gitlab::ApplicationRateLimiter 모듈을 직접 호출할 수 있습니다.

다음 요율 제한 아키텍처

2022년 5월에 우리는 전반적인 요율 제한 아키텍처를 전망하여 새로운 버전의 응용프로그램 제한 프레임워크에 대한 작업을 시작했습니다.

우리는 새로운 요구 사항을 정의하고 다음 아키텍처를 설계하고 있으니, 새로운 기능을 추가해야 하는 경우 현재 구축하는 대신 Rate Limiting Architecture Working Group에 기여하는 것을 고려하십시오.

다음 반복의 요율 제한 아키텍처에 어떤 기능을 구축하고 싶은지에 대한 예시:

  1. 네임스페이스/플랜 당 제한을 정의하고 재정의할 수 있는 기능 구현.
  2. 구현된 제한에 대한 자동 문서화 및 기본값 확인 기능.
  3. 찾기 및 탐색할 수 있는 하나의 위치에 제한 정의.
  4. 접근 제한이 근접할 때 사용자에게 알림을 지원하는 소프트 및 하드 제한.