테스트 GitLab 인스턴스에서 혼돈 발생

Werner Vogels는 아마존 웹 서비스의 CTO로 유명하게 말했습니다. 모든 것은 항상 실패합니다.

개발자로서, 소프트웨어가 일반 작동뿐만 아니라 동작하는 실패 모드를 고려하는 것이 중요합니다. 이렇게 함으로써 소수의 사용자 중 작은 일시적 에러가 발생하여 500에러가 발생하는 경우와 모든 사용자에게 영향을 미치는 전체 사이트 중단 사이의 차이가 날 수 있습니다.

Tolstoy를 para사하자면, 모든 행복한 서버는 비슷하지만, 실패하는 서버는 각각의 방식으로 실패합니다. 다행히도, 이러한 실패 모드를 시도할 수 있는 방법이 있으며, 혼돈 엔드포인트는 이 프로세스를 돕기 위한 도구입니다.

현재 다음과 같은 조건을 모방하는 네 가지 엔드포인트가 있습니다.

  • 느린 요청.
  • CPU 바운드 요청.
  • 메모리 누수.
  • 예기치 않은 프로세스 충돌.

혼돈 엔드포인트 활성화

명백한 이유로 이러한 엔드포인트는 production에서 기본적으로 활성화되어 있지 않습니다. 개발 환경에서는 기본적으로 활성화됩니다.

caution
혼돈 엔드포인트에 대한 액세스를 비밀 토큰을 사용하여 보안해야 합니다. 앱이 어떻게 동작하는지 정확히 알지 못한다면 production에 활성화해서는 안됩니다.

비밀 토큰은 GITLAB_CHAOS_SECRET 환경 변수를 통해 설정할 수 있습니다. 예를 들어, GDK를 사용할 때 다음 명령을 사용하여 설정할 수 있습니다.

GITLAB_CHAOS_SECRET=secret gdk start

secret를 자신의 비밀 토큰으로 바꿉니다.

혼돈 호출

혼돈 엔드포인트를 활성화하고 응용 프로그램을 다시 시작한 후 엔드포인트를 사용하여 테스트할 수 있습니다.

기본적으로 혼돈 엔드포인트를 호출할 때, 요청을 받는 웹 워커 프로세스에서 처리합니다. 이는 예를 들어, Kill 작업을 호출하는 경우, 해당 요청을 처리하는 Puma 워커 프로세스가 종료됩니다. 이러한 작업을 Sidekiq에서 테스트하려면 각 엔드포인트의 async 파라미터를 true로 설정할 수 있습니다. 이렇게 하면 Sidekiq 워커에서 혼돈 프로세스가 실행됩니다.

메모리 누수

응용 프로그램에서 메모리 누수를 모방하려면 /-/chaos/leakmem 엔드포인트를 사용합니다.

요청이 완료된 후 메모리는 유지되지 않습니다. 요청이 완료된 후 Ruby 가비지 수집기는 메모리를 회수하려고 시도합니다.

GET /-/chaos/leakmem
GET /-/chaos/leakmem?memory_mb=1024
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50&async=true
속성 유형 필수 설명
memory_mb integer 아니오 유출될 메모리 용량(MB). 기본값은 100MB입니다.
duration_s integer 아니오 메모리가 보존되어야 하는 최소 기간(초). 기본값은 30초입니다.
async boolean 아니오 Sidekiq 백그라운드 워커 프로세스에서 메모리 누수를 실행하도록 true로 설정합니다.
curl "http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10&token=secret"

CPU spin

이 엔드포인트는 주어진 기간 동안 단일 코어를 100%로 완전히 사용하려고 시도합니다.

라크 서버 설정에 따라 요청이 사전에 지정된 기간(일반적으로 60초) 이후에 제한될 수 있습니다.

GET /-/chaos/cpu_spin
GET /-/chaos/cpu_spin?duration_s=50
GET /-/chaos/cpu_spin?duration_s=50&async=true
속성 유형 필수 설명
duration_s integer 아니오 코어가 사용되는 기간(초). 기본값은 30초입니다.
async boolean 아니오 Sidekiq 백그라운드 워커 프로세스에서 CPU 사용하도록 true로 설정합니다.
curl "http://localhost:3000/-/chaos/cpu_spin?duration_s=60" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/cpu_spin?duration_s=60&token=secret"

DB spin

이 엔드포인트는 주어진 기간 동안 단일 코어를 완전히 사용하고 DB 요청과 교차로 사용하려고 시도합니다. 이 엔드포인트는 동시에 실행될 때 다른 스레드에 실행을 양보하는 모델링에 사용할 수 있습니다.

