Rails 요청 SLI(서비스 수준 지표)
GitLab v19.1요청 Apdex SLI와 오류율 SLI는 애플리케이션에 정의된 SLI입니다. 요청 Apdex는 애플리케이션 성능 지표로서 성공한 요청의 처리 시간을 측정합니다. 오류율은 서버 오동작 지표로서 실패한 요청을 측정합니다. gitlab_sli_rails_request_apdex_total: 이 카운터는 5xx 상태 코드가 응답으로 반환되지 않은 모든 요청에 대해 증가합니다.
Rails 요청 SLI(서비스 수준 지표)#
이 SLI는 서비스 모니터링에 사용됩니다. 그러나 기본적으로 [스테이지 그룹의 오류 예산](/19.1/development/stage_group_observability/#error-budget)에는
사용되지 않습니다.
요청 Apdex SLI와 오류율 SLI는 애플리케이션에 정의된 SLI입니다.
요청 Apdex는 애플리케이션 성능 지표로서 성공한 요청의 처리 시간을 측정합니다. 여기에는 REST 및 GraphQL API와 일반 컨트롤러 엔드포인트가 포함됩니다.
오류율은 서버 오동작 지표로서 실패한 요청을 측정합니다. 여기에는 REST API와 일반 컨트롤러 엔드포인트가 포함됩니다.
-
gitlab_sli_rails_request_apdex_total: 이 카운터는5xx상태 코드가 응답으로 반환되지 않은 모든 요청에 대해 증가합니다. 느린 실패가 중복 계산되지 않도록 보장하며, 해당 요청은 오류 SLI에서 이미 집계됩니다. -
gitlab_sli_rails_request_apdex_success_total: 이 카운터는 엔드포인트 긴급도에 따라 정의된 목표 처리 시간보다 빠르게 처리된 모든 성공 요청에 대해 증가합니다. -
gitlab_sli_rails_request_error_total: 이 카운터는5xx상태 코드가 응답으로 반환된 모든 요청에 대해 증가합니다. -
gitlab_sli_rails_request_total: 이 카운터는 모든 요청에 대해 증가합니다.
이 카운터들은 다음 레이블로 구분됩니다:
-
endpoint_id: Rails 컨트롤러 또는 Grape API 엔드포인트의 식별자입니다. -
feature_category: 해당 컨트롤러 또는 API 엔드포인트에 지정된 기능 카테고리입니다.
요청 Apdex SLO#
이 카운터들은 성공 비율로 결합할 수 있습니다. 이 비율의 목표값은 서비스별 서비스 카탈로그에 정의되어 있습니다. 이 SLI가 SLO를 충족하려면, 기록된 비율이 다음보다 높아야 합니다:
예를 들어, 웹 서비스의 경우 최소 99.8%의 요청이 목표 처리 시간보다 빠르게 처리되어야 합니다.
이 목표값은 알림 및 서비스 모니터링에 사용됩니다. 알림이 발생하지 않도록 이 목표값을 고려하여 처리 시간을 설정하세요. 그러나 궁극적인 목표는 사용자를 만족시키는 목표 긴급도를 설정하는 것입니다.
성공한 측정값과 실패한 측정값 모두 스테이지 그룹의 오류 예산에 영향을 미칩니다.
요청 긴급도 조정#
모든 엔드포인트가 동일한 유형의 작업을 수행하는 것은 아니므로, 엔드포인트별로 서로 다른 긴급도 수준을 정의할 수 있습니다. 긴급도가 낮은 엔드포인트는 긴급도가 높은 엔드포인트보다 더 긴 요청 처리 시간을 가질 수 있습니다.
장시간 실행되는 요청은 인프라에 더 많은 비용을 유발합니다. 하나의 요청을 처리하는 동안 스레드는 해당 요청의 처리 시간 내내 점유 상태가 됩니다. 스레드는 다른 작업을 처리할 수 없습니다. Ruby의 Global VM Lock으로 인해 스레드가 락을 유지하여 동일한 Puma 워커 프로세스가 처리하는 다른 요청을 지연시킬 수 있습니다. 사실상 해당 요청은 동일 워커가 처리하는 다른 요청의 노이지 네이버가 됩니다. 이러한 이유로 목표 처리 시간의 상한을 5초로 제한합니다.
긴급도 낮추기 (목표 처리 시간 높이기)#
기존 엔드포인트의 긴급도를 개별 사례별로 낮출 수 있습니다. 다음 사항을 고려하세요:
Apdex는 체감 성능에 관한 것입니다. 사용자가 요청 결과를 적극적으로 기다리고 있다면, 5초를 기다리는 것은 허용되지 않을 수 있습니다. 그러나 엔드포인트가 대량의 데이터를 필요로 하는 자동화에 사용되는 경우라면, 5초는 허용 가능할 수 있습니다.
엔드포인트 사용 방식을 파악하는 데 프로덕트 매니저의 도움을 받을 수 있습니다.
일부 엔드포인트의 워크로드는 호출자가 지정한 파라미터에 따라 크게 달라지는 경우가 있습니다. 긴급도(urgency)는 이러한 차이를 수용할 수 있어야 합니다. 경우에 따라 엔드포인트가 수행하는 작업에 대해 별도의 애플리케이션 SLI를 정의할 수 있습니다.
특정 경우에 엔드포인트가 no-op으로 전환되어 매우 빠르게 처리될 때는, 타깃을 설정할 때 이러한 빠른 요청을 무시해야 합니다. 예를 들어, MergeRequests::DraftsController가 머지 리퀘스트를 볼 때마다 호출되지만 실제로 렌더링하는 경우가 드물다면, 엔드포인트가 실제 작업을 수행할 때도 수용할 수 있는 타깃을 선택해야 합니다.
엔드포인트가 소비하는 종속 리소스를 고려하세요. 엔드포인트가 Gitaly나 데이터베이스에서 대량의 데이터를 로드하여 성능이 만족스럽지 않다면, 긴급도를 낮춰 타깃 지속 시간을 늘리기보다는 데이터 로드 방식을 최적화하는 것을 고려하세요.
이러한 경우, 인프라에서 감당할 수 있다면 엔드포인트가 SLO를 충족하도록 일시적으로 긴급도를 낮추는 것이 적절할 수 있습니다. 그럴 때는 관련 이슈에 링크하는 코드 주석을 추가하세요.
엔드포인트가 CPU 시간을 많이 소비하는 경우에도 이를 고려해야 합니다. 이런 종류의 요청은 가능한 한 짧게 유지해야 하는 노이지 네이버(noisy neighbor)에 해당합니다.
트래픽 특성도 고려해야 합니다. 예를 들어 CI 트래픽이 같은 엔드포인트에 집중적으로 많은 job을 실행하는 것처럼, 엔드포인트로의 트래픽이 버스트(burst)하는 경우, 해당 엔드포인트가 5초씩 걸리는 것은 인프라 관점에서 허용할 수 없습니다. 일반 트래픽과 함께 들어오는 느린 요청을 수용하기 위해 플릿을 충분히 빠르게 확장할 수 없습니다.
기존 엔드포인트의 긴급도를 낮출 때는 머지 리퀘스트 리뷰에 Observability 팀원을 참여시키세요. 로그에서 제공되는 요청 속도(request rate)와 지속 시간(duration)을 활용해 권고안을 도출할 수 있습니다. 긴급도 높이기와 동일한 프로세스를 사용해 서비스 SLO보다 높은 지속 시간을 임계값으로 선택할 수 있습니다.
엔드포인트를 도입하는 머지 리퀘스트에서 가장 긴 지속 시간을 설정하는 것은 적절하지 않습니다. 이를 뒷받침할 데이터가 아직 없기 때문입니다.
긴급도 높이기 (더 낮은 타깃 지속 시간 설정)#
긴급도를 높일 때는 요청을 처리하는 플릿이 여전히 SLO를 충족하는지 확인해야 합니다. 로그의 정보를 사용해 다음을 확인할 수 있습니다:
Kibana에서 이 테이블을 엽니다.
테이블은 기본적으로 가장 바쁜 엔드포인트에 대한 정보를 로드합니다. 응답 속도를 높이려면 다음을 모두 추가하세요:
json.meta.caller_id.keyword에 대한 필터.
관심 있는 식별자를 입력합니다. 예:
Projects::RawController#show
또는:
GET /api/:version/projects/:id/snippets/:snippet_id/raw
엔드포인트를 처리하는 서비스에 대해 적절한 백분위수 지속 시간을 확인하세요. 전체 지속 시간은 의도한 타깃보다 낮아야 합니다.
전체 지속 시간이 의도한 타깃 미만이면, Kibana의 이 그래프에서 시간별 피크를 확인하세요. 여기서 해당 백분위수가 설정하려는 타깃 지속 시간을 초과해서 피크하지 않아야 합니다.
임계값을 너무 낮추면 Apdex 저하에 대한 알람이 발생할 수 있으므로, 머지 리퀘스트에 Observability 팀원도 참여시키세요.
긴급도 조정 방법#
엔드포인트에 기능 카테고리 지정과 유사한 방식으로 긴급도를 지정할 수 있습니다. 특정 타깃이 없는 엔드포인트는 기본 긴급도인 지속 시간 1초를 사용합니다. 사용 가능한 구성은 다음과 같습니다:
| 긴급도 | 지속 시간(초) | 비고 |
|---|---|---|
| :high | 0.25s | |
| :medium | 0.5s | |
| :default | 1s | 아무것도 지정하지 않을 때의 기본값입니다. |
| :low | 5s |
Rails 컨트롤러#
컨트롤러의 모든 액션에 긴급도를 지정할 수 있습니다:
class Boards::ListsController < ApplicationController
urgency :high
end
컨트롤러의 특정 액션에 대한 긴급도를 지정하려면 다음을 사용합니다:
class Boards::ListsController < ApplicationController
urgency :high, [:index, :show]
end
컨트롤러 스펙에서 엔드포인트의 요청 긴급도를 확인하는 커스텀 RSpec 매처를 사용할 수 있습니다:
specify do
expect(get(:index, params: request_params)).to have_request_urgency(:medium)
end
Grape 엔드포인트#
전체 API 클래스에 대한 긴급도를 지정하려면 다음을 사용합니다:
module API
class Issues < ::API::Base
urgency :low
end
end
API 클래스의 특정 액션에 대해서도 긴급도를 지정하려면 다음을 사용합니다:
module API
class Issues < ::API::Base
urgency :medium, [
'/groups/:id/issues',
'/groups/:id/issues_statistics'
]
end
end
또는 엔드포인트별로 긴급도를 지정할 수도 있습니다:
get 'client/features', urgency: :low do
# endpoint logic
end
커스텀 RSpec 매처는 Grape 엔드포인트 스펙과도 호환됩니다:
specify do
expect(get(api('/avatar'), params: { email: 'public@example.com' })).to have_request_urgency(:medium)
end
네임스페이스 레벨에서 긴급도를 지정할 수 없습니다. 그렇게 할 경우 디렉티브가 무시됩니다.
오류 예산 귀속 및 소유권#
이 SLI는 서비스 수준 모니터링에 사용됩니다. 이 SLI는 Stage 그룹의 오류 예산에 반영됩니다.
자세한 내용은 다음 에픽을 참조하세요: 커스텀 SLI 정의 및 오류 예산 통합). SLI에 포함된 엔드포인트는 해당 엔드포인트에 선언된 기능 카테고리를 기반으로 그룹의 오류 예산에 반영됩니다.
자신의 그룹에 포함된 엔드포인트를 확인하려면 그룹 대시보드에서 요청 속도를 확인할 수 있습니다. Budget Attribution 행의 Puma Apdex 로그 링크를 통해 1초 또는 5초 타깃을 충족하지 못하는 요청의 수를 확인할 수 있습니다.
대시보드 콘텐츠에 대한 자세한 내용은 Stage 그룹 대시보드를 참조하세요. 오류 예산 자체에 대한 탐색 내용은 이슈 1365를 참조하세요.