You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从AWS Lambda调用EC2上的gRPC服务?问题排查求助

Lambda部署后无法调用EC2上的gRPC服务问题排查与解决方案

我来帮你一步步拆解这个问题,你遇到的是几个Lambda+gRPC+VPC场景下的典型坑,咱们逐个解决:

1. 最核心的问题:Lambda异步回调未被执行

你的sendMessage是async函数,但调用grpcClient.utterQuery用的是回调模式——Lambda会在你return语句执行后立刻终止进程,根本等不到gRPC的回调完成。这就是为什么你看不到回调里的日志,返回始终是默认的reply。

解决方案:把gRPC回调包装成Promise

修改Lambda代码,将回调式的gRPC调用转为Promise,让Lambda等待请求完成后再返回:

'use strict';
const AWS = require('aws-sdk');
const grpcClient = require('./grpcClient');

// 将gRPC回调包装为Promise
const utterQueryPromise = (params) => {
  return new Promise((resolve, reject) => {
    grpcClient.utterQuery(params, (error, riaReply) => {
      if (error) reject(error);
      else resolve(riaReply);
    });
  });
};

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!';
  
  try {
    // 等待gRPC请求完成
    const riaReply = await utterQueryPromise({ 
      query: message, 
      user_id: 10101, 
      session_id: 321 
    });
    console.log('successfully queried grpc service.')
    console.log(riaReply.response);
    reply = riaReply.response; // 可以把gRPC的返回作为接口响应返回
  } catch (error) {
    console.error('gRPC调用失败:', error);
    reply = `调用失败: ${error.message}`;
  }

  return {
    statusCode: 200,
    body: JSON.stringify(reply) // Lambda返回的body必须是字符串,注意转JSON
  };
};

2. VPC配置引发的权限与网络问题

你添加VPC后出现的EACCES: permission denied,以及后续无日志但请求无响应,都和VPC的权限、网络连通性有关:

(1)Lambda的IAM角色权限

确保你的Lambda执行角色拥有AWSLambdaVPCAccessExecutionRole托管权限——它允许Lambda在VPC内创建弹性网卡、访问子网等必要资源。没有这个权限的话,Lambda无法完成初始化,会出现无法读取handler.js的权限错误。

(2)安全组的连通性配置

  • Lambda的安全组:需要允许**出站(Outbound)**流量到gRPC服务的监听端口(比如默认的50051),协议选TCP。
  • gRPC服务所在EC2的安全组:需要允许**入站(Inbound)**流量来自Lambda的安全组,端口对应gRPC服务的监听端口。

如果gRPC服务和Lambda在同一个VPC,建议用EC2的私有IP访问,避免公网网络波动。

(3)子网的网络可达性

  • 如果Lambda部署在私有子网(无公网IP),而gRPC服务在公网,需要给私有子网配置NAT网关,否则Lambda无法访问外部网络。
  • 如果gRPC服务在另一个VPC,需要配置VPC对等连接,确保两个VPC的子网能互相访问。

3. gRPC依赖的编译验证

虽然你添加了postinstall脚本,但还是要确认部署到Lambda的grpc依赖是正确编译的:

  • 本地执行npm install后,检查node_modules/grpc目录下的二进制文件是否是针对linux-x64-glibc的(可通过文件名标识判断)。
  • 也可以用serverless package命令打包后,解压查看包里的grpc依赖,避免本地环境(如Mac/Windows)的二进制文件被错误打包。

最后一步:测试与日志排查

修改代码和配置后重新部署,然后:

  1. 查看CloudWatch完整日志,确认是否有gRPC请求的日志或错误信息。
  2. 用Postman/curl测试API网关的sendMessage接口,验证返回内容是否为gRPC服务的响应。

内容的提问来源于stack exchange,提问作者24x7Programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:14:42