amazon-web-services - How to call a grpc service running on ec2 from aws lambda
问题描述
I have a grpc service, written in python, deployed on one EC2 instance. I have written a nodejs application and using the application, I am able to call the grpc service from my local machine, and also from another EC2 instance. However when I deployed the same application to Lambda (using serverless deployment), it is not able to call the same grpc service. I have added below line in the scripts section in the package.json so the code is able to deployed to lambda properly.
"postinstall": "npm rebuild grpc --target=12.x --target_arch=x64 --target_platform=linux --target_libc=glibc"
Initially the lambda was executing without any error, just that it was not calling the grpc service. After that I added VPC endpoint configuration in my serverless.yml file, it is returning Internal Server Error and logging error "EACCES: permission denied, open '/var/task/handler.js'" in cloudwatch.
Update: I updated the IAM roles, and now there is no error logged, but the lambda always respond "Go Serverless v1.0! Your function executed successfully!". None of the messages that I am trying to log in the callback to utterQuery method is logged in cloudwatch logs.
What could be wrong here.
Here is the serverless.yml file:
service: myservice
provider:
name: aws
runtime: nodejs12.x
vpc:
securityGroupIds:
- securityGroupid1
subnetIds:
- subnetId1
stage: dev
region: us-east-1
stackTags:
owner: me
functions:
sendMessage:
handler: handler.sendMessage
events:
- http:
path: sendMessage
method: post
Here is the lambda function code:
'use strict';
const AWS = require('aws-sdk');
const grpcClient = require('./grpcClient');
module.exports.sendMessage = async (event, context) => {
const timestamp = new Date().getTime();
console.log(event, timestamp);
console.log(event.body);
const message = event.body;
let reply = 'Go Serverless v1.0! Your function executed successfully!';
grpcClient.utterQuery({
query: message,
user_id: 10101,
session_id: 321
}, (error, riaReply) => {
if (error) {
console.error(error)
} else {
console.log('successfully queried grpc service.')
console.log(riaReply.response)
}
});
return {
statusCode: 200,
body: reply
};
};
解决方案
Since you're calling return
at the end of the handler, the lambda invocation is ending before the utterQuery()
call has a chance to complete and invoke is callback.
https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html suggests that instead you return a promise, and the node.js lambda runtime will know to wait for that promise to be fulfilled before ending the lambda.
推荐阅读
- bash - 0 在 bash 中是否意味着真的?!0 表示假?
- c - 使用命令行参数 (argc, argv) 的 C 计算器程序
- javascript - 检查输入字段是否已更改
- java - 如何在没有共享接口的情况下处理等效对象
- eclipse - 在 Eclipse 中使用 GitLab LFS
- json - 使用 jq 逗号分隔获取 json 输出重复我的输出
- javascript - getElementsByTagName 不适用于 DOM 方法 addEventListener
- python - Transonic 运行 python 代码而不是 pythran
- linq - 如何在 MVC 控制器 LINQ 中返回所有非 FirstOrDefault
- python - 给定一个字符串作为输入,编写一个python程序来打印所有乘客的票证