S3AbortableInputStream :并非所有字节都从 S3ObjectInputStream 中读取,中止 HTTP 连接。仅读取 ObjectMetadata 时发出警告
S3AbortableInputStream : Not all bytes were read from the S3ObjectInputStream, aborting HTTP connection. Warning when reading only ObjectMetadata
我正在使用 <aws.java.sdk>1.11.637</aws.java.sdk>
和 Spring boot 2.1.4.RELEASE.
代码:这会导致 S3 警告(这里我必须从 S3Object 访问仅 getUserMetadata
而不是整个对象内容)
private Map<String, String> getUserHeaders(String key) throws IOException {
Map<String, String> userMetadata = new HashMap<>();
S3Object s3Object = null;
try {
s3Object = s3Client.getObject(new GetObjectRequest(bucketName, key));
userMetadata.putAll(s3Object.getObjectMetadata().getUserMetadata());
} finally {
if (s3Object != null) {
s3Object.close();
}
}
return userMetadata;
}
输出:每当s3Object.close();被调用,然后我在控制台上看到带有以下消息的警告
{"msg":"Not all bytes were read from the S3ObjectInputStream, aborting HTTP connection. This is likely an error and may result in sub-optimal behavior. Request only the bytes you need via a ranged GET or drain the input stream after use.","logger":"com.amazonaws.services.s3.internal.S3AbortableInputStream","level":"WARN","component":"demo-app"}
我对错误原因的调查:
我进一步检查了 https://github.com/aws/aws-sdk-java/blob/c788ca832287484c327c8b32c0e2b0090a74c23d/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/internal/S3AbortableInputStream.java#L173-L187,它说如果 _readAllBytes() 不是真的(在我的情况下使用 S3Object 只是为了 getUserMetadata 而不是整个流内容)那么总会有警告。
问题:
a) S3Object.close 如何导致调用 S3AbortableInputStream.close
因为我假设 S3Object.close https://github.com/aws/aws-sdk-java/blob/c788ca832287484c327c8b32c0e2b0090a74c23d/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/model/S3Object.java#L222 中的代码仅通过 is.close();
调用 SdkFilterInputStream.close
b) 当我只想使用 S3Object 读取元数据而不是整个对象内容时,我应该如何摆脱这些警告。
也许可以尝试使用此 API 函数,该函数旨在仅检索 S3 对象的元数据:
ObjectMetadata getObjectMetadata(GetObjectMetadataRequest getObjectMetadataRequest)
throws SdkClientException,
AmazonServiceException
因此将您的代码更改为:
ObjectMetadata s3ObjectMeta = null;
s3ObjectMeta = s3Client.getObjectMetadata(new GetObjectMetadataRequest(bucketName, key));
userMetadata.putAll(s3ObjectMeta.getUserMetadata());
我正在使用 <aws.java.sdk>1.11.637</aws.java.sdk>
和 Spring boot 2.1.4.RELEASE.
代码:这会导致 S3 警告(这里我必须从 S3Object 访问仅 getUserMetadata
而不是整个对象内容)
private Map<String, String> getUserHeaders(String key) throws IOException {
Map<String, String> userMetadata = new HashMap<>();
S3Object s3Object = null;
try {
s3Object = s3Client.getObject(new GetObjectRequest(bucketName, key));
userMetadata.putAll(s3Object.getObjectMetadata().getUserMetadata());
} finally {
if (s3Object != null) {
s3Object.close();
}
}
return userMetadata;
}
输出:每当s3Object.close();被调用,然后我在控制台上看到带有以下消息的警告
{"msg":"Not all bytes were read from the S3ObjectInputStream, aborting HTTP connection. This is likely an error and may result in sub-optimal behavior. Request only the bytes you need via a ranged GET or drain the input stream after use.","logger":"com.amazonaws.services.s3.internal.S3AbortableInputStream","level":"WARN","component":"demo-app"}
我对错误原因的调查:
我进一步检查了 https://github.com/aws/aws-sdk-java/blob/c788ca832287484c327c8b32c0e2b0090a74c23d/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/internal/S3AbortableInputStream.java#L173-L187,它说如果 _readAllBytes() 不是真的(在我的情况下使用 S3Object 只是为了 getUserMetadata 而不是整个流内容)那么总会有警告。
问题:
a) S3Object.close 如何导致调用 S3AbortableInputStream.close
因为我假设 S3Object.close https://github.com/aws/aws-sdk-java/blob/c788ca832287484c327c8b32c0e2b0090a74c23d/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/model/S3Object.java#L222 中的代码仅通过 is.close();
SdkFilterInputStream.close
b) 当我只想使用 S3Object 读取元数据而不是整个对象内容时,我应该如何摆脱这些警告。
也许可以尝试使用此 API 函数,该函数旨在仅检索 S3 对象的元数据:
ObjectMetadata getObjectMetadata(GetObjectMetadataRequest getObjectMetadataRequest)
throws SdkClientException,
AmazonServiceException
因此将您的代码更改为:
ObjectMetadata s3ObjectMeta = null;
s3ObjectMeta = s3Client.getObjectMetadata(new GetObjectMetadataRequest(bucketName, key));
userMetadata.putAll(s3ObjectMeta.getUserMetadata());