애플리케이션 한도 개발

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

문서화

우선, 정보를 수집하고 다양한 GitLab 계층에 설정된 서로 다른 한도가 무엇인지 결정해야 합니다. 다른 사람들과 협력하여 문서화하고 이러한 한도를 전달하세요.

애플리케이션 한도를 소개하는 방법에 대한 가이드가 있습니다.

계획 한도 구현

데이터베이스 계획 한도 삽입

plan_limits 테이블에 새 열을 만들고 한도 값을 삽입합니다.

두 개의 개별 마이그레이션 스크립트 파일을 만드는 것이 권장됩니다.

  1. 원하는 한도를 나타내는 기본 값이 비어 있지 않은 새 열을 plan_limits 테이블에 추가합니다. 예:

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

    계획 한도 항목이 0으로 설정되면 한도가 활성화되지 않은 것입니다. 이 설정은 특별하고 문서화된 상황에서만 사용해야 합니다.

  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에만 존재합니다. 존재하지 않는 계획에 대해서는 아무 동작도 수행하지 않습니다.

    마이그레이션에서 GitLab.com에만 한도를 설정하고 다른 인스턴스는 기본 한도를 사용하도록 허용하려면 #up#down 메서드의 시작 부분에 return unless Gitlab.com?를 추가하여 다른 인스턴스의 경우 마이그레이션이 아무 동작도 수행하지 않도록 합니다.

요금제 한도 검증

현재 한도 가져오기

프로젝트나 네임스페이스를 통해 현재 한도에 접근할 수 있습니다, 예를 들어:

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 관심사

Limitable 관심사를 사용하여 모델이 한도를 초과하지 않도록 검증할 수 있습니다.

현재 모델에 대한 레코드 수가 정의된 한도를 초과하지 않도록 보장합니다.

검증되는 객체의 한도 범위와 한도 이름을 지정해야 합니다.

한도 이름이 복수형 모델 이름과 다를 경우에만 설정합니다.

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 플랜을 사용합니다, 인스턴스 범위 기능에는 라이센스가 할당되지 않기 때문입니다.

class InstanceVariable
  include Limitable

  self.limit_name = 'instance_variables' # 선택 사항. InstanceVariable는 instance_variables에 해당합니다.
  self.limit_scope = Limitable::GLOBAL_SCOPE
end

구독 요금제

Self-managed:

  • default: 모든 사용자.

GitLab.com:

  • default: 모든 시스템 범위 기능.
  • free: Free 구독이 있는 네임스페이스와 프로젝트.
  • bronze: Bronze 구독이 있는 네임스페이스와 프로젝트. 이 티어는 더 이상 구매할 수 없습니다.
  • silver: Premium 구독이 있는 네임스페이스와 프로젝트.
  • premium: Premium 구독이 있는 네임스페이스와 프로젝트.
  • premium_trial: Premium Trial 구독이 있는 네임스페이스와 프로젝트.
  • gold: Ultimate 구독이 있는 네임스페이스와 프로젝트.
  • ultimate: Ultimate 구독이 있는 네임스페이스와 프로젝트.
  • ultimate_trial: Ultimate Trial 구독이 있는 네임스페이스와 프로젝트.
  • ultimate_trial_paid_customer: Ultimate를 30일 동안 체험 중인 Premium 구독이 있는 네임스페이스와 프로젝트.
  • opensource: GitLab 오픈 소스 프로그램의 구성원인 네임스페이스와 프로젝트.

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

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

Rack::Attack을 사용한 속도 제한 구현

우리는 Rack::Attack 미들웨어를 사용하여 Rack 요청을 제한합니다.

이는 Rails 컨트롤러, Grape 엔드포인트 및 기타 모든 Rack 요청에 적용됩니다.

새로운 스로틀을 추가하는 과정은 대략적으로 다음과 같습니다:

  1. rate_limits JSONB 열에 새로운 필드를 추가합니다.

  2. rate_limits 열에 대한 JSON 스키마 검증기를 업데이트합니다.

  3. 새로운 속도 제한을 구성하기 위해 Gitlab::RackAttackGitlab::RackAttack::Request를 확장합니다.

원하는 요청에 적용합니다.

  1. app/views/admin/application_settings/_ip_limits.html.hamlAdmin 영역 양식에 새로운 설정을 추가합니다.

  2. 사용자 및 IP 속도 제한응용 프로그램 설정 API에 새로운 설정을 문서화합니다.

  3. GitLab.com의 속도 제한을 구성하고 GitLab.com 특정 속도 제한에 문서화합니다.

구현 세부정보는 다음의 과거 이슈를 참조하세요:

Gitlab::ApplicationRateLimiter를 사용하여 속도 제한 구현

이 모듈은 특정 작업을 제한하는 데 사용할 수 있는 맞춤형 속도 제한기를 구현합니다.

Rack::AttackRack::Throttle와 달리 미들웨어 수준에서 작동하는 이 모듈은 컨트롤러 또는 API 수준에서 사용할 수 있습니다.

컨트롤러에서 사용할 CheckRateLimit 관심사를 참조하세요. 코드의 다른 부분에서는 Gitlab::ApplicationRateLimiter 모듈을 직접 호출할 수 있습니다.

다음 속도 제한 아키텍처

2022년 5월, 우리는 미래 지향적인 속도 제한 아키텍처를 사용하여 애플리케이션 제한 프레임워크의 다음 반복 버전을 작업하기 시작했습니다.

우리는 새로운 요구 사항을 정의하고 다음 아키텍처를 설계하는 작업을 하고 있으므로, 새로운 제한을 추가하기 위한 새로운 기능이 필요하다면 지금 당장 구축하는 대신 속도 제한 아키텍처 워킹 그룹에 기여해 주시기 바랍니다.

다음 속도 제한 아키텍처에서 구축하고자 하는 기능의 예:

  1. 네임스페이스 / 플랜별로 제한을 정의하고 재정의할 수 있게 하기.

  2. 구현된 제한과 기본값에 대한 문서를 자동으로 생성하기.

  3. 찾아보고 탐색할 수 있는 단일 위치에 제한 정의하기.

  4. 사용자에게 제한에 근접할 때 알림을 지원하는 부드러운 제한 및 강력한 제한.