使用 GRPC 与 Google Cloud Run 通信的 Google App Engine 给出“错误:14 不可用:连接已断开”
Posted
技术标签:
【中文标题】使用 GRPC 与 Google Cloud Run 通信的 Google App Engine 给出“错误:14 不可用:连接已断开”【英文标题】:Google App Engine communicating with Google Cloud Run using GRPC gives "Error: 14 UNAVAILABLE: Connection dropped" 【发布时间】:2022-01-11 16:27:06 【问题描述】:tl;博士
在镜像中用 C++ 编写的 gRPC 服务器(本地 Docker,在线云运行)在本地工作,但当用 node.js 编写的 gRPC 客户端向它发送请求时,它不能在线工作。无论客户端是本地还是 Google App 引擎上的客户端都是如此。该图像绝对有效,因为当 grpcurl 向其发送请求时它会正确响应。
详细信息
Node.js 中的客户端代码
import loadPackageDefinition, credentials from '@grpc/grpc-js';
import loadSync from '@grpc/proto-loader';
const packageDef = loadSync(
'./path/to/file.proto',
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
,
);
const packageNameProto = loadPackageDefinition(packageDef).packageName;
const client = new packageProto.ServiceName(
`$host:$port`,
credentials.createInsecure(),
);
client.calculation(tempInputs, function(err, result)
// code
);
C++ 中的服务器代码。
void RunServer()
int port = 50051;
char* port_ptr = std::getenv("PORT");
if (port_ptr != nullptr)
port = std::atoi(port_ptr);
if (port < MIN_PORT or MAX_PORT < port)
port = 50051;
std::ostringstream server_address;
server_address << "0.0.0.0:" << port;
// std::string server_address("0.0.0.0:50051");
ServiceNameServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address.str(), grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address.str() << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
int main(int argc, char** argv)
RunServer();
return 0;
客户端和服务器、GCP和本地兼容性表
Local Server on Docker in WSL2 | Cloud Run Server | |
---|---|---|
Local Client from command line in Ubuntu on WSL2 | Works using localhost:50051 and 'my-external-ip address':50051 port forwarded to my machine | Doesn't work using 'cloud-run-url':443, giving the "Error: 14 UNAVAILABLE: Connection dropped" |
App Engine Client | Works using 'my-external-ip address':50051 port forwarded to my machine | Doesn't work using 'cloud-run-url':443, giving the "Error: 14 UNAVAILABLE: Connection dropped" |
grpcurl command in Ubuntu on WSL2 | X | Works using 'cloud-run-url':443 as cloud run wants requests on 443. Command is 'docker run -i -v pwd :/protos fullstorydev/grpcurl -d @ -proto protos/file.proto cloud.run.url.run.app:443 protoPackage.ProtoService.proto_function < inputs.json' |
根据 Google 文档,服务器映像为 built 和 deployed。
客户端使用gcloud app deploy
部署。
在云运行服务触发器中,我将“入口”设置为“允许所有流量”,将“身份验证”设置为“允许未经身份验证的调用”。
HTTP/2 连接已启用。我也尝试过禁用它们,因为'Using gRPC' 指南说你只需要在使用 gRPC 流时进行设置,而我没有。
错误日志:(已删除私人信息)
"textPayload": "Error: 14 UNAVAILABLE: Connection dropped\n at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:31:26)\n at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:180:52)\n at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)\n at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)\n at /workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:160:78\n at processTicksAndRejections (internal/process/task_queues.js:77:11) ",
"insertId": "61adfe9d000b03a0c#######",
"resource":
"type": "gae_app",
"labels":
"project_id": "$PROJECT_ID",
"module_id": "default",
"zone": "europe-west2-3",
"version_id": "20211206t121319"
,
"timestamp": "2021-12-06T12:14:21.721824Z",
"severity": "ERROR",
"labels":
"clone_id": "00c61b117ca5f61b7b4b7b7dde5eddded10f5bead78cf0cf0eee3fe1111a982786d972c65976ff49ddd14eaab4b708ed52349b06cc1538deacc7a89b8d6641b55a14f5799#######"
,
"logName": "projects/$PROJECT_ID/logs/stdout",
"receiveTimestamp": "2021-12-06T12:14:22.008561030Z"
带有“GRPC_TRACE=all GRPC_VERBOSITY=DEBUG”的错误日志:(已删除私人信息)
D 2021-12-06T12:25:38.616Z | resolving_load_balancer | dns:$CLOUD_RUN_URL:443 CONNECTING -> CONNECTING
D 2021-12-06T12:25:38.616Z | channel | (22) dns:$CLOUD_RUN_URL:443 callRefTimer.unref | configSelectionQueue.length=0 pickQueue.length=0
D 2021-12-06T12:25:38.616Z | channel | (22) dns:$CLOUD_RUN_URL:443 Pick result: QUEUE subchannel: undefined status: undefined undefined
D 2021-12-06T12:25:38.616Z | channel | (22) dns:$CLOUD_RUN_URL:443 callRefTimer.ref | configSelectionQueue.length=0 pickQueue.length=1
D 2021-12-06T12:25:38.616Z | connectivity_state | (22) dns:$CLOUD_RUN_URL:443 CONNECTING -> CONNECTING
D 2021-12-06T12:25:38.617Z | subchannel | (24) $CLOUD_RUN_IP_ADD_1:443 CONNECTING -> READY
D 2021-12-06T12:25:38.618Z | pick_first | Pick subchannel with address $CLOUD_RUN_IP_ADD_1:443
D 2021-12-06T12:25:38.618Z | pick_first | CONNECTING -> READY
D 2021-12-06T12:25:38.618Z | resolving_load_balancer | dns:$CLOUD_RUN_URL:443 CONNECTING -> READY
D 2021-12-06T12:25:38.618Z | channel | (22) dns:$CLOUD_RUN_URL:443 callRefTimer.unref | configSelectionQueue.length=0 pickQueue.length=0
D 2021-12-06T12:25:38.618Z | channel | (22) dns:$CLOUD_RUN_URL:443 Pick result: COMPLETE subchannel: $CLOUD_RUN_IP_ADD_1:443 status: undefined undefined
D 2021-12-06T12:25:38.618Z | connectivity_state | (22) dns:$CLOUD_RUN_URL:443 CONNECTING -> READY
D 2021-12-06T12:25:38.618Z | subchannel_refcount | (24) $CLOUD_RUN_IP_ADD_1:443 refcount 2 -> 3
D 2021-12-06T12:25:38.618Z | subchannel_refcount | (23) $CLOUD_RUN_IPV6_1::a:443 refcount 3 -> 2
D 2021-12-06T12:25:38.618Z | subchannel_refcount | (24) $CLOUD_RUN_IP_ADD_1:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (25) $CLOUD_RUN_IPV6_2::a:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (26) $CLOUD_RUN_IP_ADD_2:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (27) $CLOUD_RUN_IPV6_3::a:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (28) $CLOUD_RUN_IP_ADD_3:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (29) $CLOUD_RUN_IPV6_4::a:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (30) $CLOUD_RUN_IP_ADD_4:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (31) $CLOUD_RUN_IPV6_3::35:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (32) $CLOUD_RUN_IP_ADD_5:443 refcount 3 -> 2
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (23) $CLOUD_RUN_IPV6_1::a:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (26) $CLOUD_RUN_IP_ADD_2:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (25) $CLOUD_RUN_IPV6_2::a:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (28) $CLOUD_RUN_IP_ADD_3:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (27) $CLOUD_RUN_IPV6_3::a:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (30) $CLOUD_RUN_IP_ADD_4:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (29) $CLOUD_RUN_IPV6_4::a:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | subchannel_refcount | (32) $CLOUD_RUN_IP_ADD_5:443 refcount 2 -> 1
D 2021-12-06T12:25:38.619Z | call_stream | Starting stream on subchannel (24) $CLOUD_RUN_IP_ADD_1:443 with headers
grpc-accept-encoding: identity,deflate,gzip
accept-encoding: identity
:authority: $CLOUD_RUN_URL:443
user-agent: grpc-node-js/1.4.4
content-type: application/grpc
:method: POST
:path: /protoPackage.ProtoService/proto_function
te: trailers
D 2021-12-06T12:25:38.620Z | call_stream | [3] attachHttp2Stream from subchannel $CLOUD_RUN_IP_ADD_1:443
D 2021-12-06T12:25:38.620Z | subchannel_refcount | (24) $CLOUD_RUN_IP_ADD_1:443 callRefcount 0 -> 1
D 2021-12-06T12:25:38.620Z | call_stream | [3] sending data chunk of length 223 (deferred)
D 2021-12-06T12:25:38.620Z | call_stream | [3] calling end() on HTTP/2 stream
D 2021-12-06T12:25:38.627Z | call_stream | [3] ended with status: code=14 details="Connection dropped"
D 2021-12-06T12:25:38.628Z | subchannel_refcount | (24) $CLOUD_RUN_IP_ADD_1:443 callRefcount 1 -> 0
D 2021-12-06T12:25:38.628Z | call_stream | [3] close http2 stream with code 8
ERROR!
Error: 14 UNAVAILABLE: Connection dropped
at Object.callErrorFromStatus (/home/sam/nodejs/elevate-online-njs/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/home/sam/nodejs/elevate-online-njs/node_modules/@grpc/grpc-js/build/src/client.js:180:52)
at Object.onReceiveStatus (/home/sam/nodejs/elevate-online-njs/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
at Object.onReceiveStatus (/home/sam/nodejs/elevate-online-njs/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
at /home/sam/nodejs/elevate-online-njs/node_modules/@grpc/grpc-js/build/src/call-stream.js:160:78
at processTicksAndRejections (internal/process/task_queues.js:77:11)
code: 14,
details: 'Connection dropped',
metadata: Metadata internalRepr: Map(0) , options:
D 2021-12-06T12:25:38.631Z | subchannel | (24) $CLOUD_RUN_IP_ADD_1:443 connection closed
D 2021-12-06T12:25:38.632Z | subchannel | (24) $CLOUD_RUN_IP_ADD_1:443 READY -> IDLE
D 2021-12-06T12:25:38.632Z | subchannel_refcount | (24) $CLOUD_RUN_IP_ADD_1:443 refcount 2 -> 1
D 2021-12-06T12:25:38.632Z | pick_first | READY -> IDLE
D 2021-12-06T12:25:38.632Z | resolving_load_balancer | dns:$CLOUD_RUN_URL:443 READY -> IDLE
D 2021-12-06T12:25:38.632Z | connectivity_state | (22) dns:$CLOUD_RUN_URL:443 READY -> IDLE
D 2021-12-06T12:25:38.632Z | call_stream | [3] HTTP/2 stream closed with code 8
D 2021-12-06T12:25:39.275Z | subchannel | (2) $CLOUD_RUN_IPV6_1::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.275Z | subchannel | (2) $CLOUD_RUN_IPV6_1::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.277Z | subchannel | (2) $CLOUD_RUN_IPV6_1::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_1::a:443 - Local (:::0)
D 2021-12-06T12:25:39.277Z | subchannel | (2) $CLOUD_RUN_IPV6_1::a:443 connection closed
D 2021-12-06T12:25:39.277Z | subchannel | (2) $CLOUD_RUN_IPV6_1::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.278Z | subchannel | (2) $CLOUD_RUN_IPV6_1::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.278Z | subchannel | (4) $CLOUD_RUN_IPV6_2::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.279Z | subchannel | (4) $CLOUD_RUN_IPV6_2::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.280Z | subchannel | (4) $CLOUD_RUN_IPV6_2::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_2::a:443 - Local (:::0)
D 2021-12-06T12:25:39.281Z | subchannel | (4) $CLOUD_RUN_IPV6_2::a:443 connection closed
D 2021-12-06T12:25:39.281Z | subchannel | (4) $CLOUD_RUN_IPV6_2::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.281Z | subchannel | (4) $CLOUD_RUN_IPV6_2::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.281Z | subchannel | (6) $CLOUD_RUN_IPV6_3::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.282Z | subchannel | (6) $CLOUD_RUN_IPV6_3::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.284Z | subchannel | (6) $CLOUD_RUN_IPV6_3::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_3::a:443 - Local (:::0)
D 2021-12-06T12:25:39.284Z | subchannel | (6) $CLOUD_RUN_IPV6_3::a:443 connection closed
D 2021-12-06T12:25:39.284Z | subchannel | (6) $CLOUD_RUN_IPV6_3::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.284Z | subchannel | (6) $CLOUD_RUN_IPV6_3::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.284Z | subchannel | (8) $CLOUD_RUN_IPV6_4::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.285Z | subchannel | (8) $CLOUD_RUN_IPV6_4::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.286Z | subchannel | (8) $CLOUD_RUN_IPV6_4::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_4::a:443 - Local (:::0)
D 2021-12-06T12:25:39.287Z | subchannel | (8) $CLOUD_RUN_IPV6_4::a:443 connection closed
D 2021-12-06T12:25:39.288Z | subchannel | (8) $CLOUD_RUN_IPV6_4::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.289Z | subchannel | (8) $CLOUD_RUN_IPV6_4::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.290Z | subchannel | (10) $CLOUD_RUN_IPV6_5::200a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.291Z | subchannel | (10) $CLOUD_RUN_IPV6_5::200a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.293Z | subchannel | (10) $CLOUD_RUN_IPV6_5::200a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_5::200a:443 - Local (:::0)
D 2021-12-06T12:25:39.293Z | subchannel | (10) $CLOUD_RUN_IPV6_5::200a:443 connection closed
D 2021-12-06T12:25:39.294Z | subchannel | (10) $CLOUD_RUN_IPV6_5::200a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.294Z | subchannel | (10) $CLOUD_RUN_IPV6_5::200a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.602Z | subchannel | (23) $CLOUD_RUN_IPV6_1::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.602Z | subchannel | (23) $CLOUD_RUN_IPV6_1::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.604Z | subchannel | (23) $CLOUD_RUN_IPV6_1::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_1::a:443 - Local (:::0)
D 2021-12-06T12:25:39.604Z | subchannel | (23) $CLOUD_RUN_IPV6_1::a:443 connection closed
D 2021-12-06T12:25:39.604Z | subchannel | (23) $CLOUD_RUN_IPV6_1::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.605Z | subchannel | (23) $CLOUD_RUN_IPV6_1::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.605Z | subchannel | (25) $CLOUD_RUN_IPV6_2::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.606Z | subchannel | (25) $CLOUD_RUN_IPV6_2::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.607Z | subchannel | (25) $CLOUD_RUN_IPV6_2::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_2::a:443 - Local (:::0)
D 2021-12-06T12:25:39.607Z | subchannel | (25) $CLOUD_RUN_IPV6_2::a:443 connection closed
D 2021-12-06T12:25:39.607Z | subchannel | (25) $CLOUD_RUN_IPV6_2::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.608Z | subchannel | (25) $CLOUD_RUN_IPV6_2::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.608Z | subchannel | (27) $CLOUD_RUN_IPV6_3::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.608Z | subchannel | (27) $CLOUD_RUN_IPV6_3::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.610Z | subchannel | (27) $CLOUD_RUN_IPV6_3::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_3::a:443 - Local (:::0)
D 2021-12-06T12:25:39.610Z | subchannel | (27) $CLOUD_RUN_IPV6_3::a:443 connection closed
D 2021-12-06T12:25:39.610Z | subchannel | (27) $CLOUD_RUN_IPV6_3::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.611Z | subchannel | (27) $CLOUD_RUN_IPV6_3::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.611Z | subchannel | (29) $CLOUD_RUN_IPV6_4::a:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.611Z | subchannel | (29) $CLOUD_RUN_IPV6_4::a:443 creating HTTP/2 session
D 2021-12-06T12:25:39.612Z | subchannel | (29) $CLOUD_RUN_IPV6_4::a:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_4::a:443 - Local (:::0)
D 2021-12-06T12:25:39.612Z | subchannel | (29) $CLOUD_RUN_IPV6_4::a:443 connection closed
D 2021-12-06T12:25:39.612Z | subchannel | (29) $CLOUD_RUN_IPV6_4::a:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.612Z | subchannel | (29) $CLOUD_RUN_IPV6_4::a:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:39.613Z | subchannel | (31) $CLOUD_RUN_IPV6_3::35:443 TRANSIENT_FAILURE -> CONNECTING
D 2021-12-06T12:25:39.613Z | subchannel | (31) $CLOUD_RUN_IPV6_3::35:443 creating HTTP/2 session
D 2021-12-06T12:25:39.614Z | subchannel | (31) $CLOUD_RUN_IPV6_3::35:443 connection closed with error connect ENETUNREACH $CLOUD_RUN_IPV6_3::35:443 - Local (:::0)
D 2021-12-06T12:25:39.614Z | subchannel | (31) $CLOUD_RUN_IPV6_3::35:443 connection closed
D 2021-12-06T12:25:39.614Z | subchannel | (31) $CLOUD_RUN_IPV6_3::35:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:39.614Z | subchannel | (31) $CLOUD_RUN_IPV6_3::35:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.270Z | subchannel_refcount | (2) $CLOUD_RUN_IPV6_1::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.270Z | subchannel_refcount | (4) $CLOUD_RUN_IPV6_2::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.270Z | subchannel_refcount | (5) $CLOUD_RUN_IP_ADD_2:443 refcount 1 -> 0
D 2021-12-06T12:25:48.271Z | subchannel | (5) $CLOUD_RUN_IP_ADD_2:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.271Z | subchannel_refcount | (6) $CLOUD_RUN_IPV6_3::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.271Z | subchannel_refcount | (7) $CLOUD_RUN_IP_ADD_3:443 refcount 1 -> 0
D 2021-12-06T12:25:48.271Z | subchannel | (7) $CLOUD_RUN_IP_ADD_3:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.271Z | subchannel_refcount | (8) $CLOUD_RUN_IPV6_4::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.271Z | subchannel_refcount | (9) $CLOUD_RUN_IP_ADD_4:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel | (9) $CLOUD_RUN_IP_ADD_4:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.272Z | subchannel_refcount | (10) $CLOUD_RUN_IPV6_5::200a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel_refcount | (11) $CLOUD_RUN_IP_ADD_5:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel | (11) $CLOUD_RUN_IP_ADD_5:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.272Z | subchannel_refcount | (23) $CLOUD_RUN_IPV6_1::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel_refcount | (24) $CLOUD_RUN_IP_ADD_1:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel_refcount | (25) $CLOUD_RUN_IPV6_2::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel_refcount | (26) $CLOUD_RUN_IP_ADD_2:443 refcount 1 -> 0
D 2021-12-06T12:25:48.272Z | subchannel | (26) $CLOUD_RUN_IP_ADD_2:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.273Z | subchannel_refcount | (27) $CLOUD_RUN_IPV6_3::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.273Z | subchannel_refcount | (28) $CLOUD_RUN_IP_ADD_3:443 refcount 1 -> 0
D 2021-12-06T12:25:48.273Z | subchannel | (28) $CLOUD_RUN_IP_ADD_3:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.273Z | subchannel_refcount | (29) $CLOUD_RUN_IPV6_4::a:443 refcount 1 -> 0
D 2021-12-06T12:25:48.273Z | subchannel_refcount | (30) $CLOUD_RUN_IP_ADD_4:443 refcount 1 -> 0
D 2021-12-06T12:25:48.273Z | subchannel | (30) $CLOUD_RUN_IP_ADD_4:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.273Z | subchannel_refcount | (31) $CLOUD_RUN_IPV6_3::35:443 refcount 1 -> 0
D 2021-12-06T12:25:48.273Z | subchannel_refcount | (32) $CLOUD_RUN_IP_ADD_5:443 refcount 1 -> 0
D 2021-12-06T12:25:48.274Z | subchannel | (32) $CLOUD_RUN_IP_ADD_5:443 CONNECTING -> TRANSIENT_FAILURE
D 2021-12-06T12:25:48.274Z | subchannel | (5) $CLOUD_RUN_IP_ADD_2:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.274Z | subchannel | (7) $CLOUD_RUN_IP_ADD_3:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.274Z | subchannel | (9) $CLOUD_RUN_IP_ADD_4:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.274Z | subchannel | (11) $CLOUD_RUN_IP_ADD_5:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.274Z | subchannel | (26) $CLOUD_RUN_IP_ADD_2:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.275Z | subchannel | (28) $CLOUD_RUN_IP_ADD_3:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.275Z | subchannel | (30) $CLOUD_RUN_IP_ADD_4:443 TRANSIENT_FAILURE -> IDLE
D 2021-12-06T12:25:48.275Z | subchannel | (32) $CLOUD_RUN_IP_ADD_5:443 TRANSIENT_FAILURE -> IDLE
【问题讨论】:
【参考方案1】:从grpc documentation 开始,credentials.createSsl()
的所有 3 个参数都是可选的。然而,
如果使用客户端证书,则必须同时传递第二个和第三个参数。
因此,因为我使用的是客户端证书并且没有传递 private_key 或 cert_chain,所以我不得不禁用“NODE_TLS_REJECT_UNAUTHORIZED”。
因此,文档表明只使用credentials.createSsl()
而不传递证书是可以的。但是official code examples 并未将其作为示例用例。
我目前的工作代码是
import loadPackageDefinition, credentials from '@grpc/grpc-js';
import loadSync from '@grpc/proto-loader';
const packageDef = loadSync(
'./path/to/file.proto',
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
,
);
const packageNameProto = loadPackageDefinition(packageDef).packageName;
const ssl_creds = credentials.createSsl();
const client = new packageNameProto.Uppeak(
`$host:$port`,
ssl_creds,
);
感谢 Pablo 指出这一点。
旧答案
我们现在有一个解决方案来让它工作,但这绝对不是一个理想的解决方案。
我们不使用grpc.credentials.createInsecure()
,而是按照guide(底部概述的步骤)创建自签名SSL证书。
然后在 node.js 代码中如下使用它。请注意,将NODE_TLS_REJECT_UNAUTHORIZED
设置为“0”会引发警告。
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; // new
import loadPackageDefinition, credentials from '@grpc/grpc-js';
import loadSync from '@grpc/proto-loader';
import readFileSync from 'fs'; // new
const packageDef = loadSync(
'./path/to/file.proto',
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
,
);
const packageNameProto = loadPackageDefinition(packageDef).packageName;
const root_cert = readFileSync('./server.crt'); // new
const ssl_creds = credentials.createSsl(root_cert); // new
const client = new packageNameProto.Uppeak(
`$host:$port`,
ssl_creds,
); // changed
Creating a self signed certificate
-
您需要在 Linux 上安装 Apache 和 openssl。
生成服务器密钥:
openssl genrsa -des3 -out server.key 4096
用它创建一个证书签名请求。此命令将提示一系列内容(国家、州或省等)。确保“通用名称(例如,您的姓名)”与您的盒子注册的完全限定域名(或您的 IP 地址,如果您没有的话)匹配:
openssl req -new -key server.key -out server.csr
现在对证书签名请求进行签名。此示例持续 365 天:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
【讨论】:
这很好,但也阅读您的问题,我认为您可能发现了一个错误。我在 [Issue Tracker](issuetracker.google.com) 上看不到任何报告,我设法找到的只是github issue where someone with your problem latched on,但在说他们会这样做之后并没有创建自己的问题,只是说那"logging is helping shed more light on the problem"
。关于使用443...The docs you shared只指定需要使用port env,我觉得可以改一下?
在我的情况下,使用grpc.credentials.createSsl()
就足够了,无需任何自行生成的根证书。
@Pablo 我自己试一试,然后更新答案以上是关于使用 GRPC 与 Google Cloud Run 通信的 Google App Engine 给出“错误:14 不可用:连接已断开”的主要内容,如果未能解决你的问题,请参考以下文章
使用 grpc 和 protobuf(生成的客户端)通过 HTTP 2 访问 Google Cloud Pubsub
如何在 Google Cloud Platform 上部署 GRPC 服务器和客户端?