部署Node.js gRPC服务至Azure Web App遇CANCELLED错误求助
我在Node.js应用中同时搭建了Express.js服务器与gRPC服务器,服务器代码如下:
const server = getServer(); server.bindAsync( `0.0.0.0:${process.env.HTTP20_ONLY_PORT}`, grpc.ServerCredentials.createInsecure(), (err, port) => { if (err) { console.error(err); return; } console.log(`gRPC server started on port ${port}`); server.start(); } ); const getServer = () => { const server = new grpc.Server(); server.addService(dataCalculatorPackage.DataCalculatorService.service, { PerformanceDataByPlanAndForcesIds: getPerformanceDataByPlanIdAndForceIdByCall, } as DataCalculatorServiceHandlers); return server; };
gRPC服务器看起来已正常启动。我已在Azure中启用HTTP/2版本,并将HTTP 2.0代理设置为仅gRPC,同时添加了HTTP20_ONLY_PORT环境变量。
我的gRPC客户端基于Nest.js,通过Azure服务URL建立连接,代码如下:
const packageDef = loadSync(path.resolve(__dirname, PROTO_FILE), { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true, }); const grpcObj = loadPackageDefinition(packageDef) as unknown as ProtoGrpcType; this.grpcClient = new grpcObj.dataCalculatorPackage.DataCalculatorService( `azurewebsite.url.com`, credentials.createInsecure(), );
但调用请求时收到如下取消错误:
[ERROR] 29 - 02/19/2024, 10:34:35 AM ERROR [ExceptionsHandler] 1 CANCELLED: Call cancelled 2024-02-19T10:34:35.863451309Z: [ERROR] Error: 1 CANCELLED: Call cancelled ...
相同镜像在本地Docker中运行正常,求解决思路。
检查Azure端口映射与环境变量配置
确认HTTP20_ONLY_PORT环境变量在Azure应用服务的配置 -> 应用程序设置中正确配置,且该端口已在配置 -> 常规设置中指定为gRPC专用端口。同时验证服务器绑定的内部端口与Azure端口转发规则一致,确保外部请求能正确路由到gRPC服务器监听的端口。修正gRPC客户端连接配置
Azure应用服务默认强制HTTPS,即使服务器使用createInsecure(),前端会做SSL终止,客户端必须使用SSL连接。同时需指定443端口(Azure gRPC服务的默认端口):this.grpcClient = new grpcObj.dataCalculatorPackage.DataCalculatorService( `azurewebsite.url.com:443`, credentials.createSsl(), );验证Azure应用服务的gRPC专属配置
- 确认配置 -> 常规设置中已开启
HTTP/2,且HTTP20_ONLY_PORT值与服务器监听端口一致 - 检查网络 -> 访问限制,确保客户端IP未被拦截
- 通过Azure日志流查看服务器启动日志,确认是否输出
gRPC server started on port X,验证服务器在Azure环境中正常启动
- 确认配置 -> 常规设置中已开启
核对proto定义与服务方法一致性
确保客户端与服务器端的proto文件完全一致,包括服务方法名(PerformanceDataByPlanAndForcesIds)、消息结构、字段类型。即使设置了keepCase: true,也要严格核对大小写和命名,避免因定义不匹配导致调用失败。调整请求超时与实例健康检查
- 为客户端调用设置合理的超时时间,避免因Azure网络延迟导致请求被取消:
const call = this.grpcClient.PerformanceDataByPlanAndForcesIds(request, { deadline: Date.now() + 10000 }); // 设置10秒超时 - 如果应用服务启用自动缩放,检查实例启动状态,确保请求不会被路由到未就绪的实例。
- 为客户端调用设置合理的超时时间,避免因Azure网络延迟导致请求被取消:
内容的提问来源于stack exchange,提问作者שולמית טנג'ר

