【问题标题】:Is a Singleton Apache Thrift client better than multiple client instances?Singleton Apache Thrift 客户端是否比多个客户端实例更好?
【发布时间】:2023-07-10 15:47:01
【问题描述】:

我有一个 thrift 服务器应用程序和另一个通过 apache thrift 与之通信的客户端应用程序。

3 个问题:

1 - 在我的客户端应用程序中,当创建一个节俭客户端并打开传输以进行通信时,通过保持传输在整个应用程序生命周期(也就是始终开启)中重用相同的客户端和传输作为单例更好吗?打开,或者创建一个新客户端,打开传输,然后在每次调用节俭服务器时关闭它会更好?

2 - 为什么?

3 - 就性能而言,它是否会改变任何东西(考虑通过同一个客户端打开和关闭传输和数据吞吐量的开销)?

【问题讨论】:

    标签: c# client-server thrift


    【解决方案1】:

    '1 和'2。带有 I/O 堆栈(proto/trans)的单个 Thrift 客户端代表单个连接。连接的设置和拆除成本相对较高,因此如果您经常使用客户端,保留它通常是个好主意。但是,客户端对象通常不是线程安全的,因此如果您的应用程序是多线程的,您将需要管理对客户端的访问,以便对 RPC 请求/响应操作进行序列化。

    '3.如果你经常发出 RPC 请求,打开和关闭连接会增加很多开销,所以通常最好保持连接打开。另一方面,如果您很少发出 RPC 请求,则在不使用连接时保持连接打开会占用服务器上的资源,因此最好为每个稀疏请求打开和关闭。

    我的建议是在真空中为每个独立线程创建一个客户端,但真正的答案是对每种情况进行试验并衡量结果,选择最快/最便宜的结果。

    【讨论】:

    • 我们不应该像这里提到的那样保留节俭的客户端池:layer4.fr/blog/2013/11/04/pooling-a-thrift-client 吗?我认为在多线程环境中保留客户端池是个好主意。
    • 如果您发出罕见的请求,池化不会减少服务器上的负载。如果您在所有线程上发出频繁的请求,则将客户端换入和换出池会减慢客户端的速度。如果您在一组线程中频繁发出请求,但没有一个线程是重度用户,那么池可能是一个不错的选择。了解应用程序正确答案的唯一方法是在每个模型的实际负载下对其进行测量。
    • 连接是什么意思?是传输还是套接字?
    • 我假设问题是指基于 TSocket 的传输连接。 “套接字”是一种抽象,在这种情况下,表示可连接的端点。 Apache Thrift 中的 TSocket 传输使用 TCP 连接来发出 RPC 请求。每个连接都会产生操作系统开销,因此目标是平衡操作系统开销与应用程序使用模式。 THttp 和 TNamedPipes 连接的注意事项也类似,但池/无池和连接持久性断点可能不同。