프로파일링
성능 문제를 추적하기 쉽도록 GitLab에는 기본적으로 사용 가능한 프로파일링 도구 세트가 함께 제공됩니다. 일부 도구는 기본적으로 제공되지만, 다른 일부 도구는 명시적으로 활성화해야 합니다.
URL 프로파일링
Gitlab::Profiler.profile
메서드와 해당하는 bin/profile-url
스크립트를 사용하여 특정 URL의 GET 또는 POST 요청을 프로파일링할 수 있습니다. 이 요청은 기본적으로 익명 사용자(기본값) 또는 특정 사용자로 실행될 수 있습니다.
프로파일러의 첫 번째 인수는 전체 URL(인스턴스 호스트명 포함)이거나 슬래시로 시작하는 절대 경로입니다.
보고 덤프는 기본적으로 임시 파일에 저장되며, Stackprof API를 사용하여 상호 작용할 수 있습니다.
스크립트를 사용할 때는 매개변수를 전달하여 커맨드 라인 도움말을 확인할 수 있습니다.
대화형 콘솔 세션에서 메서드를 사용할 때는 해당 콘솔 세션 내의 애플리케이션 코드의 모든 변경 사항이 프로파일러 출력에 반영됩니다.
예:
Gitlab::Profiler.profile('/my-user')
# 보고 덤프가 저장된 임시 파일의 위치를 반환합니다
class UsersController; def show; sleep 100; end; end
Gitlab::Profiler.profile('/my-user')
# 보고 덤프가 저장된 임시 파일의 위치를 반환합니다
# UsersController#show에서 100초가 소요됨
권한이 필요한 라우트의 경우 Gitlab::Profiler
에 사용자를 제공해야 합니다. 다음과 같이 수행할 수 있습니다:
Gitlab::Profiler.profile('/gitlab-org/gitlab-test', user: User.first)
Gitlab::Profiler.profile
에 logger:
키워드 인수를 전달하여 ActiveRecord 및 ActionController 로그 출력을 해당 로거에 전송합니다. 추가 옵션은 메서드 소스와 함께 문서화되어 있습니다.
Gitlab::Profiler.profile('/gitlab-org/gitlab-test', user: User.first, logger: Logger.new($stdout))
출력 데이터의 샘플링 파일 (out
)을 구성하려면 profiler_options
해시를 전달하십시오. 예:
Gitlab::Profiler.profile('/gitlab-org/gitlab-test', user: User.first, profiler_options: { out: 'tmp/profile.dump' })
GitLab::Profiler
보고서 읽기
샘플링 데이터에 대해 Stackprof를 실행하여 시간이 소요된 위치에 대한 요약을 얻을 수 있습니다. 예:
stackprof tmp/profile.dump
샘플링 데이터의 예:
==================================
Mode: wall(1000)
Samples: 8745 (6.92% miss rate)
GC: 1399 (16.00%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
1022 (11.7%) 1022 (11.7%) Sprockets::PathUtils#stat
957 (10.9%) 957 (10.9%) (marking)
493 (5.6%) 493 (5.6%) Sprockets::PathUtils#entries
576 (6.6%) 471 (5.4%) Mustermann::AST::Translator#decorator_for
439 (5.0%) 439 (5.0%) (sweeping)
630 (7.2%) 241 (2.8%) Sprockets::Cache::FileStore#get
208 (2.4%) 208 (2.4%) ActiveSupport::FileUpdateChecker#watched
206 (2.4%) 206 (2.4%) Digest::Instance#file
544 (6.2%) 176 (2.0%) Sprockets::Cache::FileStore#safe_open
176 (2.0%) 176 (2.0%) ActiveSupport::FileUpdateChecker#max_mtime
268 (3.1%) 147 (1.7%) ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#exec_no_cache
140 (1.6%) 140 (1.6%) ActiveSupport::BacktraceCleaner#add_gem_filter
116 (1.3%) 116 (1.3%) Bootsnap::CompileCache::ISeq.storage_to_output
160 (1.8%) 113 (1.3%) Gem::Version#<=>
109 (1.2%) 109 (1.2%) block in <main>
108 (1.2%) 108 (1.2%) Gem::Version.new
131 (1.5%) 105 (1.2%) Sprockets::EncodingUtils#unmarshaled_deflated
1166 (13.3%) 82 (0.9%) Mustermann::RegexpBased#initialize
82 (0.9%) 78 (0.9%) FileUtils.touch
72 (0.8%) 72 (0.8%) Sprockets::Manifest.compile_match_filter
71 (0.8%) 70 (0.8%) Grape::Router#compile!
91 (1.0%) 65 (0.7%) ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#query
93 (1.1%) 64 (0.7%) ActionDispatch::Journey::Path::Pattern::AnchoredRegexp#accept
59 (0.7%) 59 (0.7%) Mustermann::AST::Translator.dispatch_table
62 (0.7%) 59 (0.7%) Rails::BacktraceCleaner#initialize
2492 (28.5%) 49 (0.6%) Sprockets::PathUtils#stat_directory
242 (2.8%) 49 (0.6%) Gitlab::Instrumentation::RedisBase.add_call_details
47 (0.5%) 47 (0.5%) URI::RFC2396_Parser#escape
46 (0.5%) 46 (0.5%) #<Class:0x00000001090c2e70>#__setobj__
44 (0.5%) 44 (0.5%) Sprockets::Base#normalize_logical_path
플레임그래프를 생성할 수도 있습니다:
stackprof --d3-flamegraph tmp/profile.dump > flamegraph.html
자세한 내용은 Stackprof 문서를 참조하십시오.
Speedscope flamegraphs
파폭그래프를 생성하려면 성능 표시줄에서 파폭그래프 샘플링 모드 버튼을 선택하거나 요청에 performance_bar=flamegraph
매개변수를 추가합니다.
Speedscope 문서에서 뷰에 대해 더 많은 정보를 찾을 수 있습니다.
Stackprof 문서에서 다양한 샘플링 모드에 대해 더 많은 정보를 찾을 수 있습니다.
이 기능은 성능 표시줄에 액세스할 수 있는 모든 사용자에게 활성화됩니다.
Bullet
Bullet는 N+1 쿼리 문제를 추적하는 데 사용할 수 있는 Gem입니다. 이는 쿼리 문제를 Rails 로그와 브라우저 콘솔에 기록합니다. Bullet 섹션은 성능 표시줄에 표시됩니다.
Bullet는 기본적으로 개발 모드에서만 활성화됩니다. 그러나 로깅은 비활성화되어 있습니다. Bullet 로깅은 시끄러우므로 로깅을 구성하려면 다음을 수행합니다:
-
환경에 따라 Bullet를 매뉴얼으로 활성화하거나 비활성화하려면
config/gitlab.yml
에 다음 라인을 추가하고enabled
값을 필요에 따라 변경합니다:bullet: enabled: false
-
Bullet 로깅을 활성화하려면 GitLab을 시작하기 전에
ENABLE_BULLET
환경 변수를 비어 있지 않은 값으로 설정합니다:ENABLE_BULLET=true bundle exec rails s
Bullet를 사용하여 N+1
쿼리를 찾은 후에는 QueryRecoder 테스트를 작성하여 회귀를 방지하는 것이 좋습니다.
System stats
프로파일링 중이거나 이후에는 루비 가상 머신 프로세스에 대한 메모리 소비, CPU에서 소요된 시간 또는 가비지 수집기 통계와 같은 자세한 정보를 얻고 싶을 수 있습니다. 이러한 정보는 다양한 도구를 통해 개별적으로 손쉽게 생성할 수 있지만 편의상 이 데이터를 JSON 페이로드로 내보내는 요약 엔드포인트가 추가되었습니다:
curl localhost:3000/-/metrics/system | jq
예시 출력:
{
"version": "ruby 2.7.2p137 (2020-10-01 revision a8323b79eb) [x86_64-linux-gnu]",
"gc_stat": {
"count": 118,
"heap_allocated_pages": 11503,
...
},
"memory_rss": 1326501888,
...
}
참고: 이 엔드포인트는 Rails 웹 워커에만 사용할 수 있습니다. Sidekiq 워커는 이 방법으로 검사할 수 없습니다.
성능에 영향을 주는 설정
애플리케이션 설정
- 기본적으로
development
환경은 핫 리로딩이 활성화되어 있습니다. 이로 인해 Rails는 각 요청마다 파일 변경을 확인하고 잠재적인 경항 록을 만듭니다. 핫 리로딩은 단일 스레드이기 때문에 첫 번째 요청은 항상 느릴 수 있습니다. -
development
환경은 요청이 발생할 때 코드를 지연 로딩할 수 있기 때문에 첫 번째 요청이 항상 느립니다.
프로파일링/벤치마킹을 위해 이러한 기능을 비활성화하려면 GitLab을 시작하기 전에 RAILS_PROFILE
환경 변수를 true
로 설정합니다. 예를 들어 GDK를 사용하는 경우:
- GDK 루트 디렉터리에
env.runit
파일을 만듭니다. -
env.runit
파일에export RAILS_PROFILE=true
를 추가합니다. -
gdk restart
를 사용하여 GDK를 다시 시작합니다.
이 환경 변수는 개발 모드에만 적용됩니다.
GC 설정
루비의 가비지 수집기 (GC)는 응용 프로그램 성능에 직접적인 영향을 미칠 수 있는 다양한 환경 변수를 통해 조정할 수 있습니다.
다음 표는 이러한 변수들과 기본값을 나열합니다.
환경 변수 | 기본값 |
---|---|
RUBY_GC_HEAP_INIT_SLOTS
| 10000
|
RUBY_GC_HEAP_FREE_SLOTS
| 4096
|
… |
(원본)
GitLab은 응용 프로그램 성능을 높이거나 메모리 요구 사항을 낮추거나 둘 다를 위해 이러한 설정을 변경할 수 있습니다.
각각의 설정이 GC 성능, 메모리 사용 및 GitLab의 비활성 상태에서 응용 프로그램 시작 시간에 어떻게 영향을 미치는지를 확인하려면 scripts/perf/gc/collect_gc_stats.rb
스크립트를 실행합니다. 이 스크립트는 표준 출력에 GC 통계와 일반적인 시간 데이터를 CSV 형식으로 출력합니다.