“无法执行 HTTP 请求:连接到 <bucket-name>.s3.amazonaws.com:443 失败:连接超时

Ksh*_*rma 10 amazon-s3 amazon-web-services aws-sdk aws-lambda aws-java-sdk

我正在尝试用 java 编写一个连接到 S3 的 Lambda 函数,然后获取数据。

当我在本地运行它时,使用 main 函数它工作正常并返回结果。但是当我将其上传到 AWS lambda 并运行它时,我收到以下错误消息:

"errorMessage": "无法执行 HTTP 请求:连接到存储桶名称.s3.amazonaws.com:443 [存储桶名称.s3.amazonaws.com/52.217.1.172] 失败:连接超时", "errorType": “com.amazonaws.SdkClientException”,

我的 S3 存储桶是公开的。

我的 pom.xml:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.11.493</version>
</dependency>
    <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-core</artifactId>
    <version>1.1.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

我的请求处理程序:

public class LambdaRequestHandler implements RequestHandler<String, String> {
@Autowired
public ClaimSuffixNumberService csService;
    @Override
    public String handleRequest(String input, Context context) {
        if(csService == null) {
            csService = Application.getBean(ClaimSuffixNumberService.class);
        }
        String result= csService.readAndMakeCall("claimSuffix");
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的服务

public String getObject(String fileName) {
    System.out.println("Inside Get Object");
    try {
        BasicAWSCredentials awsCreds = new BasicAWSCredentials("access-key","secret-key");
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                                .withRegion(Regions.US_EAST_1)
                                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                                .build();
        System.out.println(s3Client);
        S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket-name, object-name));
        InputStream is = s3object.getObjectContent();
        String content = StreamUtils.copyToString(is, 
 StandardCharsets.UTF_8);
        return content;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public String readAndMakeCall(String fileName) {
    try {
        System.out.println("Reading for " + fileName);
        String content = getObject(fileName);
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        List<ClaimSuffixNumber> claimSuffixList = mapper.readValue(content, mapper.getTypeFactory().constructCollectionType(List.class, ClaimSuffixNumber.class));
        System.out.println(claimSuffixList.toString());
        for(ClaimSuffixNumber i: claimSuffixList) {
            System.out.println(i);
        }
        return claimSuffixList.toString();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return " ";
}
Run Code Online (Sandbox Code Playgroud)

小智 6

正如 Mario 所说,您的 Lambda 目前无法访问互联网。这很可能是由于您的 VPC 配置所致。我相信马里奥的回答是正确的。您可以设置 S3 VPC 终端节点。就我而言,由于我使用 SES 和 Lambda,因此您无法为 SES 设置端点,因此我使用 NAT 网关添加解决方法。(注意:NAT 网关没有免费套餐)

  • 进入 VPC 控制台,进入“子网”菜单,然后在您拥有 Lambda 函数的 VPC 中创建一个新子网。
  • 接下来,进入 NAT 网关菜单并创建一个 NAT 网关。选择一个可以访问 Internet 的子网(不是新的子网)并且位于同一 VPC 中。您可以通过转至子网菜单、选择子网并单击“路由表”选项卡来检查子网是否可以访问 Internet。如果它可以访问互联网,您应该会看到类似以下内容:
|---------------------|------------------|
|     Destination     |      Target      |
|---------------------|------------------|
|     0.0.0.0/0       |     igw-####     |
|---------------------|------------------|
Run Code Online (Sandbox Code Playgroud)
  • 接下来,转到“路由表”菜单并创建一个新的路由表。确保位于同一个 VPC 中。当您创建新路由时,默认情况下它会附带一条 Internet 网关路由,因此请单击“路由”选项卡并将该路由替换为指向 NAT 网关的新路由。它应该看起来像这样:
|---------------------|------------------|
|     Destination     |      Target      |
|---------------------|------------------|
|     0.0.0.0/0       |     nat-####     |
|---------------------|------------------|
Run Code Online (Sandbox Code Playgroud)
  • 接下来,转到“子网关联”选项卡并关联您刚刚创建的子网。
  • 最后,返回您的 Lambda 函数并将子网更改为您刚刚创建的子网。它现在应该可以访问互联网。如果您需要更高的可用性,您可以创建具有不同可用性区域的其他子网并重复相同的过程。

重申一下,NAT 网关没有免费套餐,因此请记住这一点。这是定价信息https://aws.amazon.com/vpc/pricing/


Har*_*var 0

检查分配给 lambda 的角色。有权访问 s3 读写权限的 Lambda 角色。

检查 lambda 角色策略。

检查分配给它的存储桶策略以及分配给存储桶的 Cors 配置。