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

部署在Cloud Run的Node.js gRPC客户端连接报错:Error 14 UNAVAILABLE

如何正确连接部署在Cloud Run上的Node.js gRPC服务

问题背景

本地运行Node.js gRPC服务端和客户端时一切正常,但将服务端部署到Cloud Run后,客户端修改连接地址为Cloud Run域名时出现错误:

Error: 14 UNAVAILABLE: read ECONNRESET

服务端代码(greeter_server.js):

var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;

function sayHello(call, callback) {
  callback(null, {message: 'Hello ' + call.request.name});
}

function main() {
  var server = new grpc.Server();
  server.addService(hello_proto.Greeter.service, {sayHello: sayHello});
  server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
    server.start();
  });
}

main();

原客户端代码(greeter_client.js):

var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';

var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;

function main() {
  var target = 'localhost:50051'; // 修改为Cloud Run地址时报错
  var client = new hello_proto.Greeter(target, grpc.credentials.createInsecure());
  var user='world';
  client.sayHello({name: user}, function(err, response) {
    console.log('Greeting:', response.message);
  });
}

main();

错误原因

Cloud Run对gRPC服务的连接有两个强制要求:

  1. 必须使用TLS加密连接,不允许无加密的createInsecure()方式;
  2. 外部访问必须使用443端口,Cloud Run会将外部443端口转发到容器内部指定的50051端口。

原客户端代码的问题在于:使用了无加密凭证,且没有指定正确的443端口。

解决方法

修改客户端代码的两个关键部分:

1. 修正目标地址格式

将target改为Cloud Run域名+443端口,不需要添加https://前缀:

var target = 'greeter-service-abcdefghij-ue.a.run.app:443';

2. 使用安全SSL凭证

替换grpc.credentials.createInsecure()为grpc.credentials.createSsl(),建立加密连接:

var client = new hello_proto.Greeter(target, grpc.credentials.createSsl());

修改后的完整客户端代码

var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';

var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;

function main() {
  var target = 'greeter-service-abcdefghij-ue.a.run.app:443';
  var client = new hello_proto.Greeter(target, grpc.credentials.createSsl());
  var user='world';
  client.sayHello({name: user}, function(err, response) {
    if (err) {
      console.error('调用失败:', err);
      return;
    }
    console.log('Greeting:', response.message);
  });
}

main();

额外说明

  • 服务端代码无需修改:Cloud Run会自动处理外部443端口到容器内部50051端口的转发,服务端绑定0.0.0.0:50051是正确的。
  • 确保Cloud Run服务已正确配置:容器端口设置为50051,服务已正常启动并对外暴露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:15:40