라크 서버 설정에 따라 요청이 사전에 지정된 기간(일반적으로 60초) 이후에 제한될 수 있습니다.

GET /-/chaos/db_spin
GET /-/chaos/db_spin?duration_s=50
GET /-/chaos/db_spin?duration_s=50&async=true
속성 유형 필수 설명
interval_s float 아니오 각 DB 요청 간의 간격(초). 기본값은 1초입니다.
duration_s integer 아니오 코어가 사용되는 기간(초). 기본값은 30초입니다.
async boolean 아니오 Sidekiq 백그라운드 워커 프로세스에서 작업을 수행하도록 true로 설정합니다.
curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60&token=secret"

Sleep

이 엔드포인트는 CPU Spin 엔드포인트와 유사하지만, 네트워크 서비스로의 네트워크 호출과 같은 오프 프로세서 활동을 모방합니다. 지정된 duration_s만큼 sleep합니다.

CPU Spin 엔드포인트와 마찬가지로, 구성된 제한을 초과하는 경우 요청 시간 초과로 이어질 수 있습니다.

GET /-/chaos/sleep
GET /-/chaos/sleep?duration_s=50
GET /-/chaos/sleep?duration_s=50&async=true
속성 유형 필수 설명
duration_s integer 아니오 요청이 sleep하는 기간(초). 기본값은 30초입니다.
async boolean 아니오 Sidekiq 백그라운드 워커 프로세스에서 sleep하도록 true로 설정합니다.
curl "http://localhost:3000/-/chaos/sleep?duration_s=60" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/sleep?duration_s=60&token=secret"

Kill

이 엔드포인트는 KILL 시그널을 사용하여 워커 프로세스의 예기치 못한 종료를 모방합니다.

이 엔드포인트는 KILL 시그널을 사용하기 때문에, 프로세스가 정리되거나 종료되도록 기회를 주지 않습니다.

GET /-/chaos/kill
GET /-/chaos/kill?async=true
속성 유형 필수 설명
async boolean 아니오 Sidekiq 백그라운드 워커 프로세스에 시그널을 보내도록 true로 설정합니다.
curl "http://localhost:3000/-/chaos/kill" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/kill?token=secret"

종료

이 엔드포인트는 QUIT 시그널을 사용하여 워커 프로세스의 예기치 않은 종료를 시뮬레이션합니다. KILL과 달리, QUIT 시그널은 코어 덤프를 작성하려고 시도합니다. 자세한 내용은 core(5)를 참조하세요.

GET /-/chaos/quit
GET /-/chaos/quit?async=true
속성 타입 필수 여부 설명
async boolean 아니오 Sidekiq 백그라운드 워커 프로세스에 시그널을 보내려면 true로 설정합니다.
curl "http://localhost:3000/-/chaos/quit" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/quit?token=secret"

가비지 수집기 실행

이 엔드포인트는 요청을 처리하는 워커에서 GC 실행을 트리거하고 해당 워커 ID와 GC 통계를 JSON 형식으로 반환합니다. 이것은 대부분 Puma를 독립 모드로 실행할 때 유용합니다. 그렇지 않으면 요청을 처리하는 워커를 미리 알 수 없기 때문입니다.

엔드포인트:

POST /-/chaos/gc

예시 요청:

curl --request POST "http://localhost:3000/-/chaos/gc" \
     --header 'X-Chaos-Secret: secret'
curl --request POST "http://localhost:3000/-/chaos/gc?token=secret"

예시 응답:

{
  "worker_id": "puma_1",
  "gc_stat": {
    "count": 94,
    "heap_allocated_pages": 9077,
    "heap_sorted_length": 9077,
    "heap_allocatable_pages": 0,
    "heap_available_slots": 3699720,
    "heap_live_slots": 2827510,
    "heap_free_slots": 872210,
    "heap_final_slots": 0,
    "heap_marked_slots": 2827509,
    "heap_eden_pages": 9077,
    "heap_tomb_pages": 0,
    "total_allocated_pages": 9077,
    "total_freed_pages": 0,
    "total_allocated_objects": 14229357,
    "total_freed_objects": 11401847,
    "malloc_increase_bytes": 8192,
    "malloc_increase_bytes_limit": 30949538,
    "minor_gc_count": 71,
    "major_gc_count": 23,
    "compact_count": 0,
    "remembered_wb_unprotected_objects": 41685,
    "remembered_wb_unprotected_objects_limit": 83370,
    "old_objects": 2617806,
    "old_objects_limit": 5235612,
    "oldmalloc_increase_bytes": 8192,
    "oldmalloc_increase_bytes_limit": 122713697
  }
}