gpt4 book ai didi

java - Thrift TSimpleServer 在多次成功请求后变得无响应

转载 作者:可可西里 更新时间:2023-11-01 02:31:20 27 4
gpt4 key购买 nike

我在 Linux 上运行的 Java 应用程序提供了一个 Thrift API。我正在使用 .NET 客户端连接到 API 并执行操作。

对服务的前几次调用工作正常,没有错误,但随后(看似随机)调用将“挂起”。如果我强制退出我的客户端并尝试重新连接,服务要么再次挂起,要么我的客户端出现以下错误:

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at Thrift.Transport.TStreamTransport.Read(Byte[] buf, Int32 off, Int32 len)
(etc.)

当我使用 JConsole 获取线程转储时,服务器处于 accept()

"Thread-1" prio=10 tid=0x00002aaad457a800 nid=0x79c7 runnable [0x00000000434af000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
- locked <0x00000005c0fef470> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at org.apache.thrift.transport.TServerSocket.acceptImpl(TServerSocket.java:113)
at org.apache.thrift.transport.TServerSocket.acceptImpl(TServerSocket.java:35)
at org.apache.thrift.transport.TServerTransport.accept(TServerTransport.java:31)
at org.apache.thrift.server.TSimpleServer.serve(TSimpleServer.java:63)
服务器上的

netstat 显示到 TIME_WAIT 上的服务端口的连接最终在我强制退出客户端几分钟后消失(正如预期的那样)。

设置Thrift服务的代码如下:

        int port = thriftServicePort;
String host = thriftServiceHost;
InetAddress adr = InetAddress.getByName(host);
InetSocketAddress address = new InetSocketAddress(adr, port);
TServerTransport serverTransport = new TServerSocket(address);
TServer server = new TSimpleServer(new TServer.Args(serverTransport).processor((org.apache.thrift.TProcessor)processor));

server.serve();

请注意,我们正在使用采用显式主机名或 IP 地址的 TServerTransport 构造函数。我怀疑我应该将其更改为采用仅指定端口的构造函数(最终绑定(bind)到 InetAddress.anyLocalAddress())。或者,我想我可以将服务配置为绑定(bind)到“通配符”地址(“0.0.0.0”)。

我应该提一下,该服务并未托管在开放的互联网上。它托管在一个专用网络中,我正在使用 SSH 隧道来访问它。因此,服务绑定(bind)到的主机名无法在我的本地网络中解析(尽管我可以通过隧道建立初始连接)。我想知道这是否类似于 RMI TCP callback problem

是否有关于正在发生的事情的技术解释(如果这是一个常见问题),或者我可以采取的其他故障排除步骤?

更新

今天遇到同样的问题,但是这次 jstack 显示 Thrift 服务器永远阻塞从输入流中读取:

"Thread-1" prio=10 tid=0x00002aaad43fc000 nid=0x60b3 runnable [0x0000000041741000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:127)
at org.apache.thrift.transport.TTransport.readAll(TTransport.java:84)
at org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:378)
at org.apache.thrift.protocol.TBinaryProtocol.readI32(TBinaryProtocol.java:297)
at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:204)
at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:22)
at org.apache.thrift.server.TSimpleServer.serve(TSimpleServer.java:70)

所以我们需要在TServerSocket构造函数中设置一个“客户端超时”。但为什么这会导致应用程序在 accept() 上阻塞时也拒绝连接?

最佳答案

从您的堆栈跟踪看来,您正在使用 TSimpleServer,其 javadocs say ,

Simple singlethreaded server for testing.

可能您想使用的是 TThreadPoolServer .

很可能发生的情况是 TSimpleServer 的单个线程被阻塞,等待死客户端响应或超时。并且因为 TSimpleServer 是单线程的,所以没有线程可用于处理其他请求。

关于java - Thrift TSimpleServer 在多次成功请求后变得无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14512489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com