【问题标题】:"Unable to execute HTTP request: Connect to <bucket-name>.s3.amazonaws.com:443 failed: connect timed out“无法执行 HTTP 请求:连接到 <bucket-name>.s3.amazonaws.com:443 失败:连接超时
【发布时间】:2023-04-08 12:32:01
【问题描述】:

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

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

"errorMessage": "无法执行 HTTP 请求:连接到 bucket-name.s3.amazonaws.com:443 [bucket-name.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>

我的请求处理程序:

public class LambdaRequestHandler implements RequestHandler<String, String>{

@Autowired
public ClaimSuffixNumberService csService;

@Override
public String handleRequest(String input, Context context) {
    // TODO Auto-generated method stub

    if(csService==null) {
        csService= Application.getBean(ClaimSuffixNumberService.class);
    }
    String result= csService.readAndMakeCall("claimSuffix");
    return result;
}



}

我的服务

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) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;
}





public String readAndMakeCall(String fileName) {
// TODO Auto-generated method stub
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) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
return " ";
}

【问题讨论】:

  • 你配置角色和桶策略了吗???
  • 什么最终奏效了?

标签: amazon-web-services amazon-s3 aws-lambda aws-sdk aws-java-sdk


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    根据错误,我认为您的 lambda 没有互联网。当你在 Vpc 中配置你的 lambda 时,你失去了互联网连接。要重新获得 Internet 访问权限,您应该: - 在默认 vpc 中启动 lambda(如果可能) - 为您的自定义 vpc 设置一个 s3 vpc 端点(允许来自您的自定义 vpc 的应用程序访问 s3,还有其他可以配置的端点;检查定价,这仅适用于某些 aws 服务) - 设置 NAT 网关(请参阅定价,连接不仅限于 aws 服务)

    无关,没有理由对 aws 凭据进行硬编码。应将所有必需的权限分配给您的执行角色。

    【讨论】:

      【解决方案3】:

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

      检查 lambda 角色政策。

      检查分配给它的存储桶策略和 Cors 配置到存储桶。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-21
        • 2023-02-17
        • 2017-07-28
        相关资源
        最近更新 更多