AWS X-Ray: From scratch to practical use

AWS X-Ray: From scratch to practical use

avatar

Phong Nguyen

2024.07.26

Bài blog này sẽ giới thiệu đến các bạn nội dụng khá chi tiết liên quan đến AWS X-Ray

Những thách thức về microservice

Điều tra nguyên nhân khi xảy ra sự cố

  • Trong rất nhiều trường hợp, mỗi microservice khác nhau thường do các Team khác nhau vận hành và sử dụng các stack công nghệ khác nhau, dẫn đến log bị phân tán và format cũng khác nhau.
  • Rất khó hiểu lỗi xảy ra ở đâu vì nhiều service khác nhau đang phụ thuộc vào nhau.

Khó phân tích performance

  • Do sự phụ thuộc giữa các service và thay đổi hàng ngày nên rất khó xác định service nào đang bị bottleneck

Giới thiệu AWS X-Ray

  • AWS X-Ray là dịch vụ phân tích hiệu suất và sự cố của các ứng dụng chạy trên AWS, Chẳng hạn như các ứng dụng được xây dựng bằng kiến ​​trúc microservices.

Kiểm tra trạng thái thực hiện request

  • Với AWS X-Ray, bạn có thể theo dõi luồng request và response của applicatiopn cũng như trực quan hóa các cuộc gọi giữa các service, latency, error, v.v.
  • Sự phụ thuộc giữa các microservice dễ dàng được hình dung.

Phát hiện sự cố application

  • Thu thập thông tin liên quan về cách ứng dụng của bạn đang chạy để xác định và khắc phục nguyên nhân gốc rễ của các vấn đề và lỗi về hiệu suất.

Cải thiện hiệu suất ứng dụng

  • Xem mối quan hệ giữa các dịch vụ và tài nguyên trong thời gian thực và xác định các điểm nghẽn như độ trễ tăng lên hoặc hiệu suất giảm. Từ đó cải thiện hiệu suất

Khái niệm trong AWS X-Ray

Segments

Dữ liệu hành vi. Compute resources chạy application logic và gửi những data về công việc của nó dưới dạng segments. Segments  này cung cấp resource's name, chi tiết về request và chi tiết về công việc đã thực hiện.

Ví dụ: khi một HTTP request đến ứng dụng của bạn, nó có thể ghi lại dữ liệu sau:

  • The host – hostname, alias or IP address
  • The request – method, client address, path, user agent
  • The response – status, content
  • The work done – start and end times, subsegments
  • Issues that occur – errors, faults and exceptions, including automatic capture of exception stacks.

Subsegments

  • Một Segments có thể chia dữ liệu về công việc được thực hiện thành các Subsegments.
  • Các Subsegments cung cấp thông tin chi tiết hơn về thời gian và chi tiết về các downstream calls (Ví dụ trên là các call đến DynamoDB hoặc S3) mà ứng dụng của bạn đã thực hiện để đáp ứng request ban đầu.

Traces

Một tập hợp các segments được tạo trong một request.

Câu hỏi là X-Ray quản lý các Traces (gồm nhiều segments) như thế nào?

  • Trace quản lý nhiều segments dựa vào TraceID. Mỗi segments sẽ có 1 TraceID.
  • TraceID là ID để theo dõi các reuqest và là duy nhất cho mỗi request. Về cơ bản, nó được tạo khi segment đầu tiên được tạo.

Quản lý các kết nối và thứ tự của các segment như thế nào?

  • Thứ tự của các segment được quản lý bằng segmentID.
  • SegmentID là duy nhất cho một segment trong trace. Root SegmentID xác định kết nối và thứ tự của các segment.

TraceID và SegmentID được truyền đi như thế nào?

  • TraceID và SegmentID cho từng Segment được truyền đi bởi trace header.
  • Trace Header là HTTP Header định nghĩa: TraceID (Root), Parrent Segment ID, Sampling Decision (Sampled)

Bạn có thể thêm thông tin vào segment để dễ tìm kiếm hơn. Các cặp key-values được lập Index để sử dụng trong Filter Expressions.

"aws:api_stage": "prod"

Metadada

Thêm thông tin vào các segment để debug và phân tích. Một cặp key-value có thể chứa các giá trị thuộc bất kỳ loại nào.

"game": {
  "id": "abcde",
  "session": "xxxyyyyzzz",
  ...
}

Sampling

  • AWS X-Ray xác định request nào được record theo sampling rule.
  • Default Sampling Rule
    • Request đầu tiên luôn được theo dõi mỗi giây
    • 5% tất cả các request tiếp theo sẽ được trace
  • Tại sao việc Sampling cần thiết?
    • Kiểm soát số tiền thanh toán (thanh toán dựa trên số lượng trace)
    • Ảnh hưởng đến hiệu suất ứng dụng

