aws x-ray는 분산 애플리케이션을 추적해서 분석하는 서비스다. 하나의 클라이언트 요청이 응답하기까지 여러 서비스를 거치게 되는데 이런 분산 환경에서 각 서비스별로 걸리는 시간, 메타 정보를 모아 시각화해준다. 분산 환경에서 산발적인 요청을 하나로 연결하기 위해 X-Amzn-Trace-Id 추적 헤더를 포함한다. aws sdk는 이 추적 헤더를 추가해서 여러 segment를 하나의 trace로 관리한다.
최초 요청에 대해 하나의 trace가 생성되고, trace는 여러 개의 segment로 구성된다. 하나의 segment는 여러 개의 subsegment로 또 나뉠 수 있다. 위 서비스 맵에서 보이는 그래프가 segment, subsegment를 표현한다.
x-ray는 데이터 전송하는 데 사용되는 오버헤드를 최소화하기 위해 애플리케이션에서 직접 x-ray로 전달하지 않는다. x-ray로 데이터를 쌓는 작업은 x-ray daemon에서 하고, 이 daemon은 일정 양을 버퍼에 모은 후 전달한다. x-ray sdk는 udp로 daemon에게 던지기만 한다.
보통 인프라를 구성할 때 많은 aws 서비스를 사용하는 만큼 다양한 서비스들이 x-ray integration을 지원한다. segment 구성을 위한 정보 수집과 추적 헤더 관리, serverless 환경인 경우 daemon까지 해준다.
데이터 구성
Segment
{
"trace_id": "1-5eb02fa4-e1932281179b6e40bcfa5422",
"id": "160cb4921e8ede74",
"start_time": 1588604836.375,
"end_time": 1588604836.516,
"name": "example.com"
}
- trace_id: segment / subsegment를 연결하는 고유한 식별자, {version}-{16진수 unix time}-{16진수 24자리 식별자}
- id: 16진수 16자리 식별자
- start_time: 부동소수점 방식의 timestamp
- end_time: 부동소수점 방식의 timestamp
- in_progress: segment가 종료되지 않는 경우 end_time 대신 in_progress를 true로 지정.
- name: 서비스 이름
위 필수 속성 외에 아래 추가적인 속성이 있다.
- origin: 추적하는 대상의 리소스를 명시(AWS::ECS::Containre, Database::SQL 등)
- parent_id: downstream에서 연결을 위해 지정하는 upstream의 subsegment id. sdk는 X-Amzn-Trace-Id 헤더에 trace-id와 같이 parent-id도 넘긴다.
- metadata: 검색은 불가능한 key-value 데이터로 최대 64KB까지 가능하다.
- annotation: 검색이 가능한 key-value 데이터로 전체 데이터를 filtering, grouping 할 때 사용한다. api가 url path로 구분이 되지 않는 경우 annotation에 method 명을 추가하면 깔끔하게 정리할 수 있다.
- subsegments: 아래 따로 설명
subsegments
downstream 호출에 대한 정보 기록으로 subsegments는 또 다른 subsegments를 가질 수 있다.
segment와 마찬가지로 id, name, start_time, end_time(또는 in_progress), trace_id는 필수 값이다. 추가로 segment 정보와 따로 보낼 경우 부모 segment와의 연결고리가 필요하므로 parent_id도 필수 값이다
추가적인 필드도 segment와 비슷하다.
- metadata, annotation, subsegments
- namespace: aws sdk 호출이면 aws, 아니면 remote
- sql: url, user, sanitized_query 등 sql 상세 정보를 추가한다.
함수 단위 추적
x-ray로 전달되는 데이터를 보면 사실 꼭 분산 시스템에만 적용되는 건 아니다. 결국 x-ray가 참조하는 트레이스 정보는 json 데이터일 뿐이며 양식에 맞게 custom 하게 구현만 하면 뭐든 가능하다.
x-ray java sdk에서는 aop를 활용해서 손쉽게 subsegment를 추가할 수 있다. AbstractXRayInterceptor
를 상속받아 xrayEnabledClasses
함수를 구현하면 된다. 함수 내용을 구현할 필요 없이 추적하고자 하는 대상을 @Pointcut
으로 지정하기만 하면 된다.
@Aspect
@Component
public class XRayInspector extends AbstractXRayInterceptor {
@Override
@Pointcut("within(com.example.service..*)")
public void xrayEnabledClasses() {}
}
sampling
기본값으로 sdk는 매 초마다 최초 요청(reservoir)을 포함한 5% 샘플링해서 기록한다. 매 초의 최초 요청을 기록하기 때문에 모든 서버의 정보를 취합하면 샘플링 오차가 생긴다. 따라서 각 서버가 아닌 x-ray 서비스에서 규칙을 관리하고, sdk가 이 규칙을 참조하도록 하면 정상적으로 전체적인 샘플링을 할 수 있다.
또한 x-ray console에서 샘플링 규칙을 변경하면 자동으로 반영된다. sdk를 사용하는 서버를 재시작하지 않아도 된다. x-ray daemon이 알아서 규칙을 갱신하고 이에 맞게 추적 정보를 보내준다. 그래서 AWSXRayDaemonWriteAccess
policy를 보면 xray:GetSampling*
action도 들어있다.
비용
저장한 트레이스 크기와, 검색, 스캔에 비용이 부과된다. 트레이스 정보는 30일간 저장된다. 트레이스는 최대 500KB이다.
기본으로 제공되는 free tier는 다음과 같다.
- 매달 100,000개의 trace
- 매달 1,000,000개의 검색/스캔
free tier를 넘어가면 추가 요금이 발생한다.
- 5달러 / 1,000,000 트레이스
- 0.5달러 / 1,000,000 검색/스캔
'aws' 카테고리의 다른 글
AWS CodePipeline으로 CI/CD 구축하기 (0) | 2020.05.12 |
---|---|
AWS fargate 사용법 (0) | 2020.05.12 |
AWS API Gateway (0) | 2020.05.02 |
AWS Lambda (0) | 2020.04.27 |
AWS DynamoDB (0) | 2020.04.26 |
댓글