【问题标题】:How to use TBufferedTransport of TThreadedSelectorServer in java如何在java中使用TThreadedSelectorServer的TBufferedTransport
【发布时间】:2020-11-14 08:25:38
【问题描述】:

如何在java中使用TThreadedSelectorServer的TBufferedTransport?

在 Python 客户端中:

self.tsocket= TSocket.TSocket(self.host, self.port)
self.transport = TTransport.TBufferedTransport(self.tsocket)
protocol = TBinaryProtocol(self.transport)
client = Handler.Client(protocol)
self.transport.open()

在 Java 服务器中

TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(port);
TProcessor tprocessor = new ExecutionService.Processor<ExecutionService.Iface>(handler);
TThreadedSelectorServer.Args tArgs = new TThreadedSelectorServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
this.server = new TThreadedSelectorServer(tArgs);

Python 客户端使用 TBufferedTransport,Java 服务器使用 TFramedTransport。导致异常:

AbstractNonblockingServer$FrameBuffer  Read an invalid frame size of -2147418111. Are you using TFramedTransport on the client side?

由于某些原因,客户端无法修改,所以想将java服务器修改为TBufferedTransport。 java中如何使用TThreadedSelectorServer的TBufferedTransport? 谢谢!!!

【问题讨论】:

    标签: java python thrift


    【解决方案1】:

    TThreadedSelectorServer 需要TFramedTransport (reference):

    半同步/半异步服务器,具有单独的线程池来处理非阻塞 I/O。接受在单个线程上处理,并且可配置数量的非阻塞选择器线程管理客户端连接的读取和写入。 ... 和 TNonblockingServer 一样,它依赖于 TFramedTransport 的使用。

    这适用于派生自TNonblockingServer (reference) 的其他非阻塞服务器类:

    一个非阻塞的 TServer 实现。就调用而言,这允许所有连接的客户端之间的公平性。该服务器本质上是单线程的。如果您想要一个有限的线程池以及调用公平,请参阅 THsHaServer。要使用此服务器,您必须在最外层传输处使用 TFramedTransport,否则此服务器将无法确定何时已从线路中读取整个方法调用。客户端也必须使用 TFramedTransport。

    如果您不能在客户端使用TFramedTransport,则必须使用阻塞服务器,即TThreadPoolServerreference):

    服务器使用 Java 内置的 ThreadPool 管理来生成一个工作池,以阻塞方式处理客户端连接。

    您的代码将如下所示:

          TServerSocket serverTransport = new TServerSocket(9090);
          TThreadPoolServer.Args tArgs = new TThreadPoolServer.Args(serverTransport);
          tArgs.processor(processor);
          tArgs.protocolFactory(new TBinaryProtocol.Factory());
          TThreadPoolServer server = new TThreadPoolServer(tArgs);
    

    详细说明阻塞服务器和非阻塞服务器之间的差异(作为一般参考,如果您已经清楚差异,请致歉):阻塞意味着当从套接字读取数据时,不能进行其他操作,而读。所以当数据部分到达时,当前线程会一直等待,直到剩余数据到达。所以当阻塞服务器只有一个线程时,一次只能处理一个客户端。等待来自客户端的进一步数据所花费的时间不能用于为其他客户端提供服务。

    为了支持多个客户端,可以添加多个线程(就像 TThreadPoolServer 所做的那样)。和以前一样,每个线程一次只能处理一个客户端,因此可以同时服务的客户端数量受线程数量的限制。您当然可以生成许多线程,但这不能很好地扩展:支持 TThreadPoolServer 的 Java ThreadPool 使用的线程是系统级线程,因此它们带有一些资源开销用于创建和切换线程。因此,创建大量线程来为大量客户端提供服务意味着更多的时间花在操作系统记录任务上。

    非阻塞服务器(源自TNonblockingServer)旨在通过从其他客户端读取数据来利用等待来自一个客户端的数据所花费的时间来解决此问题。这样,单个线程可以处理多个客户端,从当前具有可用数据的任何客户端读取。非阻塞服务器当然也可以有多个线程,每个线程处理多个客户端。这样,线程的数量不必与客户端的数量成比例。相反,线程的数量可以与 CPU 内核的数量成比例地选择,然后在内核上运行的每个线程可以读取 I/O 带宽和 CPU 速度允许的尽可能多的数据。出于这个原因,非阻塞服务器可以更好地扩展客户端数量。

    因此,如果您必须同时处理大量客户端,则最好使用TNonblockingServer,并且最好找到一种方法将客户端切换为使用TFramedTransport。如果您的用例只处理有限数量的客户端,那么使用 TThreadPoolServer 而不修改客户端应该没问题,即使每个客户端都会产生大量数据。

    【讨论】:

    • 非常感谢。完美解决了我的问题
    猜你喜欢
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2014-12-09
    • 2023-04-11
    • 2016-03-28
    • 2014-07-04
    • 2018-01-20
    相关资源
    最近更新 更多