테스트 GitLab 인스턴스에서 카오스 생성하기
GitLab v19.1Amazon Web Services의 CTO인 Werner Vogels가 유명하게 말했듯이, 모든 것은 언제나 실패합니다. 개발자로서, 소프트웨어가 일반적으로 동작하는 방식만큼이나 장애가 발생할 수 있는 상황을 함께 고려하는 것이 중요합니다.
Amazon Web Services의 CTO인 Werner Vogels가 유명하게 말했듯이, 모든 것은 언제나 실패합니다.
개발자로서, 소프트웨어가 일반적으로 동작하는 방식만큼이나 장애가 발생할 수 있는 상황을 함께 고려하는 것이 중요합니다. 이를 통해 소수의 사용자가 경험하는 몇 가지 500 오류로 끝나는 사소한 문제와, 모든 사용자에게 장시간 영향을 미치는 전체 서비스 중단 사이의 차이를 만들 수 있습니다.
Tolstoy를 인용하자면, 행복한 서버는 모두 비슷하지만, 실패하는 서버는 저마다 다른 방식으로 실패합니다. 다행히도 이러한 장애 상황을 시뮬레이션할 수 있는 방법이 있으며, 카오스 엔드포인트는 이 과정을 지원하는 도구입니다.
현재 다음 상황을 시뮬레이션하는 네 가지 엔드포인트가 있습니다:
-
느린 요청
-
CPU 바운드 요청
-
메모리 누수
-
예상치 못한 프로세스 충돌
카오스 엔드포인트 활성화#
명백한 이유로, 이 엔드포인트들은 production 환경에서는 기본적으로 비활성화되어 있습니다.
development 환경에서는 기본적으로 활성화되어 있습니다.
카오스 엔드포인트에 대한 접근을 시크릿 토큰으로 보호해야 합니다. 무엇을 하는지 정확히 알지 못하는 이상 프로덕션 환경에서는 활성화하지 않는 것이 좋습니다.
시크릿 토큰은 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). 기본값은 100 MB. |
| duration_s | integer | 아니오 | 메모리를 유지할 최소 시간(초). 기본값은 30초. |
| async | boolean | 아니오 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 메모리 누수를 발생시킴 |
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 스핀#
이 엔드포인트는 주어진 시간 동안 단일 코어를 100% 완전히 사용하려고 시도합니다.
rack 서버 설정에 따라 미리 정해진 시간(일반적으로 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 | 아니오 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 CPU를 소비함 |
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 스핀#
이 엔드포인트는 주어진 시간 동안 단일 코어를 완전히 사용하면서 DB 요청과 번갈아 실행하려고 시도합니다. 이 엔드포인트를 사용하여 동시 실행 시 다른 스레드로 실행을 양보하는 상황을 모델링할 수 있습니다.
rack 서버 설정에 따라 미리 정해진 시간(일반적으로 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 | 아니오 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 작업을 수행함 |
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"
슬립#
이 엔드포인트는 CPU 스핀 엔드포인트와 유사하지만, 백엔드 서비스에 대한 네트워크 호출과 같은 오프프로세서 활동을 시뮬레이션합니다. 지정된 duration_s 동안 슬립합니다.
CPU 스핀 엔드포인트와 마찬가지로, duration_s가 설정된 제한을 초과하면 요청이 타임아웃될 수 있습니다.
GET /-/chaos/sleep
GET /-/chaos/sleep?duration_s=50
GET /-/chaos/sleep?duration_s=50&async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| duration_s | integer | 아니오 | 요청이 슬립할 시간(초). 기본값은 30초 |
| async | boolean | 아니오 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에서 슬립함 |
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 | 아니오 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에 시그널을 보냄 |
curl "http://localhost:3000/-/chaos/kill" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/kill?token=secret"
Quit#
이 엔드포인트는 QUIT 시그널을 사용하여 워커 프로세스의 예상치 못한 종료를 시뮬레이션합니다.
KILL과 달리, QUIT 시그널은 코어 덤프 작성도 시도합니다.
자세한 내용은 core(5)를 참조하세요.
GET /-/chaos/quit
GET /-/chaos/quit?async=true
| 속성 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
| async | boolean | 아니오 | true로 설정하면 Sidekiq 백그라운드 워커 프로세스에 시그널을 보냄 |
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
}
}