【发布时间】:2014-02-24 19:30:59
【问题描述】:
我已经尝试解决这个问题大约一周了。要么我遗漏了一些非常明显的东西,要么问题出在 API 的服务器端,要么服务器故意拖延我(我用 python 编码)。
我想做什么:
- 我正在尝试获取财务数据(所有市场的市场深度更好)。问题是交易所服务的 api 只支持只获取一个市场的数据(总共大约 75-85 个,变量)所以我决定为每个市场启动一个线程
- 每个线程将处理一个市场,尝试获取该市场的数据,如果成功返回,否则将市场重新添加到队列中,稍后由新线程处理
- 执行此操作,直到覆盖所有市场,并无限期重复以保持数据最新
我使用请求库在 python 中对此进行了编码。它适用于几次迭代,但随后服务器停止响应。为了克服这个问题,我在 requests.get 中添加了超时。它超时,但服务器也没有响应新的查询,大约 1 分钟。然后一切都顺利进行了几次迭代,然后一切都停止了,然后重复。
这是python代码。
import requests, json
import thread, threading
from time import sleep, clock
#Get queue
conn = requests.get('http://data.bter.com/api/1/pairs/')
mainQueue = json.loads(conn.content)
conn.close()
#Variable globals
marketCount = 0
queue = mainQueue[:]
#Static globals
lock = threading.Lock()
completeSize = len(queue)
def getOrderData(marketid):
global queue, marketCount
try:
data = requests.get(str('http://data.bter.com/api/1/depth/'
+marketid), timeout = 3)
except:
with lock:
print "Timed out: %s" % marketid
queue.append(marketid)
return
with lock:
marketCount += 1
data.close()
return
while True:
print "##################################"
#Initialize data
crT = clock()
marketCount = 0
queue = mainQueue[:]
#Start retrieving all markets
while marketCount != completeSize:
while len(queue) == 0 and marketCount != completeSize:
sleep(0.01)
if marketCount != completeSize:
marketid = queue.pop(0)
thread.start_new_thread(getOrderData, (marketid,))
#Print time spent
print "Finished, total time:",clock()-crT
sleep(1)
这是程序在运行时的行为方式。
完成表示我获得了所有财务数据一次,并开始再次更新。如您所见,似乎一切正常,然后开始停止,超时。突然之间,一切又开始正常工作了。我还注意到,在我用 data.close() 关闭 get 连接后,一个状态为 TIME_WAIT 的 tcp 连接会在 tcp 监控程序中保留很长时间。经过几次迭代后,它们有很多,只是在 TIME_WAIT 状态下等待。
所以,这是我的问题
- 是否有可能在所有保持在 TIME_WAIT 状态的 TCP 连接中,正在等待服务器向它们发送某种信号以释放它们?如果是这样,服务器是否可能因为我同时有太多(活动?活动?)连接而停止响应我?
- 如果不是,为什么我的所有 get 请求都超时的停滞期会发生?是因为服务器可能对每个客户端每分钟的查询有限制吗?当我到达那个位置时,大约一分钟后,它神奇地又开始正常工作了,
- 我有 TONS 和 TONS 的 TCP 连接处于 TIME_WAIT 状态等待,并且它们不断累积。 (我一开始大概每秒80个连接,如果4分钟就可以完全释放连接,那就是累积了19200个连接)怎么解决,有问题吗?
- 我启动了很多线程。有问题吗?
- 以线性方式获取所有数据,一个接一个的市场不是一种选择,太慢,数据会过时。还有什么其他方法可以让整个市场数据保持最新?(最多 3 秒)
- 还有什么要告诉我的吗?
我知道我的代码还没有保存数据。我只是想先得到它。代码很糟糕,但由于我正在测试一个简短的片段,所以我没有理会评论(我改变了很多次试图找到一种方法)
提前致谢。我真的希望我能克服这个。
【问题讨论】:
标签: python multithreading api tcp python-requests