Cách thức hoạt động của việc thu thập dữ liệu AWS X-Ray

  1. Gửi dữ liệu segment được tạo bởi SDK AWS X-Ray được nhúng trong application của bạn tới daemon X-Ray
  2. X-Ray Deamon thực hiện buffer segment data và chuyển dữ liệu đó sang API X-Ray theo định kỳ.
  3. API X-Ray tạo trace từ dữ liệu phân đoạn được thu thập
  4. Trực quan hóa, phân tích và debug trace bằng AWS X-Ray Console

(Cũng có thể trao đổi dữ liệu trực tiếp với API X-Ray bằng AWS CLI, v.v. mà không cần sử dụng SDK X-Ray.)

Tận dụng AWS X-Ray

  • Để tận dụng AWS X-Ray, trước tiên hãy kết hợp X-Ray SDK vào ứng dụng của bạn.

  • SDK X-Ray hỗ trợ các ngôn ngữ như Java, .NET, Node.js, Python, Ruby và Go và có thể dễ dàng thêm vào code ứng dụng của bạn.

  • Bằng cách sử dụng X-Ray SDK, bạn có thể thêm metadata như TraceID và ID segment vào các request cũng như response mà ứng dụng của bạn gửi và nhận.

  • Các metadata này được thu thập bởi các tác nhân như X-Ray Daemon và gửi đến API X-Ray.

  • API X-Ray tạo thông tin trace dựa trên matadata đã nhận và làm cho nó có thể xem được bằng X-Ray Console, X-Ray CLI, v.v.

Lưu ý rằng nếu mục tiêu monitoring là EC2, bạn sẽ cần cài đặt X-Ray Agent và nếu bạn đang giám sát ECS, bạn sẽ cần cài đặt X-Ray Agent hoặc Docker Container.

Không cần cài đặt cho ElasticBeanstalk, Lambda hoặc API Gateway. Tuy nhiên cần Enable X-Ray trên những Service này.

Với AWS X-Ray, bạn có thể tận dụng các tính năng sau:

  • Service Map:

    Hiển thị đồ họa các thành phần ứng dụng và phụ thuộc. Mỗi nút hoặc cạnh hiển thị số liệu thống kê như số lượng request tỷ lệ lỗi và độ trễ.

  • Trace:

    Xem flow request và response riêng lẻ một cách chi tiết. Mỗi segment hoặc subsegment hiển thị thông tin như phía request, phía được request, thời gian xử lý và status code.

  • Alarm:

    Bạn có thể đặt cảnh báo dựa trên thông tin trace. Alarm có thể được tích hợp với CloudWatch để thông báo cho bạn và thực hiện hành động khi xảy ra tình trạng bất thường.

Lab Introduction

Tóm lại hiểu đơn giản AWS X-Ray là dịch vụ cho phép bạn hình dung thời gian xử lý cho từng thành phần và điều tra các điểm nghẽn.

Lý thuyết cũng còn khá lan man, để hiểu rõ hơn, chúng ra sẽ tiến hành bài demo sau.

Kiểm tra xem X-Ray trông như thế nào với ba cấu hình sau.

  1. API Gateway - Lambda
  2. API Gateway - Lambda(Không setting X-Ray) - DynamoDB
  3. API Gateway - Lambda(Có setting X-Ray) - DynamoDB

Architecture diagram

  • Enable X-Ray ở API gateway
  • Setting như bên dưới
    • Pattern 1: Resource /test01 GET, liên kết với lambda: cmp-lam-nonvpc-x-ray01. API send request đến lambda, lambda trả về kết quả đơn giản như "Hello World"
    • Pattern 2: Resource /test02 GET, liên kết với lambda: cmp-lam-nonvpc-x-ray02. API send request đến lambda, lambda thực hiện 1 request get đến DynamoDB
    • Pattern 3: Resource /test03 GET, liên kết với lambda: cmp-lam-nonvpc-x-ray03. Tương tự như Pattern 2 nhưng khác ở chỗ có Enable X-Ray cho Lambda

Các bước thực hiện

Create DynamoDB

  • Table name: cmp-dynamodb-userdb
  • Partition key: PhoneNumber

Add 1 Item:

  • PhoneNumber: 07012345678
  • Name (String): Phong Nguyen

Create Lambda Role

  • Role name: CMPLambdaCommonRole
  • Policy:
    • AmazonDynamoDBFullAccess
    • AWSLambdaBasicExecutionRole
    • AWSXRayDaemonWriteAccess

Create Lambda X-Ray Layer

