【问题标题】:AWS XRAY SDK issue: Failed to begin subsegment named 'Amazon S3': segment cannot be foundAWS XRAY 开发工具包问题:无法开始名为“Amazon S3”的子段:找不到段
【发布时间】:2019-05-19 09:08:55
【问题描述】:

我们正在向 Spring Boot 应用程序添加 XRAY,但我无法解决以下错误:

Failed to begin subsegment named 'Amazon S3': segment cannot be found.

这是我们代码的相关部分:

pom.xml:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-core</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-spring</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
    <version>1.2.1</version>
</dependency> 

SpringApplication.java

@Bean
public Filter TracingFilter() {
    return new AWSXRayServletFilter("myService");
}

类调用 S3

@PostConstruct
public void runOnStartup(){
    String fileName = "myFileName";
    String bucketName = "myBucketName";

    amazonS3Client = AmazonS3ClientBuilder.standard()
        .withCredentials(new ProfileCredentialsProvider("MyCredentials"))
        .withClientConfiguration(getClientConfiguration())
        .withRegion(region)
        .build();

    Segment segment = AWSXRay.beginSegment("do-startup-operation");
    S3Object s3Object = amazonS3Client.getObject(bucketName, fileName);
    AWSXRay.endSegment();

    //Do stuff with S3Object
}

到目前为止我已经尝试过:

1) 我尝试过使用和不使用 sdk-aws-sdk-instrumentor 导入,在这样做时添加 TracingHandler 配置,如 this questionthis documentation. 中所述

.withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder()))

2) 我发现 this thread 似乎建议使用 AWSXRAY.createSegment(),但我不确定 lambda 中会发生什么或它是否与我的场景相关

我已阅读并发现相关的其他文档/代码: https://docs.aws.amazon.com/xray/latest/devguide/scorekeep-startup.html

https://docs.aws.amazon.com/xray/latest/devguide/scorekeep-sdkclients.html

https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-multithreading.html

https://docs.aws.amazon.com/xray/latest/devguide/scorekeep-workerthreads.html

https://github.com/aws/aws-xray-sdk-java/blob/master/aws-xray-recorder-sdk-core/src/main/java/com/amazonaws/xray/contexts/ThreadLocalSegmentContext.java#L23

附:我简化了我的代码并省略了一些错误处理,以使查看此问题的人更容易阅读

【问题讨论】:

    标签: amazon-web-services spring-boot amazon-s3 aws-sdk aws-xray


    【解决方案1】:

    更换后可以正常使用

    AWSXRay.getGlobalRecorder()
    

    Entity mySegment = AWSXRay.beginSegment("do-startup-operation");
    AWSXRay.getGlobalRecorder().setTraceEntity(mySegment);
    S3Object s3Object = amazonS3Client.getObject(bucketName, fileName);
    AWSXRay.endSegment();
    

    【讨论】:

      【解决方案2】:

      X-Ray servlet 过滤器将在收到请求时打开一个段,并在返回响应之前关闭它。它创建的段代表完整的请求/响应生命周期。作为服务该请求的一部分而捕获的任何内容(在这种情况下可能是一些 AWS 服务调用)都称为子段。如您所见,子段需要跟踪上下文(这是用于哪个段)。

      问题在于,在服务器启动时,instrumentor 尝试捕获 S3 调用,但由于还没有请求进入,因此无法找到上下文。一种选择是将环境变量AWS_XRAY_CONTEXT_MISSING 设置为LOG_ERROR,因此没有例外,只有一个日志条目。在https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-configuration.html#xray-sdk-java-configuration-envvars查看更多详情。

      为了在 lambda 上运行,lambda 容器将为每次调用创建一个段。它将跟踪上下文设置为环境变量。因此,只要捕获的代码在处理程序类中,上下文就应该始终存在。

      【讨论】:

        猜你喜欢
        • 2014-01-09
        • 1970-01-01
        • 2014-09-20
        • 2013-07-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-10
        • 1970-01-01
        • 2020-08-29
        相关资源
        最近更新 更多