aws xray通过设置采样规则对请求进行过滤

参考资料

初始化环境

复制代码
npm init -y
npm install aws-xray-sdk
npm intall aws-sdk
npm install express

使用nodejs结合express的server来测试此配置,代码如下

js 复制代码
// app.js
var AWSXRay = require('aws-xray-sdk');
// xray将aws sdk包装
var AWS = AWSXRay.captureAWS(require('aws-sdk'));
// var AWS = require('aws-sdk');

// AWSXRay.config([AWSXRay.plugins.EC2Plugin, AWSXRay.plugins.ElasticBeanstalkPlugin]);
AWS.config.update({ region: 'cn-north-1' });

// 指定xray守护进程监听地址
AWSXRay.setDaemonAddress('127.0.0.1:2000');

const express = require('express')
const app = express()
const port = 3000

app.use(AWSXRay.express.openSegment('TestPathApp'));

app.get('/', (req, res) => {
    var document = AWSXRay.getSegment();
    // 添加注释和元数据
    document.addAnnotation("mykey", "my value");
    document.addMetadata("my key", "my value", "my namespace");
    res.send('Hello World!')
    var s3 = new AWS.S3();
    var params = {};
    s3.listBuckets(params, function (err, data) {
        if (err) console.log(err, err.stack);
        else console.log(data);
    });
})

app.get('/testpath', (req, res) => {
    res.send('test path!')
})

app.use(AWSXRay.express.closeSegment());

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

运行服务器

复制代码
node main.js

配置采样规则的参考文档

https://docs.aws.amazon.com/zh_cn/xray/latest/devguide/xray-console-sampling.html

适用于 Node.js 的 X-Ray 配置

采样规则的配置方式

xray在ec2平台上配置xray采样规则,可以控制使用xray-sdk的服务器行为

在service侧设置采样规则的目的在于,不修改或重新部署代码的情况下修改采样行为,控制记录的数据量。

默认的采样规则

  • 每秒记录首次请求
  • 任何其他请求的5%

采样规则的配置方式

  • 在sdk中配置从json中读取采样规则(存在的问题有,每个实例使用单独的采样规则可能导致请求数量变高,更新采样规则需要重新运行代码)

    本地定义规则的缺点,固定目标由记录器的每个实例独立应用,而不是由 X-Ray 服务管理。随着部署更多主机,固定速率会成倍增加,这使得控制记录的数据量变得更加困难

  • 在控制台创建采样规则,并在sdk中配置读取xray服务中定义好的采样规则(不需要重新部署代码,请求数量不会额外升高)

    X-Ray SDK 需要额外配置才能使用您在控制台中配置的采样规则。

    如果 SDK 无法访问 X-Ray 获取采样规则,它将恢复为每秒第一个请求的默认本地规则(1,5%)

采样规则的内容

默认的规则如下

  • 每秒采样1个,固定比率为5%
  • 匹配所有的满足要求的规则*

设置采样名称和优先级

设置采样限制

  • reservoir,每秒钟请求的采样数量
  • fixed rate,超出reservoir之后,对额外请求的百分比
  • 举例,存储器容量为50,百分比为10%,如果总体请求为100,则每秒钟的采样数量为50+(100-50)*10%=55

设置采样标准

选择面向服务的条件,以确定要匹配的请求。值可以包括多字符匹配通配符(*)或单字符匹配通配符(?)

我们创建的服务器接受请求后,向xray发送的数据的原始raw data(先将ec2的插件关闭)如下

json 复制代码
{
    "Id": "1-645b3731-14c36c71cafd66c95e9ce301",
    "Duration": 0.001,
    "LimitExceeded": false,
    "Segments": [
        {
            "Id": "36cdc1612a565cbf",
            "Document": {
                "id": "36cdc1612a565cbf",
                "name": "TestPathApp",
                "start_time": 1683699504.526,
                "trace_id": "1-645b3731-14c36c71cafd66c95e9ce301",
                "end_time": 1683699504.527,
                "http": {
                    "request": {
                        "url": "http://127.0.0.1:3000/testpath",
                        "method": "GET",
                        "user_agent": "curl/7.88.1",
                        "client_ip": "::ffff:127.0.0.1"
                    },
                    "response": {
                        "status": 200
                    }
                },
                "aws": {
                    "xray": {
                        "package": "aws-xray-sdk",
                        "rule_name": "Default",
                        "sdk_version": "3.5.0",
                        "sdk": "X-Ray for Node.js"
                    }
                },
                "service": {
                    "name": "unknown",
                    "version": "unknown",
                    "runtime": "node",
                    "runtime_version": "v16.15.0"
                }
            }
        }
    ]
}

在控制台配置采样规则

其中代码中的TestPathApp就是服务名称

复制代码
app.use(AWSXRay.express.openSegment('TestPathApp'));

在sdk配置采样规则

创建规则json文件

