我正在尝试用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 " ";
}
答案 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网关没有免费层)
|---------------------|------------------|
| Destination | Target |
|---------------------|------------------|
| 0.0.0.0/0 | igw-#### |
|---------------------|------------------|
|---------------------|------------------|
| Destination | Target |
|---------------------|------------------|
| 0.0.0.0/0 | nat-#### |
|---------------------|------------------|
仅重申一下,NAT网关没有免费层,因此请记住这一点。这是定价信息https://aws.amazon.com/vpc/pricing/