【发布时间】:2021-09-17 01:48:10
【问题描述】:
服务器:
override fun subscribe(request: Subscribe, responseObserver: StreamObserver<SubscriptionEvent>) {
sessionStore.grpcHandler(responseObserver, request.sessionId) { session ->
eventStream.stream(session.id)
.doOnNext {
try {
if ((responseObserver as ServerCallStreamObserver).isCancelled) {
log.debug { "Stopping to stream events, seems like client cancelled it" }
responseObserver.onCompleted()
return@doOnNext
}
responseObserver.onNext(it)
} catch (e: StatusRuntimeException) {
log.error("Could not stream an event", e)
}
}
.doOnError { throwable ->
log.error("Subscription failed", throwable)
}
.subscribe()
}
}
客户:
fun subscribe(sessionId: String, tenantId: String, botId: String) {
subscriptionsThreadPool.submit {
try {
subscriptionService.withDeadlineAfter(Long.MAX_VALUE, TimeUnit.SECONDS).subscribe(
Subscribe.newBuilder().setSessionId(sessionId).build(),
SubscribeStreamObserver(sessionId, tenantId, botId)
)
finishLatch.await()
} catch (e: Throwable) {
log.error("Could not subscribe to connector-service", e)
}
}
}
服务器正在使用https://github.com/LogNet/grpc-spring-boot-starter
客户端的netty配置(值得一提的是grpc服务器前面没有任何代理):
private fun rpcChannel(): ManagedChannel =
NettyChannelBuilder
.forTarget(properties.connectorServiceUrl)
.usePlaintext()
.build()
一旦我开始客户端订阅(即调用流事件的订阅方法),最多需要 4 分钟直到它失败并出现 UNAVAILABE Connection reset 异常。总是大约 3-4 分钟。我确实尝试设置所有可能的 netty 配置属性,但没有任何帮助。这是日志..
服务器:
2021-07-06 11:56:26.045 DEBUG [/] [-worker-ELG-3-1] io.grpc.netty.NettyServerHandler : Connection Error
java.io.IOException: Connection reset by peer
at java.base/sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at java.base/sun.nio.ch.SocketDispatcher.read(Unknown Source)
at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
at java.base/sun.nio.ch.SocketChannelImpl.read(Unknown Source)
at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Unknown Source)
2021-07-06 11:56:26.045 DEBUG [/] [-worker-ELG-3-1] io.grpc.netty.NettyServerHandler : [id: 0x1f9596dc, L:/172.17.0.110:8081 - R:/46.5.255.46:58262] OUTBOUND GO_AWAY: lastStreamId=2147483647 errorCode=2 length=24 bytes=436f6e6e656374696f6e2072657365742062792070656572
2021-07-06 11:56:26.046 DEBUG [/] [-worker-ELG-3-1] i.g.n.NettyServerTransport.connections : Transport failed
客户:
2021-07-06 13:56:25.996 DEBUG [/] [-worker-ELG-1-1] io.grpc.netty.NettyClientHandler : Caught a connection error
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:367)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:398)
at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1133)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:832)
2021-07-06 13:56:26.008 DEBUG [/] [-worker-ELG-1-1] io.grpc.netty.NettyClientHandler : [id: 0x52cea98f, L:/192.168.178.20:57940 - R:/116.202.155.130:30192] OUTBOUND GO_AWAY: lastStreamId=0 errorCode=2 length=16 bytes=436f6e6e656374696f6e207265736574
2021-07-06 13:56:26.013 DEBUG [/] [-worker-ELG-1-1] io.grpc.netty.NettyClientHandler : Network channel is closed
io.grpc 版本为 1.37.0
有什么想法吗?
【问题讨论】:
-
你说服务器前面没有代理但是客户端和服务器之间有“NAT”设备,如果你看到本地并删除两边的IP地址:服务器:L:/ 172.17.0.110:8081 - R:/46.5.255.46:58262] 客户端:L:/192.168.178.20:57940 - R:/116.202.155.130:30192] 并且没有端口号匹配。这些中间设备是否可能正在关闭/重置连接?