애플리케이션 제한 개발
GitLab v19.1이 문서는 GitLab에 애플리케이션 제한을 추가하려는 기여자를 위한 개발 가이드입니다. 우선, 정보를 수집하고 다양한 GitLab 티어에 설정된 여러 제한 사항을 결정해야 합니다. 애플리케이션 제한 도입에 관한 가이드가 있습니다.
이 문서는 GitLab에 애플리케이션 제한을 추가하려는 기여자를 위한 개발 가이드입니다.
문서화#
우선, 정보를 수집하고 다양한 GitLab 티어에 설정된 여러 제한 사항을 결정해야 합니다. 다른 기여자들과 협력하여 해당 제한 사항을 문서화하고 공유하세요.
애플리케이션 제한 도입에 관한 가이드가 있습니다.
플랜 제한 구현#
plan_limits 테이블은 **셀 범위 구성(cell-scoped configuration)**입니다. 각 셀은 자체 테이블 사본을 가지며,
제한 사항은 셀 간에 마이그레이션되지 않습니다. 새로운 셀은 각 제한에 대한 칼럼 기본값으로 시작하고,
관리자는 관리자 Plan Limits API를 통해 셀별로 제한을 조정합니다.
이 때문에 모든 새로운 플랜 제한은 반드시 해당 API를 통해 설정 가능해야 합니다.
그렇지 않으면 새로운 제한이 각 셀에서 칼럼 기본값만 취할 수 있습니다.
셀 간에 일관성을 유지해야 하는 플랜 제한은 도입하지 마세요.
plan_limits는 셀 로컬이므로 동기화 상태를 유지할 방법이 없습니다.
데이터베이스 플랜 제한 삽입#
plan_limits 테이블에 새 칼럼을 만들고 제한 값을 삽입합니다.
두 개의 별도 마이그레이션 스크립트 파일을 만드는 것을 권장합니다.
- 원하는 제한을 나타내는 null이 아닌 기본값을 가진 새 칼럼을
plan_limits테이블에 추가합니다:
add_column(:plan_limits, :project_hooks, :integer, default: 100, null: false)
0으로 설정된 플랜 제한 항목은 제한이 활성화되어 있지 않음을 의미합니다.
이 설정은 특수하고 문서화된 상황에서만 사용해야 합니다.
- (선택 사항)
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', 'premium', 30)
create_or_update_plan_limit('project_hooks', 'premium_trial', 30)
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', 'premium', 0)
create_or_update_plan_limit('project_hooks', 'premium_trial', 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이 되도록 합니다.
- 관리자 Plan Limits API를 통해 새 칼럼을 노출합니다:
PUT /application/plan_limits에 optional 파라미터로 추가하세요
(lib/api/admin/plan_limits.rb).
관리자가 셀별로 제한을 조정할 수 있습니다.
-
응답 엔티티에 추가하세요 (
lib/api/entities/plan_limit.rb). 제한 값을 다시 읽을 수 있습니다. -
Plan Limits API 페이지에 해당 속성을 문서화하세요.
플랜 제한 유효성 검사#
현재 제한 가져오기#
현재 제한에 대한 접근은 프로젝트 또는 네임스페이스를 통해 수행할 수 있습니다:
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' # Optional as ProjectHook corresponds with 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' # Optional as InstanceVariable corresponds with instance_variables
self.limit_scope = Limitable::GLOBAL_SCOPE
end
구독 플랜#
GitLab Self-Managed:
default: 모든 사용자.
GitLab.com:
-
default: 시스템 전체 기능. -
free: Free 구독을 가진 네임스페이스 및 프로젝트. -
premium: Premium 구독을 가진 네임스페이스 및 프로젝트. -
premium_trial: Premium Trial 구독을 가진 네임스페이스 및 프로젝트. -
ultimate: Ultimate 구독을 가진 네임스페이스 및 프로젝트. -
ultimate_trial: Ultimate Trial 구독을 가진 네임스페이스 및 프로젝트. -
ultimate_trial_paid_customer: 30일 동안 Ultimate를 체험 중인 Premium 구독의 네임스페이스 및 프로젝트. -
opensource: GitLab Open Source 프로그램 회원인 네임스페이스 및 프로젝트.
GitLab.com에는 구독이 없는 early_adopter 플랜이 있습니다.
test 환경에는 플랜이 없습니다.
Rack::Attack을 사용한 속도 제한 구현#
Rack::Attack 미들웨어를 사용하여 Rack 요청을 스로틀합니다.
Rails 컨트롤러, Grape 엔드포인트 및 다른 Rack 요청에 적용됩니다.
새 스로틀을 추가하는 프로세스는 대략 다음과 같습니다:
-
ApplicationSetting모델의 rate_limits JSONB 칼럼에 새 필드를 추가합니다. -
rate_limits 칼럼의 JSON 스키마 검증기를 업데이트합니다.
-
Gitlab::RackAttack과Gitlab::RackAttack::Request를 확장하여 새 속도 제한을 구성하고, 원하는 요청에 적용합니다. -
app/views/admin/application_settings/_ip_limits.html.haml의 Admin 영역 폼에 새 설정을 추가합니다. -
사용자 및 IP 속도 제한 및 애플리케이션 설정 API에 새 설정을 문서화합니다.
-
GitLab.com의 속도 제한을 구성하고 GitLab.com의 속도 제한에 문서화합니다.
구현 세부 사항은 다음 이슈를 참조하세요:
Gitlab::ApplicationRateLimiter를 사용한 속도 제한 구현#
이 모듈은 특정 작업을 스로틀하는 데 사용할 수 있는 사용자 정의 속도 제한기를 구현합니다.
미들웨어 수준에서 동작하는 Rack::Attack 및 Rack::Throttle과 달리,
컨트롤러 또는 API 수준에서 사용할 수 있습니다.
컨트롤러에서 사용하려면 CheckRateLimit concern을 참조하세요.
코드의 다른 부분에서는 Gitlab::ApplicationRateLimiter 모듈을 직접 호출할 수 있습니다.
다음 속도 제한 아키텍처#
2022년 5월부터 미래 지향적인 속도 제한 아키텍처를 사용하는 애플리케이션 제한 프레임워크의 다음 이터레이션 작업을 시작했습니다.
새로운 요구 사항을 정의하고 다음 아키텍처를 설계하는 작업을 진행 중입니다. 새로운 제한을 추가하기 위한 새 기능이 필요한 경우, 지금 바로 구현하는 대신 속도 제한 아키텍처 워킹 그룹에 기여하는 것을 고려하세요.
다음 이터레이션의 속도 제한 아키텍처에 구축하고자 하는 기능의 예시:
-
네임스페이스별 / 플랜별로 제한을 정의하고 재정의할 수 있도록 합니다.
-
구현된 제한과 기본값에 관한 문서를 자동으로 생성합니다.
-
검색하고 탐색할 수 있는 단일 장소에 제한을 정의합니다.
-
소프트 및 하드 제한, 제한에 근접할 때 사용자에게 알림을 지원합니다.