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

时间:2019-02-08 08:29:16

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

我正在尝试用Java编写Lambda函数,该函数连接到S3,然后获取数据。

当我在本地运行它时,使用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 " ";
}

3 个答案:

答案 0 :(得分:0)

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

检查lambda角色策略。

检查分配给它的存储桶策略,并将Cors配置也存储到存储桶。

答案 1 :(得分:0)

基于错误,我认为您的lambda没有互联网。在Vpc中配置Lambda时,互联网连接中断。要恢复互联网访问,您应该: -在默认vpc中启动lambda(如果可能) -为自定义vpc设置s3 vpc端点(允许来自自定义vpc的应用程序访问s3,还可以配置其他端点;请检查价格,这仅适用于某些AWS服务) -设置NAT网关(请参阅价格,连接性不仅限于AWS服务)

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

答案 2 :(得分:0)

就像马里奥说的那样,您的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-####     |
|---------------------|------------------|
  • 接下来,转到“路由表”菜单并创建一个新的路由表。确保它在同一VPC中。创建新路由时,默认情况下,它带有Internet网关路由,因此,请单击“路由”选项卡,并替换该路由为指向NAT网关的新路由。它应该看起来像这样:
|---------------------|------------------|
|     Destination     |      Target      |
|---------------------|------------------|
|     0.0.0.0/0       |     nat-####     |
|---------------------|------------------|
  • 接下来,转到“子网关联”标签,并关联刚创建的子网。
  • 最后,返回到Lambda函数,并将子网更改为仅创建的子网。现在应该可以访问互联网了。如果您需要更多可用性,则可以创建具有不同可用性区域的其他子网,并重复相同的过程。

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