json 复制代码
cat sampling-rules.json
{
  "version": 2,
  "rules": [
    {
      "description": "Player moves.",
      "host": "*",
      "http_method": "*",
      "url_path": "/api/move/*",
      "fixed_target": 1,
      "rate": 0.05
    }
  ],
  "default": {
    "fixed_target": 1,
    "rate": 0.1
  }
}

在sdk中引用即可

js 复制代码
// AWSXRay.middleware.setSamplingRules('sampling-rules.json');
AWSXRay.setDaemonAddress('127.0.0.1:2000');
var rules = {
    "rules": [
        {
            "description": "Player moves.",
            "service_name": "*",
            "http_method": "*",
            "url_path": "/api/move/*",
            "fixed_target": 1,
            "rate": 0.05
        }
    ],
    "default": {
        "fixed_target": 0,
        "rate": 0.1
    },
    "version": 1
}

我们重新启动server,并监控xray守护进程的日志

js 复制代码
var logger = {
    error: (message, meta) => { console.log(message, meta); },
    warn: (message, meta) => { console.log(message, meta); },
    info: (message, meta) => { console.log(message, meta); },
    debug: (message, meta) => { console.log(message, meta); }
}

AWSXRay.setLogger(logger);

当请求/testpath时,日志如下

  • 由于没有匹配的centralized sampling rule,因此使用了本地采样方法
  • segment的元数据
shell 复制代码
No effective centralized sampling rule match. Fallback to local rules. undefined
Local sampling rule match found for { http_method: GET, host: 127.0.0.1:3000, url_path: /testpath }. Matched { http_method: *, host: *, url_path: /testpath }. Using fixed_target: 1 and rate: 0.05. undefined

Starting middleware segment: { url: /testpath, name: TestPathApp, trace_id: 1-645b4739-390fcc9ee953490557b0b920, id: dac471632ef967d6, sampled: true } undefined
Closed middleware segment successfully: { url: /testpath, name: TestPathApp, trace_id: 1-645b4739-390fcc9ee953490557b0b920, id: dac471632ef967d6, sampled: true } undefined

Segment sent: {"trace_id:"1-645b4739-390fcc9ee953490557b0b920","id":"dac471632ef967d6"} undefined
UDP message sent: {"trace_id":"1-645b4739-390fcc9ee953490557b0b920","id":"dac471632ef967d6","start_time":1683703609.304,"name":"TestPathApp","service":{"runtime":"node","runtime_version":"v16.15.0","version":"unknown","name":"unknown"},"aws":{"xray":{"sdk":"X-Ray for Node.js","sdk_version":"3.5.0","package":"aws-xray-sdk"}},"http":{"request":{"method":"GET","user_agent":"curl/7.88.1","client_ip":"::ffff:127.0.0.1","url":"http://127.0.0.1:3000/testpath"},"response":{"status":200}},"end_time":1683703609.328} undefined
Successfully refreshed centralized sampling rule cache. undefined

但请求/时,日志如下

复制代码
Rule Default is matched. undefined

Starting middleware segment: { url: /, name: TestPathApp, trace_id: 1-645b477b-ba767934aabd33cbda7c5455, id: a54f43f3efcd4f89, sampled: false } undefined
Closed middleware segment successfully: { url: /, name: TestPathApp, trace_id: 1-645b477b-ba767934aabd33cbda7c5455, id: a54f43f3efcd4f89, sampled: false } undefined

Successfully reported rule statistics to get new sampling quota. undefined

可见,由于采样规则的设置,我们成功控制了数据收集量,避免额外的开销(例如lb健康检查的请求)

相关推荐
AWS官方合作商2 天前
AWS S3企业级部署解决方案:从入门到高可用性实践
微服务·云计算·aws
亚林瓜子2 天前
AWS Elastic Beanstalk的部署Python Flask后端服务(Hello,World)
python·flask·aws·eb
weixin_307779132 天前
实现AWS Step Function安全地请求企业内部API返回数据
开发语言·python·云计算·aws
日月星辰Ace2 天前
基于 AWS DynamoDB 分布式锁
分布式·aws
日月星辰Ace2 天前
AWS EC2 Launch template
aws
AWS官方合作商2 天前
万物互联时代,AWS IoT Core如何构建企业级物联网中枢平台?
物联网·云计算·aws
lisw053 天前
云计算(Cloud Computing)概述——从AWS开始
云计算·aws
运维开发王义杰3 天前
解决 AWS RDS MySQL mysqldump 导入sql SET @@GLOBAL 权限不足问题
sql·mysql·aws
在云上(oncloudai)4 天前
DeepSeek-R3、GPT-4o 与 Claude-3.5-Sonnet 全面对比:性能、应用场景与技术解析
claude·aws·gpt-4o·deepseek-r3
xybDIY4 天前
【Amazon 工具】在MacOS本地安装 AWS CLI、kubectl、eksctl工具
macos·云计算·aws