This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
proposed @grzesiek @fabiopitino 2023-05-22

GitLab 모듈화된 단일 체계

요약

GitLab Rails 주요 프로젝트는 Ruby on Rails 프레임워크를 사용하여 큰 단일 응용 프로그램으로 구현되었습니다. 2,200,000 줄 이상의 루비 코드와 수백 명의 엔지니어가 매일 기여하고 있습니다.

애플리케이션은 10년 이상 복잡성이 증가해 왔습니다. 단일 체계 구조는 이 기간 동안 우리에게 잘 맞아왔으며 빠른 개발 속도와 우수한 엔지니어링 프로덕션성을 유지할 수 있게 했습니다.

우리는 일관된 오픈 코어 아키텍처를 추구하고 있지만, 속도를 유지하고 개발 예측 가능성을 높이기 위해 도메인 간 경계를 강화해야 합니다.

우리가 엔지니어링 조직으로 성장할수록 다소 다른 관련 아키텍처 패러다임을 탐구하고 싶습니다: 모듈화된 단일 체계 디자인을 사용하여 여전히 위성 서비스를 사용하는 단일 체계 아키텍처를 유지하면서.

이는 엔지니어링 효율성을 높이고 인지 부하를 줄이며, 필요한 경우 내부 구성요소를 분리하여 별도로 배포하고 실행할 수 있게 할 것으로 기대됩니다.

동기

큰 규모의 밀접한 단일 응용 프로그램과 작업하는 것은 도전적입니다:

엔지니어링:

  • 엔지니어를 온보딩하는 데 시간이 걸립니다. 엔지니어가 프로덕션적으로 느끼기까지는 시간이 걸리며 맥락의 크기와 결합의 양 때문입니다.
  • 우리는 몇 가지 도메인에 대해 CODEOWNERS 파일 기능을 사용해야 하지만 이 규칙들은 복잡합니다.
  • 응용 프로그램의 크기 때문에 엔지니어가 응용 프로그램의 정신적인 지도를 만드는 것이 어렵습니다. 겉으로 보기에 격리된 변경도 응용 프로그램의 다른 부분에 긴밀한 파급 효과가 발생할 수 있습니다.
  • 엔지니어링 인재의 이탈/유지. 프로덕션성을 위해 끊임없이 이를 극복하려는 것은 지치고 사기가 저하됩니다.

아키텍처:

  • 단일 체계 내부에는 구조가 거의 없습니다. 우리는 어떤 모듈의 생성을 강요하기는 했지만 회사 전체적인 전략은 존재하지 않으며 코드 구성이어야 할 기능적인 부분이 무엇인지, 그리고 코드를 어떻게 구성할지에 대한 전략이 없습니다.
  • 기존 모듈 간에 격리가 없습니다. 루비는 효과적으로 경계를 강제할 수 있는 기본 도구를 제공하지 않습니다. 모든 것이 동일한 메모리 공간 하에 존재합니다.
  • 우리는 효율성을 높일 수 있는 추상화를 거의 구축하지 않습니다.
  • 응용 프로그램의 안정적인 부분을 별도 서비스로 이동하는 것은 높은 결합력으로 인해 불가능합니다.
  • 특정 도메인으로 변경 사항을 배포하고 그 내부에서 발생한 오류를 격리하는 것이 불가능합니다.

프로덕션성:

  • 복잡한 변경에 대해 프로덕션에 필요한 매체 시간이 오래 걸립니다.
  • 광범위한 커뮤니티 구성원들에게 기여하는 것은 어려울 수 있습니다.
  • 테스트 시간을 줄이려면 꾸준하고 끈기 있는 노력이 필요합니다.

목표

  • 관심사 분리를 통해 개발 속도와 예측 가능성을 높입니다.
  • 결합을 줄이고 유용한 추상화를 도입하여 코드 품질을 개선합니다.
  • GitLab 구성요소를 별도로 배포하고 실행할 수 있는 추상화를 구축합니다.

목표 달성 방법

모듈화가 중대한 기술적 노력이라는 것을 인정하면서도, 주된 도전은 기술적인 것보다는 조직적인 것이라고 믿습니다. 우리는 모듈이 GitLab.com에서 잘 작동하는 방식으로 격리된 방식으로 설계해야 하며, Self-Managed형 인스턴스에서도 잘 작동해야 하기 때문입니다. 또한, 모듈화를 GitLab에서 원하는 방식과 일치시켜야 합니다.

