我有以下情况:
我有一个 Web 服务,可根据单个用户请求聚合来自某些第三方服务器的数据。对第三方的请求可以是 SOAP 或带有 XML 数据的普通 urllib2 请求,每个请求都在单独的线程中完成。
这是我正在做的事情的总体情况:
ThirdParty1(Thread):
def run(self):
try:
result = SOAPProxy('http://thirdparty.com', timeout=2).method(params)
dostuff_and_save(result) # save results on database
except Exception:
log.warn('Ooops')
ThirdParty2(Thread): ...
def myview(params):
thread = [ThirdParty1(), ThirdParty2()]
for t in thread: t.start()
for t in thread: t.join(timeout=2)
return result # this is actually just a token, that I use to retrieve the data saved by the threads
我当前的问题是当任何第三方服务器挂在他们身边时,可靠地返回对我用户请求的响应。我试图在线程连接、SOAPProxy 对象上设置超时,并执行socket.setdefaulttimeout
. 不遵守任何超时。
我设法挖掘了 SOAPProxy 问题,发现它使用 httplib,而 httplib深入使用 socket.makefile(),文档说:
socket.makefile([mode[, bufsize]])
返回与套接字关联的文件对象。(文件对象在文件 > 对象中描述。)文件对象引用套接字文件描述符的 dup()ped 版本,因此 > 文件对象和套接字对象可以独立关闭或垃圾收集。套接字必须处于阻塞模式(不能有超时)。可选模式和 bufsize 参数的解释方式与内置 file() 函数相同。
我发现的所有其他 SOAP 库,都以一种或另一种方式使用 httplib。为了使事情复杂化,我可能需要从请求线程访问数据库,我不完全理解用这种策略杀死线程的后果是什么,我正在考虑从线程外部做数据库的东西,当那个是可能的。
然后,我的问题是:
当不遵守超时时,我的 Web 服务如何及时响应用户并优雅地处理行为不良的第三方服务器?
HTTPResponse 使用 makefile 的事实可能没有我想象的那么糟糕,事实证明默认情况下它makefile
实际上是非缓冲的,并且它可以引发超时异常,这是我尝试过的:
在一个控制台上,我netcat -l -p 8181 '0.0.0.0'
在另一个控制台上打开python2.7
并运行:
>>> import socket
>>> af, socktype, proto, canoname, sa = socket.getaddrinfo('0.0.0.0', 8181, 0, socket.SOCK_STREAM)[0]
>>> s=socket.socket(af, socktype, proto)
>>> s.settimeout(.5)
>>> s.connect(sa)
>>> f=s.makefile('rb', 0)
>>> f.readline()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/socket.py", line 430, in readline
data = recv(1)
socket.timeout: timed out
但是我如何做可靠的第三方请求的问题仍然存在。