Tải về file python.zip tại đây (đây chính là Layer chứa thư viện X-Ray và requests)

Tạo Lambda Layer

Create Lambda

Lambda: cmp-lam-nonvpc-x-ray01

  • Author from scratch
  • Basic information
    • Function name: cmp-lam-nonvpc-x-ray01
    • Runtime: Python 3.12
    • Architecture: x86_64
    • Execution role: Use an existing role -> CMPLambdaCommonRole
  • Code: Default

-------------

Lambda: cmp-lam-nonvpc-x-ray02

  • Author from scratch

  • Basic information

    • Function name: cmp-lam-nonvpc-x-ray02
    • Runtime: Python 3.12
    • Architecture: x86_64
    • Execution role: Use an existing role -> CMPLambdaCommonRole
  • Code:

    import json
    import boto3
    from boto3.dynamodb.conditions import Key
    
    def lambda_handler(event, context):
    
        # access dynamodb
        InputPhoneNumber = "07012345678"
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table("cmp-dynamodb-userdb")
        querydata = table.query(
          KeyConditionExpression = Key("PhoneNumber").eq(InputPhoneNumber)
        )
        if querydata["Count"] == 0:
            username = "unknown"
        else:
            username = querydata["Items"][0]["Name"]
        return {
            'statusCode': 200,
            'body' : username
        }
    
    

-------------

Lambda: cmp-lam-nonvpc-x-ray03

  • Author from scratch

  • Basic information

    • Function name: cmp-lam-nonvpc-x-ray02
    • Runtime: Python 3.12
    • Architecture: x86_64
    • Execution role: Use an existing role -> CMPLambdaCommonRole
  • Code:

    import json
    import layer
    import boto3
    from boto3.dynamodb.conditions import Key
    
    def lambda_handler(event, context):
    
        # access dynamodb
        InputPhoneNumber = "07012345678"
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table("cmp-dynamodb-userdb")
        querydata = table.query(
          KeyConditionExpression = Key("PhoneNumber").eq(InputPhoneNumber)
        )
        if querydata["Count"] == 0:
            username = "unknown"
        else:
            username = querydata["Items"][0]["Name"]
        return {
            'statusCode': 200,
            'body' : username
        }
    
    
  • X-Ray active tracing: Enable

  • Add layer: x-ray-layer

Create API gateway

  • REST API
  • New API
  • API name: cmp-api-test-xray
  • API endpoint type: Regional

Lần lượt tạo các resource và method:

  • /test01 -> GET -> lambda: cmp-lam-nonvpc-x-ray01
  • /test02 -> GET -> lambda: cmp-lam-nonvpc-x-ray02
  • /test03 -> GET -> lambda: cmp-lam-nonvpc-x-ray03

Deploy lên new stage: prod

Thực hiện Active X-Ray tracing

Test hoạt động

Lấy URL của API sau khi deploy và call lần lượt các API:

Pattern 1: API Gateway + Lambda chỉ trả về kết quả đơn giản "Hello from Lambda!"

Pattern 2: API Gateway + Lambda (Không setting X-Ray, Có xử lý DynamoDB). Lambda sẽ thực thi xử lý get data và trả về kết quả.

Pattern 3: API Gateway + Lambda (Có setting X-Ray, Có xử lý DynamoDB). Lambda sẽ thực thi xử lý get data và trả về kết quả. Đồng thời code trong Pattern 3 có thêm đoạn import layer cho phép liên kết với X-Ray

Confirm kết quả từ X-Ray

Tại màn hình Trace map, ta sẽ thấy các lệnh gọi API sẽ đi như thế nào. Mặc dù lambda cmp-lam-nonvpc-x-ray02 có xử lý liên quan đến get item từ DB nhưng không bật X-RAY nên thông tin liên quan đến DynamoDb không thể hiện, còn Lambda cmp-lam-nonvpc-x-ray03 có bật X-Ray nên đã hiển thị thông tin DynamoDB.

Click vào từng node có thể xem được độ trễ từng service:

Xem chi tiết từng trace

Pattern 1:

Pattern 2:

Pattern 3:

Giả sử change code lambda cmp-lam-nonvpc-x-ray03 gây ra lỗi.

Nhật xét:

  • Nếu bạn bật X-Ray ở phía gọi service, bạn có thể nhận thông tin đến cả những sevice mà lệnh gọi đó thực hiện. Ví dụ như bật X-Ray ở API gateway nên bạn nhận được thông tin thời gian thực hiện request ở Lambda. Tương tự như vậy, khi bạn bật X-Ray ở lambda, bạn biết được DynamoDB xử lý mất bao nhiêu thời gian.

Tài liệu Tham khảo: