- Sidekiq 작업에 전달되는 인수 로깅
- Sidekiq 대기열 대기 또는 느린 성능 조사
- 쓰레드 덤프
rbspy
를 사용한 루비 프로파일링perf
를 사용한 프로세스 프로파일링- GNU 프로젝트 디버거(
gdb
) - Sidekiq kill signals
- 블로킹 쿼리 확인
- Sidekiq 대기열 관리
- 실행 중인 작업 취소 (파괴적인)
- 크론 작업 수동으로 트리거하기
- 크론 작업 비활성화
- Sidekiq 작업 중복성 Idempotency 키 지우기
- Sidekiq BRPOP 호출에 의한 Redis CPU 포화
- 오류:
OpenSSL::Cipher::CipherError
- 관련 주제
Sidekiq 문제 해결
Sidekiq는 GitLab이 비동기로 작업을 실행하기 위해 사용하는 백그라운드 작업 프로세서입니다. 문제가 발생하면 문제 해결이 어려울 수 있습니다. 또한 프로덕션 시스템의 작업 대기열이 채워지는 경우에는 고압일 가능성이 높습니다. 사용자는 새 브랜치가 표시되지 않거나 병합 요청이 업데이트되지 않는 것을 알게 됩니다. 다음은 병목 현상을 진단하는 데 도움이 되는 몇 가지 문제 해결 단계입니다.
GitLab 관리자/사용자는 GitLab 지원팀과 함께 이러한 디버그 단계를 수행하여 백트레이스를 분석해야 합니다. 이는 때로는 GitLab에서 버그나 개선이 필요한 사항을 드러낼 수 있습니다.
백트레이스 중 어디에서든 데이터베이스, Redis에서 대기 중이거나 뮤텍스를 획들기 위해 대기하고 있는 쓰레드가 의심스러운 경우를 주의해야 합니다. 이 가능성이 있을 수도 있지만, 나머지 쓰레드와 다른 하나를 찾으세요. 이 다른 쓰레드는 모든 사용 가능한 CPU를 사용하거나 루비 전역 인터프리터 락을 가지고 있을 수 있어서 다른 쓰레드가 계속할 수 없게 만들 수 있습니다.
Sidekiq 작업에 전달되는 인수 로깅
일부 특정 작업을 제외한 모든 작업의 숫자 인수를 기본적으로 GitLab에 의해 기록합니다. (예: 비밀번호 초기화 토큰).
예제 로그 출력:
{"severity":"INFO","time":"2020-06-08T14:37:37.892Z","class":"AdminEmailsWorker","args":["[FILTERED]","[FILTERED]","[FILTERED]"],"retry":3,"queue":"admin_emails","backtrace":true,"jid":"9e35e2674ac7b12d123e13cc","created_at":"2020-06-08T14:37:37.373Z","meta.user":"root","meta.caller_id":"Admin::EmailsController#create","correlation_id":"37D3lArJmT1","uber-trace-id":"2d942cc98cc1b561:6dc94409cfdd4d77:9fbe19bdee865293:1","enqueued_at":"2020-06-08T14:37:37.410Z","pid":65011,"message":"AdminEmailsWorker JID-9e35e2674ac7b12d123e13cc: done: 0.48085 sec","job_status":"done","scheduling_latency_s":0.001012,"redis_calls":9,"redis_duration_s":0.004608,"redis_read_bytes":696,"redis_write_bytes":6141,"duration_s":0.48085,"cpu_s":0.308849,"completed_at":"2020-06-08T14:37:37.892Z","db_duration_s":0.010742}
{"severity":"INFO","time":"2020-06-08T14:37:37.894Z","class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped":"ActionMailer::MailDeliveryJob","queue":"mailers","args":["[FILTERED]"],"retry":3,"backtrace":true,"jid":"e47a4f6793d475378432e3c8","created_at":"2020-06-08T14:37:37.884Z","meta.user":"root","meta.caller_id":"AdminEmailsWorker","correlation_id":"37D3lArJmT1","uber-trace-id":"2d942cc98cc1b561:29344de0f966446d:5c3b0e0e1bef987b:1","enqueued_at":"2020-06-08T14:37:37.885Z","pid":65011,"message":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper JID-e47a4f6793d475378432e3c8: start","job_status":"start","scheduling_latency_s":0.009473}
{"severity":"INFO","time":"2020-06-08T14:39:50.648Z","class":"NewIssueWorker","args":["455","1"],"retry":3,"queue":"new_issue","backtrace":true,"jid":"a24af71f96fd129ec47f5d1e","created_at":"2020-06-08T14:39:50.643Z","meta.user":"root","meta.project":"h5bp/html5-boilerplate","meta.root_namespace":"h5bp","meta.caller_id":"Projects::IssuesController#create","correlation_id":"f9UCZHqhuP7","uber-trace-id":"28f65730f99f55a3:a5d2b62dec38dffc:48ddd092707fa1b7:1","enqueued_at":"2020-06-08T14:39:50.646Z","pid":65011,"message":"NewIssueWorker JID-a24af71f96fd129ec47f5d1e: start","job_status":"start","scheduling_latency_s":0.001144}
Sidekiq JSON 로깅을 사용할 때, 인수 로그는 최대 10 킬로바이트의 텍스트 크기로 제한되며, 이 제한 이후의 인수는 폐기되고 문자열 "..."
을 포함하는 단일 인수로 대체됩니다.
SIDEKIQ_LOG_ARGUMENTS
환경 변수를 0
(false)로 설정하여 인수 로깅을 비활성화할 수 있습니다.
예제:
gitlab_rails['env'] = {"SIDEKIQ_LOG_ARGUMENTS" => "0"}
Sidekiq 대기열 대기 또는 느린 성능 조사
느린 Sidekiq 성능의 증상은 병합 요청 상태 업데이트에 문제가 있거나 CI 파이프라인이 실행되기 전에 지연된 것입니다.
잠재적인 원인으로는:
-
GitLab 인스턴스가 더 많은 Sidekiq 워커가 필요할 수 있습니다. 기본적으로 단일 노드 Linux 패키지 설치는 하나의 워커를 실행하며, Sidekiq 작업을 최대 하나의 CPU 코어에서 실행합니다. 여러 Sidekiq 워커 실행에 대해 더 읽어보기.
-
인스턴스가 더 많은 Sidekiq 워커가 구성된 경우에도 추가 워커의 대부분이 대기 중인 작업을 실행하도록 구성되지 않았습니다. 이는 인스턴스가 바쁜 경우 작업 부하가 월 또는 년간 변경되었거나, GitLab 제품 변경의 결과로 발생할 수 있습니다.
다음의 Ruby 스크립트를 사용하여 Sidekiq 워커의 상태에 관한 데이터를 수집합니다.
-
스크립트 생성:
cat > /var/opt/gitlab/sidekiqcheck.rb <<EOF require 'sidekiq/monitor' Sidekiq::Monitor::Status.new.display('overview') Sidekiq::Monitor::Status.new.display('processes'); nil Sidekiq::Monitor::Status.new.display('queues'); nil puts "----------- workers ----------- " workers = Sidekiq::Workers.new workers.each do |_process_id, _thread_id, work| pp work end puts "----------- Queued Jobs ----------- " Sidekiq::Queue.all.each do |queue| queue.each do |job| pp job end end ;nil puts "----------- done! ----------- " EOF
-
실행하고 출력 캡처:
sudo gitlab-rails runner /var/opt/gitlab/sidekiqcheck.rb > /tmp/sidekiqcheck_$(date '+%Y%m%d-%H:%M').out
성능 문제가 때로는 발생하는 경우:
-
이것을 지속적으로 5분마다 크론 작업에서 실행합니다. 충분한 공간을 가진 위치에 파일을 작성하십시오: 파일당 최소 500KB 이상의 공간을 확보하십시오.
cat > /etc/cron.d/sidekiqcheck <<EOF */5 * * * * root /opt/gitlab/bin/gitlab-rails runner /var/opt/gitlab/sidekiqcheck.rb > /tmp/sidekiqcheck_$(date '+\%Y\%m\%d-\%H:\%M').out 2>&1 EOF
-
무엇이 잘못되었는지 확인하기 위해 데이터를 참조하십시오.
-
-
출력을 분석합니다. 아래 명령들은 출력 파일 디렉토리를 가정합니다.
-
grep 'Busy: ' *
은 실행 중인 작업의 수를 보여줍니다.grep 'Enqueued: ' *
는 해당 시간에 대기 중인 작업을 보여줍니다. -
Sidekiq가 부하 중인 샘플에서 워커 전체에서 바쁜 쓰레드의 수를 살펴보세요:
ls | while read f ; do if grep -q 'Enqueued: 0' $f; then : else echo $f; egrep 'Busy:|Enqueued:|---- Processes' $f grep 'Threads:' $f ; fi done | more
예시 출력:
sidekiqcheck_20221024-14:00.out Busy: 47 Enqueued: 363 ---- Processes (13) ---- Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 23 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (0 busy) Threads: 30 (24 busy) Threads: 30 (23 busy)
- 이 출력 파일에서 47개의 쓰레드가 바쁘며, 363개의 작업 대기열이 있었습니다.
- 13 개의 워커 프로세스 중 2개만 바쁜 상태였습니다.
- 다른 워커가 너무 특정하게 구성되었음을 나타냅니다.
-
sidekiq_queues
구성과 상관관계를 찾으려면 전체 출력을 살펴보세요. -
한 가지 워커로 오버로드된 환경은 다음과 같을 수 있습니다.
sidekiqcheck_20221024-14:00.out Busy: 25 Enqueued: 363 ---- Processes (1) ---- Threads: 25 (25 busy)
-
파일 내의
---- Queues (xxx) ----
섹션을 살펴보아 그 시간에 대기 중인 작업을 결정합니다. -
파일에는 작업 부하가 발생한 지점의 낮은 수준의 세부 정보도 포함되어 있습니다. 이는 작업 부하가 어디에서 주로 발생하는지 확인하는 데 유용할 수 있습니다.
-
----------- workers -----------
섹션은 요약에서Busy
수량을 구성하는 작업에 대한 세부 정보를 제공합니다. -
----------- Queued Jobs -----------
섹션은Enqueued
상태의 작업에 대한 세부 정보를 제공합니다.
-
-
쓰레드 덤프
TTIN
신호를 Sidekiq 프로세스 ID에 보내 스레드 백트레이스를 로그 파일에 출력합니다.
kill -TTIN <sidekiq_pid>
백트레이스 출력을 확인하려면 /var/log/gitlab/sidekiq/current
또는 $GITLAB_HOME/log/sidekiq.log
를 확인하세요. 백트레이스는 일반적으로 여러 WARN
수준 메시지로 시작하는 긴 메시지입니다. 다음은 단일 스레드의 백트레이스의 예시입니다:
2016-04-13T06:21:20.022Z 31517 TID-orn4urby0 WARN: ActiveRecord::RecordNotFound: Couldn't find Note with 'id'=3375386
2016-04-13T06:21:20.022Z 31517 TID-orn4urby0 WARN: /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.2.5.2/lib/active_record/core.rb:155:in `find'
/opt/gitlab/embedded/service/gitlab-rails/app/workers/new_note_worker.rb:7:in `perform'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:150:in `execute_job'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/sidekiq-4.0.1/lib/sidekiq/processor.rb:132:in `block (2 levels) in process'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:127:in `block in invoke'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/sidekiq_middleware/memory_killer.rb:17:in `call'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/sidekiq-4.0.1/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/sidekiq_middleware/arguments_logger.rb:6:in `call'
...
일부 경우에는 Sidekiq가 멈추어 TTIN
신호에 응답하지 못할 수 있습니다. 그럴 경우 다른 문제 해결 방법으로 넘어가세요.
rbspy
를 사용한 루비 프로파일링
rbspy는 CPU 사용량의 flamegraph 스타일 다이어그램을 만들 수 있는 사용하기 쉽고 오버헤드가 적은 루비 프로파일러입니다.
GitLab의 변경 사항은 필요하지 않으며 의존성도 없습니다. 설치하려면:
-
rbspy
릴리스 페이지에서 바이너리를 다운로드합니다. - 바이너리를 실행 가능하게 만듭니다.
한 분 동안 Sidekiq worker를 프로파일링하려면 다음을 실행합니다:
sudo ./rbspy record --pid <sidekiq_pid> --duration 60 --file /tmp/sidekiq_profile.svg
이 rbspy
로 생성된 flamegraph 예시에서 대부분의 Sidekiq 프로세스 시간이 Rugged의 네이티브 C 함수 중 하나인 rev_parse
에서 소요되고 있습니다. 스택에서 rev_parse
가 ExpirePipelineCacheWorker
에 의해 호출되는 것을 볼 수 있습니다.
rbspy
는 컨테이너화된 환경에서 별도의 권한을 필요로 합니다. 최소한SYS_PTRACE
기능이 필요하며, 그렇지 않으면 permission denied
오류로 종료됩니다.
::: TabTitle 쿠버네티스
securityContext:
capabilities:
add:
- SYS_PTRACE
docker run --cap-add SYS_PTRACE [...]
services:
ruby_container_name:
...
cap_add:
- SYS_PTRACE
perf
를 사용한 프로세스 프로파일링
리눅스에는 특정 프로세스가 많은 CPU를 사용하는 경우 유용한 프로세스 프로파일링 도구인 perf
가 있습니다. 높은 CPU 사용량이 있고 Sidekiq가 TTIN
신호에 응답하지 않는 경우 다음 단계로 넘어가세요.
만약 시스템에 perf
가 설치되지 않았다면 apt-get
또는 yum
을 통해 설치하세요:
# Debian
sudo apt-get install linux-tools
# Ubuntu (추가 커널 패키지가 필요할 수 있습니다)
sudo apt-get install linux-tools-common linux-tools-generic linux-tools-`uname -r`
# Red Hat/CentOS
sudo yum install perf
Sidekiq PID에 대해 perf
를 실행하세요:
sudo perf record -p <sidekiq_pid>
30-60초 이내로 실행한 후에 Ctrl-C를 누르세요. 그런 다음 perf
보고서를 확인하세요:
$ sudo perf report
# 샘플 출력
Samples: 348K of event 'cycles', Event count (approx.): 280908431073
97.69% ruby nokogiri.so [.] xmlXPathNodeSetMergeAndClear
0.18% ruby libruby.so.2.1.0 [.] objspace_malloc_increase
0.12% ruby libc-2.12.so [.] _int_malloc
0.10% ruby libc-2.12.so [.] _int_free
위는 perf
보고서의 샘플 출력입니다. 거의 97%의 CPU가 Nokogiri 및 xmlXPathNodeSetMergeAndClear
안에서 사용되고 있는 것을 보여줍니다. 이러한 명백한 상황에 대해서는 GitLab의 어떤 작업이 Nokogiri 및 XPath를 사용하는 지 조사해야 합니다. 이것은 해당하는 루비 코드를 확인하기 위해 TTIN
또는 gdb
출력과 결합할 수 있습니다.
GNU 프로젝트 디버거(gdb
)
gdb
는 Sidekiq를 디버깅하는 데 유용한 또 다른 도구일 수 있습니다. 각 스레드를 조사하고 문제의 원인을 찾는 더 상호작용적인 방법을 제공합니다.
gdb
로 프로세스에 연결하면 해당 프로세스의 표준 작동이 중단됩니다(Sidekiq는 gdb
가 연결된 동안 작업을 처리하지 않습니다).
먼저 Sidekiq PID에 연결하여 시작하세요:
gdb -p <sidekiq_pid>
그런 다음 모든 스레드에 대한 정보를 수집하세요:
info threads
# 예시 출력
30 Thread 0x7fe5fbd63700 (LWP 26060) 0x0000003f7cadf113 in poll () from /lib64/libc.so.6
29 Thread 0x7fe5f2b3b700 (LWP 26533) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
28 Thread 0x7fe5f2a3a700 (LWP 26534) 0x0000003f7ce0ba5e in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
27 Thread 0x7fe5f2939700 (LWP 26535) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
26 Thread 0x7fe5f2838700 (LWP 26537) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
25 Thread 0x7fe5f2737700 (LWP 26538) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
24 Thread 0x7fe5f2535700 (LWP 26540) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
23 Thread 0x7fe5f2434700 (LWP 26541) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
22 Thread 0x7fe5f2232700 (LWP 26543) 0x0000003f7ce0b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
21 Thread 0x7fe5f2131700 (LWP 26544) 0x00007fe5f7b570f0 in xmlXPathNodeSetMergeAndClear ()
from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
...
위와 같이 의심스러운 스레드를 볼 수 있으면 더 많은 정보를 얻을 수 있을 것입니다:
thread 21
bt
# 예시 출력
#0 0x00007ff0d6afe111 in xmlXPathNodeSetMergeAndClear () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#1 0x00007ff0d6b0b836 in xmlXPathNodeCollectAndTest () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#2 0x00007ff0d6b09037 in xmlXPathCompOpEval () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#3 0x00007ff0d6b09017 in xmlXPathCompOpEval () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#4 0x00007ff0d6b092e0 in xmlXPathCompOpEval () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#5 0x00007ff0d6b0bc37 in xmlXPathRunEval () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#6 0x00007ff0d6b0be5f in xmlXPathEvalExpression () from /opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/nokogiri-1.6.7.2/lib/nokogiri/nokogiri.so
#7 0x00007ff0d6a97dc3 in evaluate (argc=2, argv=0x1022d058, self=<value optimized out>) at xml_xpath_context.c:221
#8 0x00007ff0daeab0ea in vm_call_cfunc_with_frame (th=0x1022a4f0, reg_cfp=0x1032b810, ci=<value optimized out>) at vm_insnhelper.c:1510
모든 스레드에서 한꺼번에 백트레이스를 출력하려면:
set pagination off
thread apply all bt
gdb
디버깅이 끝나면 프로세스에서 분리하고 종료해야 합니다:
detach
exit
Sidekiq kill signals
TTIN 시그널은 로깅을 위해 백트레이스를 출력하는 시그널로 설명되었지만 Sidekiq는 다른 시그널에도 응답합니다. 예를 들어 TSTP와 TERM을 사용하여 Sidekiq를 정상적으로 종료할 수 있습니다. 자세한 내용은 Sidekiq Signals 문서를 참조하십시오.
블로킹 쿼리 확인
때로는 Sidekiq이 작업을 처리하는 속도가 너무 빨라 데이터베이스 contention을 일으킬 수 있습니다. 위의 백트레이스에서 많은 스레드가 데이터베이스 어댑터에 갇혀있음을 보여줄 때 블로킹 쿼리를 확인하십시오.
PostgreSQL 위키에는 블로킹 쿼리를 확인할 수 있는 쿼리에 대한 세부 정보가 있습니다. 쿼리는 PostgreSQL 버전에 따라 다릅니다. 쿼리 세부 정보는 Lock Monitoring를 참조하십시오.
Sidekiq 대기열 관리
Sidekiq API를 사용하여 Sidekiq에서 여러 문제 해결 단계를 수행할 수 있습니다.
이러한 명령은 관리 목적으로 사용되며 현재 설치의 규모로 인해 관리 인터페이스가 적합하지 않을 때에만 사용해야 합니다.
모든 이러한 명령은 gitlab-rails console
을 사용하여 실행해야 합니다.
대기열 크기 보기
Sidekiq::Queue.new("pipeline_processing:build_queue").size
모든 대기 중인 작업 열거
queue = Sidekiq::Queue.new("chaos:chaos_sleep")
queue.each do |job|
# job.klass # => 'MyWorker'
# job.args # => [1, 2, 3]
# job.jid # => jid
# job.queue # => chaos:chaos_sleep
# job["retry"] # => 3
# job.item # => {
# "class"=>"Chaos::SleepWorker",
# "args"=>[1000],
# "retry"=>3,
# "queue"=>"chaos:chaos_sleep",
# "backtrace"=>true,
# "queue_namespace"=>"chaos",
# "jid"=>"39bc482b823cceaf07213523",
# "created_at"=>1566317076.266069,
# "correlation_id"=>"c323b832-a857-4858-b695-672de6f0e1af",
# "enqueued_at"=>1566317076.26761},
# }
# job.delete if job.jid == 'abcdef1234567890'
end
현재 실행 중인 작업 열거
workers = Sidekiq::Workers.new
workers.each do |process_id, thread_id, work|
# process_id는 Sidekiq 프로세스마다 고유한 식별자입니다
# thread_id는 스레드마다 고유한 식별자입니다
# work는 다음과 같이 보입니다:
# {"queue"=>"chaos:chaos_sleep",
# "payload"=>
# { "class"=>"Chaos::SleepWorker",
# "args"=>[1000],
# "retry"=>3,
# "queue"=>"chaos:chaos_sleep",
# "backtrace"=>true,
# "queue_namespace"=>"chaos",
# "jid"=>"b2a31e3eac7b1a99ff235869",
# "created_at"=>1566316974.9215662,
# "correlation_id"=>"e484fb26-7576-45f9-bf21-b99389e1c53c",
# "enqueued_at"=>1566316974.9229589},
# "run_at"=>1566316974}],
end
특정 매개변수에 대한 Sidekiq 작업 제거 (파괴적인)
조건에 따라 작업을 중지시키는 일반적인 방법은 다음 명령입니다. 이는 대기 중이지만 시작되지 않은 작업을 제거합니다. 실행 중인 작업은 종료할 수 없습니다.
queue = Sidekiq::Queue.new('<queue name>')
queue.each { |job| job.delete if <condition>}
취소되는 작업에 대한 섹션을 참조하십시오.
위의 방법에서 <queue-name>
은 삭제하려는 작업이 포함된 대기열의 이름이고 <condition>
은 어떤 작업을 삭제할지 결정합니다.
일반적으로 <condition>
은 작업 아규먼트를 참조하며 이는 해당 작업 유형에 따라 다릅니다. 특정 대기열의 아규먼트를 찾으려면 일반적으로 /app/workers/<queue-name>_worker.rb
에 위치한 관련 워커 파일의 perform
함수를 확인할 수 있습니다.
예를 들어 repository_import
는 작업 아규먼트로 project_id
를 갖고 있으며, update_merge_requests
는 project_id
, user_id
, oldrev
, newrev
, ref
를 갖고 있습니다.
아규먼트는 job.args
가 Sidekiq 작업에 제공된 모든 아규먼트의 목록이므로 순서 ID로 참조해야 합니다.
다음은 일부 예시입니다:
queue = Sidekiq::Queue.new('update_merge_requests')
# 이 예제에서는 ID가 125이고 ref가 `ref/heads/my_branch`인 어떤 update_merge_requests 작업을 삭제하려고 합니다
queue.each { |job| job.delete if job.args[0] == 125 and job.args[4] == 'ref/heads/my_branch' }
# `RepositoryImportWorker.new.perform_async(100)`와 같은 작업을 취소하는 경우
id_list = [100]
queue = Sidekiq::Queue.new('repository_import')
queue.each do |job|
job.delete if id_list.include?(job.args[0])
end
특정 작업 ID 삭제 (파괴적인)
queue = Sidekiq::Queue.new('repository_import')
queue.each do |job|
job.delete if job.jid == 'my-job-id'
end
실행 중인 작업 취소 (파괴적인)
이는 매우 위험한 작업으로 최후의 수단으로 사용해야 합니다. 작업이 실행 중인 경우 데이터 손상이 발생할 수 있으며 적절한 롤백이 구현되지 않을 수 있습니다.
Gitlab::SidekiqDaemon::Monitor.cancel_job('job-id')
이 작업을 수행하려면
SIDEKIQ_MONITOR_WORKER=1
환경 변수로 Sidekiq를 실행해야 합니다.
인터럽트를 수행하기 위해 우리는 Thread.raise
를 사용하는데, 이는 Why Ruby’s Timeout is dangerous (and Thread.raise is terrifying)에 언급된 것처럼 여러 단점이 있습니다:
여기서 함의가 흥미롭고 무서운 것을 알 수 있습니다. 이것은 예외가 발생할 수 있다는 것을 의미합니다:
- 네트워크 요청 중 (주변 코드가 Timeout::Error를 catch하는 것이 준비가 되어 있다면 괜찮음)
- 네트워크 요청의 정리 중
- rescue 블록 중
- 이후에 데이터베이스에 저장하기 위한 객체를 만드는 중
- 코드 중 어디서든, 이전에 예외를 발생시킬 수 있지 않을지라도
누구도 정말로 모든 줄에서 예외에 대비하는 코드를 작성하지 않습니다. 그것은 심지어 불가능합니다. 그래서 Thread.raise는 사실상 거의 모든 것으로 이어질 수 있는 코드에 대한 의도치 않은 공격과 같습니다. 아마도 모든 상태를 수정하지 않는 순수 함수형 코드라면 문제가 없을 것입니다. 하지만 이것은 루비이기 때문에 그럴 가능성이 적습니다 :)
크론 작업 수동으로 트리거하기
/admin/background_jobs
를 방문하여 인스턴스에서 예약/실행/보류 중인 작업을 살펴볼 수 있습니다.
UI에서 “즉시 대기열에 넣기” 버튼을 선택하여 크론 작업을 트리거할 수 있습니다. 프로그래밍 방식으로 크론 작업을 트리거하려면 먼저 Rails 콘솔을 엽니다.
테스트하려는 크론 작업을 찾으려면:
job = Sidekiq::Cron::Job.find('job-name')
# 작업 상태 가져오기:
job.status
# 지금 바로 작업 대기열에 넣기!
job.enque!
예를 들어, 저장소 미러를 업데이트하는 update_all_mirrors_worker
크론 작업을 트리거하려면:
irb(main):001:0> job = Sidekiq::Cron::Job.find('update_all_mirrors_worker')
=>
#<Sidekiq::Cron::Job:0x00007f147f84a1d0
...
irb(main):002:0> job.status
=> "enabled"
irb(main):003:0> job.enque!
=> 257
사용 가능한 작업 목록은 workers 디렉토리에서 찾을 수 있습니다.
Sidekiq 작업에 대한 자세한 정보는 Sidekiq-cron 문서를 참조하십시오.
크론 작업 비활성화
관리자 영역의 모니터링 섹션을 방문하여 Sidekiq 크론 작업을 비활성화할 수 있습니다. 또한 명령줄 및 Rails Runner를 사용하여 동일한 작업을 수행할 수도 있습니다.
모든 크론 작업을 비활성화하려면:
sudo gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:disable!)'
모든 크론 작업을 활성화하려면:
sudo gitlab-rails runner 'Sidekiq::Cron::Job.all.map(&:enable!)'
한 번에 일부 작업만 활성화하려는 경우 이름 일치를 사용할 수 있습니다. 예를 들어, 이름에 geo
가 포함된 작업만 활성화하려면:
sudo gitlab-rails runner 'Sidekiq::Cron::Job.all.select{ |j| j.name.match("geo") }.map(&:disable!)'
Sidekiq 작업 중복성 Idempotency 키 지우기
가끔 기대했던 작업(예: 크론 작업)이 전혀 실행되지 않은 것처럼 보입니다. 로그를 확인할 때 “job_status”: “deduplicated”로 표시된 작업이 실행되지 않은 경우가 있을 수 있습니다.
이는 작업이 실패하고 idempotency 키가 제대로 지워지지 않은 경우 발생할 수 있습니다. 예를 들어, Sidekiq를 중지하면 25초 후에 남아있는 작업이 모두 제거됩니다.
기본적으로 키는 6시간 후에 만료되지만,
즉시 idempotency 키를 지우려면 다음 단계를 따르십시오(제공된 예제는 Geo::VerificationBatchWorker
에 대한 것입니다):
-
Sidekiq 로그에서 작업의 worker 클래스 및
args
를 찾습니다:{ ... "class":"Geo::VerificationBatchWorker","args":["container_repository"] ... }
- Rails 콘솔 세션을 시작합니다.
-
다음 스니펫을 실행합니다:
worker_class = Geo::VerificationBatchWorker args = ["container_repository"] dj = Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob.new({ 'class' => worker_class.name, 'args' => args }, worker_class.queue) dj.send(:idempotency_key) dj.delete!
Sidekiq BRPOP 호출에 의한 Redis CPU 포화
Sidekiq BROP
호출은 Redis의 CPU 사용량 증가를 유발할 수 있습니다.
Redis의 CPU 사용량을 개선하려면 SIDEKIQ_SEMI_RELIABLE_FETCH_TIMEOUT
환경 변수를 늘리십시오.
오류: OpenSSL::Cipher::CipherError
다음과 같은 오류 메시지를 받는 경우:
"OpenSSL::Cipher::CipherError","exception.message":"","exception.backtrace":["encryptor (3.0.0) lib/encryptor.rb:98:in `final'","encryptor (3.0.0) lib/encryptor.rb:98:in `crypt'","encryptor (3.0.0) lib/encryptor.rb:49:in `decrypt'"
이 오류는 프로세스가 GitLab 데이터베이스에 저장된 암호화된 데이터를 해독할 수 없는 것을 의미합니다. 이는 /etc/gitlab/gitlab-secrets.json
파일에 문제가 있음을 나타내므로 기본 GitLab 노드에서 파일을 Sidekiq 노드로 복사했는지 확인하십시오.