我正在运行一个简单的Thrift服务器(http://thrift.apache.org/)作为Python(服务器)和Haskell(客户端)之间的跨语言平台。需要发送的唯一数据结构是3元组的双精度数,因此服务器/客户端实现也非常简单 - 只需按照教程即可。
然而,它真的非常慢!当我需要大约0.1秒或更低的时间时,每个服务器响应的响应时间约为0.5秒。
有没有人对如何提高速度有任何想法?您可以在下面看到我的简单服务器实现:
1 import sys
2
3 from vision import Vision
4 from vision.ttypes import *
5
6 from thrift.transport import TSocket
7 from thrift.transport import TTransport
8 from thrift.protocol import TBinaryProtocol
9 from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated
10 from thrift.server import TServer
11
12 class VisionHandler:
13 def observe(self):
14 ret = Position()
15 ret.x,ret.y,ret.z = (1,2,3)
16 return ret
17
18 ret = Position()
20 handler = VisionHandler()
21 processor = Vision.Processor(handler)
22 transport = TSocket.TServerSocket(port=9090)
23 tfactory = TTransport.TBufferedTransportFactory()
24 pfactory = TBinaryProtocol.TBinaryProtocolFactory()
25
26 server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
27
28 print 'Starting the vision server...'
29 server.serve()
30 print 'done.'
客户端只需运行
即可查询此服务器36 client = do
37 handle <- hOpen ("localhost", PortNumber 9090)
38 let binProto = BinaryProtocol handle
39 return (binProto, binProto)
然后
res <- Client.observe =<< client
据我所知,这一切都很标准!为什么这么慢?
谢谢!
答案 0 :(得分:2)
除了Ellioh关于套接字选项的回答中的一个很好的建议之外,其中一个问题是你的操作似乎有点小而且很好,无法在套接字上处理,并且大部分时间花费在网络和类似的延迟上。通常会尝试将您的呼叫分组以传输更多数据,并在每次呼叫中执行更多工作。粒度在网络分布式应用程序中非常重要,您需要找到一个良好性能的良好衡量标准。
答案 1 :(得分:1)
最有可能是因为套接字选项。我不记得Thrift是否允许设置套接字选项,但设置TCP_NODELAY
以关闭拥塞控制有可能解决问题。
如果this与您使用的代码相同,则可以轻松访问套接字。尝试继承TSocket。
应该为两个服务器(从accept()返回的套接字)和客户端(客户端创建的套接字)端的套接字发送/接收数据设置选项。节俭并不慢,所以问题不应该是序列化,除非你序列化的东西真是太可怕了。这意味着问题在于所有“连接,发送数据,得到答案”的东西。几乎肯定应该是因为TCP_NODELAY
关闭了Nagle算法。