在 NodeJS 中检测 GRPC 服务器故障
Detect a GRPC Server Failure in NodeJS
Framing:经验丰富 engineer/developer 第一次接触GRPC和HTTP2,很久以来第一次接触流式编程。
我需要注意哪些事件才能成功检测到 "failure"(服务器预期断开连接、服务器意外断开连接、服务器超时并消失等)使用 @grpc/grpc-js
包时的 GRPC 服务器?
也就是说——我们有一个使用原型缓冲区的 GRPC 服务,我们可以 call/setup 像这样的流
const protoLoader = require('@grpc/proto-loader')
const packageDefinition = protoLoader.loadSync(
__dirname + '/path/to/v1.proto',
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
})
const packageDefinition = grpc.loadPackageDefinition(packageDefinition).com.foo.bar.v1
const client = new packageDefinition.IngestService(
'server.url.here.com:443',
grpc.credentials.createSsl()
)
const stream = client.recordSpan(metadata)
此时stream
是一个ClientDuplexStreamImpl
object, which has Node's native Duplex
作为它的父class/object。
Duplex
对象实现了 writable
和 readable
流接口,这意味着它可能会为 ClientDuplexStreamImpl
对象发出 close
,drain
,error
,finish
,pipe
,unpipe
events (writable), or close
,data
,end
,error
,pause
,readable
, resume
events (readable). There also appears to be a metadata
and status
event。
我想做的是设置一个有弹性的流。在我天真的想法中,这就像 "If the stream disconnects for any reason, I'll destroy the object and try connecting again with a backoff algorithm" 一样简单。
我天真的想法面临的挑战是不清楚 close
和 end
之间的区别,或者 error
频道是否只是让我知道 an 发生了错误,或者如果发生了错误并且一切都消失了。
此外,因为这些是流事件,所以还不清楚是否每种服务器断开连接都会反映在流中,以及我是否需要查看不同的对象(这些对象是哪些对象?)来检测与服务器连接的实际状态。
还值得一提的是,这是针对我无法控制其实现的服务器。
所以——重申我的问题:作为 GRPC 服务的 client/consumer,我需要做什么来确保我检测到服务器有 "gone away" 并且我应该尝试重新连接?
简短的回答是 gRPC 调用通常以 status
结束,其中 status.code
等于 grpc.status.UNAVAILABLE
,因此您应该能够通过监听来完成您想要的a status/error 使用该代码并在发生这种情况时重新建立流。
首先,我想解释一下 gRPC 请求的整个生命周期。发起请求后,通常首先会得到一个包含响应头的 metadata
事件。然后您将执行一些 write
操作并接收一些 data
事件。然后流将结束,并且将触发一些半冗余事件。 end
事件表明没有更多的数据可读,但没有附加信息。 close
事件也可能在这里触发,但我从不使用它。 status
事件提供了一个 status object 来说明流是如何结束的。 .code
等于 grpc.status.OK
表示流成功完成。在任何其他情况下,也会发出 error
事件,并且 error
对象将另外具有状态具有的所有相同字段。您应该始终监听 error
事件,因为如果您不这样做并且发出一个事件,Node 会自动将其冒泡并将其作为全局异常抛出。
如果流由于任何原因结束,包括服务器断开连接,它将以 status
事件结束。网络错误,包括服务器断开连接,通常由 UNAVAILABLE
状态代码指示。当根本无法建立连接时,也会使用该代码。
在大多数情况下,gRPC 无论如何都是对连接的抽象。单个 gRPC 客户端可以由多个 TCP 连接支持,如果连接断开,gRPC 将自动尝试重新建立连接。
Framing:经验丰富 engineer/developer 第一次接触GRPC和HTTP2,很久以来第一次接触流式编程。
我需要注意哪些事件才能成功检测到 "failure"(服务器预期断开连接、服务器意外断开连接、服务器超时并消失等)使用 @grpc/grpc-js
包时的 GRPC 服务器?
也就是说——我们有一个使用原型缓冲区的 GRPC 服务,我们可以 call/setup 像这样的流
const protoLoader = require('@grpc/proto-loader')
const packageDefinition = protoLoader.loadSync(
__dirname + '/path/to/v1.proto',
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
})
const packageDefinition = grpc.loadPackageDefinition(packageDefinition).com.foo.bar.v1
const client = new packageDefinition.IngestService(
'server.url.here.com:443',
grpc.credentials.createSsl()
)
const stream = client.recordSpan(metadata)
此时stream
是一个ClientDuplexStreamImpl
object, which has Node's native Duplex
作为它的父class/object。
Duplex
对象实现了 writable
和 readable
流接口,这意味着它可能会为 ClientDuplexStreamImpl
对象发出 close
,drain
,error
,finish
,pipe
,unpipe
events (writable), or close
,data
,end
,error
,pause
,readable
, resume
events (readable). There also appears to be a metadata
and status
event。
我想做的是设置一个有弹性的流。在我天真的想法中,这就像 "If the stream disconnects for any reason, I'll destroy the object and try connecting again with a backoff algorithm" 一样简单。
我天真的想法面临的挑战是不清楚 close
和 end
之间的区别,或者 error
频道是否只是让我知道 an 发生了错误,或者如果发生了错误并且一切都消失了。
此外,因为这些是流事件,所以还不清楚是否每种服务器断开连接都会反映在流中,以及我是否需要查看不同的对象(这些对象是哪些对象?)来检测与服务器连接的实际状态。
还值得一提的是,这是针对我无法控制其实现的服务器。
所以——重申我的问题:作为 GRPC 服务的 client/consumer,我需要做什么来确保我检测到服务器有 "gone away" 并且我应该尝试重新连接?
简短的回答是 gRPC 调用通常以 status
结束,其中 status.code
等于 grpc.status.UNAVAILABLE
,因此您应该能够通过监听来完成您想要的a status/error 使用该代码并在发生这种情况时重新建立流。
首先,我想解释一下 gRPC 请求的整个生命周期。发起请求后,通常首先会得到一个包含响应头的 metadata
事件。然后您将执行一些 write
操作并接收一些 data
事件。然后流将结束,并且将触发一些半冗余事件。 end
事件表明没有更多的数据可读,但没有附加信息。 close
事件也可能在这里触发,但我从不使用它。 status
事件提供了一个 status object 来说明流是如何结束的。 .code
等于 grpc.status.OK
表示流成功完成。在任何其他情况下,也会发出 error
事件,并且 error
对象将另外具有状态具有的所有相同字段。您应该始终监听 error
事件,因为如果您不这样做并且发出一个事件,Node 会自动将其冒泡并将其作为全局异常抛出。
如果流由于任何原因结束,包括服务器断开连接,它将以 status
事件结束。网络错误,包括服务器断开连接,通常由 UNAVAILABLE
状态代码指示。当根本无法建立连接时,也会使用该代码。
在大多数情况下,gRPC 无论如何都是对连接的抽象。单个 gRPC 客户端可以由多个 TCP 连接支持,如果连接断开,gRPC 将自动尝试重新建立连接。