框架:有经验的工程师/开发人员有史以来第一次处理GRPC和HTTP2,并且很长一段时间以来第一次处理流式编程。
在使用GRPC服务器时,为了成功检测到“故障”(服务器预期断开连接,服务器意外断开连接,服务器超时并消失等,我需要注意哪些事件) @grpc/grpc-js
包?
即-我们有一个使用protobuffers的GRPC服务,我们可以像这样调用/设置流
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,它具有Node的本机ClientDuplexStreamImpl
作为其父类/对象。
Duplex
对象同时实现了Duplex
和Duplex
流接口,这意味着它可能会发出writable
事件(可写)或readable
事件(可读)。 close
,drain
,error
,finish
,pipe
,unpipe
对象似乎也有一个close
。
我想做的是设置一个具有弹性的流。在我幼稚的头脑中,这就像“如果流由于任何原因断开连接,我将销毁该对象并尝试使用退避算法再次尝试连接”。
[我天真的想法面临的挑战是,不清楚drain
和error
之间的区别是什么,还是finish
通道只是让我知道an错误发生了,或者是否发生了错误,并且一切都消失了。
而且,由于这些是流事件,因此还不清楚每种服务器断开连接是否都将在流中反映出来,以及是否需要查看其他对象(这些对象是哪些对象?)来检测其实际状态?与服务器的连接。
也值得一提的是,这是针对我无法控制其实现的服务器。
所以,重申我的问题:作为GRPC服务的客户端/消费者,我需要做些什么来确保我检测到服务器已“消失”并且应该尝试重新连接?
简短的答案是gRPC调用通常以pipe
等于unpipe
的close
,data
,end
,error
,pause
,readable
, resume
结尾,因此您应该能够通过侦听该代码的状态/错误并重新执行代码来完成所需的操作-在发生这种情况时建立流。
首先,我想解释一下gRPC请求的整个生命周期。启动请求后,通常通常会先获得一个包含响应头的close
事件。然后,您将执行一些data
操作并收到一些end
事件。然后,流将结束,并且将触发一些半冗余事件。 error
事件指示没有更多数据可读取,但是没有其他信息。 pause
事件也可能在这里触发,但是我从不使用它。 readable
事件提供了一个resume
,用于说明流的结束方式。 metadata
and status
event等于metadata
表示流成功完成。在任何其他情况下,也将发出status
事件,并且ClientDuplexStreamImpl
对象将另外具有状态具有的所有相同字段。您应该始终侦听close
事件,因为如果不这样做,则会发出一个事件,Node会自动将其冒泡并作为全局异常抛出。
如果流由于任何原因而终止,包括服务器断开连接,它将以end
事件结束。网络错误(包括服务器断开连接)通常由error
状态代码指示。当根本无法建立连接时,也会使用该代码。
在大多数情况下,gRPC无论如何都是对连接的抽象。单个gRPC客户端可以由多个TCP连接支持,如果断开连接,则gRPC将自动尝试重新建立连接。