우리의 단일 체계의 모듈화를 성공적으로 만들기 위해 필요한 많은 측면과 세부 내용이 있습니다. 아래에 나열된 측면에 대해 작업하고 세부 내용을 정제하고 추가하여 목표 방향으로 전진할 것입니다.

  1. 주요 통찰을 제공할 모듈화 증명 개념을 제공.
  2. 뼈대 上의 경계 정의를 통해 제품 구조에 모듈화 계획을 맞추기.
  3. 제품 구조를 반영할 모듈화 계획으로 도메인을 모듈화.
  4. 격리된 도메인 처리 방법에 대한 팀원들을 위한 교육 프로그램 시작 (TODO)
  5. 제어의 역전을 통해 격리된 도메인을 쉽게 구축할 수 있게 하는 도구 구축 (TODO)
  6. 단일 체계 내에서 육각형 아키텍처를 도입 (hexagonal_monolith/index.md)
  7. 단일 방향 의존성과 호스트 응용 프로그램으로 깔끔한 아키텍처 도입 (TODO)
  8. 도메인을 별도로 실행하고 배포할 수 있게 하는 추상화 구축 (TODO)

상태

진행 중.

  • Bounded Contexts 작업 그룹이 2024년 4월에 마무리되었으며 GitLab Rails 도메인 및 인프라 레이어에 강제할 바운드 컨텍스트 디렉터리을 정의했습니다.

결정 사항

  1. ADR-001: 응용 프로그램 도메인을 모듈화? 응용 프로그램 도메인 및 인프라 코드를 모듈화하는 것부터 시작합니다.
  2. ADR-002: 기능 범주 주변에 경계된 컨텍스트 정의를 코드의 단일 진리로.
  3. ADR-003: 모든 모듈 및 라이브러리에 관리자 할당.

용어집

  • 모듈은 루비 모듈이며 코드를 계층적으로 중첩할 수 있습니다.
  • 네임스페이스는 고유한 루비 상수의 계층 구조입니다. 예를 들어, Ci:: 또는 Ci::JobArtifacts::, Ci::Pipeline::Chain::과 같은 것입니다.
  • 패키지는 관련된 기능을 그룹화하는 Packwerk 패키지입니다. 이러한 패키지는 설계 및 아키텍처에 따라서 크거나 작을 수 있습니다. 패키지 내에서 모든 상수(클래스 및 모듈)는 동일한 네임스페이스를 갖습니다. 예를 들어:
    • ci 패키지에서 모든 클래스는 Ci:: 네임스페이스 아래에 중첩됩니다. Ci::PipelineProcessing::와 같이 중첩된 네임스페이스도 가능합니다.
    • ci-pipeline_creation 패키지는 모든 클래스를 Ci::PipelineCreation 아래에 중첩합니다. 즉, Ci::PipelineCreation::Chain::Command와 같은 것입니다.
    • ci 패키지에서 MergeRequests::UpdateHeadPipelineService와 같은 클래스는 패키지의 네임스페이스와 일치하지 않으므로 허용되지 않습니다.
    • 이는 Packwerk 기반의 RuboCop Cops로 쉽게 강제할 수 있습니다.
  • 경게된 컨텍스트는 도메인의 매크로 측면을 나타내는 최상위 Packwerk 패키지입니다. 예: Ci::, MergeRequests::, Packages:: 등입니다.
    • 경계된 컨텍스트는 단일 루비 모듈/네임스페이스로 나타납니다. 예: Ci::가 아니라 Ci::JobArtifacts::입니다.
    • 경계된 컨텍스트는 1개 이상의 Packwerk 패키지로 이루어질 수 있습니다. 도메인이 복잡하고 모든 구현 세부 사항 사이의 프라이버시를 강제하려는 경우 중첩된 패키지가 권장됩니다. 예: Ci::PipelineProcessing::Ci::PipelineCreation::은 동일한 경계된 컨텍스트의 별도 패키지로 구성될 수 있으며 공개 API를 노출하고 구현 세부 사항을 비공개로 유지할 수 있습니다.
    • RemoteDevelopment::와 같은 새로운 경계된 컨텍스트는 크고 복잡한 경계된 컨텍스트와는 다르게 단일 패키지로 표현될 수 있으며, Ci::와 같은 큰 경계된 컨텍스트는 더 작거나 중첩된 패키지로 구성되어야 합니다.

참조

참조 디렉터리