【问题标题】:Close connection with python tornado http client on each call在每次调用时与 python tornado http 客户端关闭连接
【发布时间】:2017-10-10 09:28:04
【问题描述】:

我正在使用 tornado python 执行对外部代理服务的数百次非阻塞调用。 外部代理服务要求我在每次通话时都使用新连接。

我写了以下内容:

config = {
        'proxy_host': 'host',
        'proxy_port': port
    }

httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
for url in urls:
    client = httpclient.AsyncHTTPClient(force_instance=True)
    client.fetch(url, callback=callback, headers=headers, **config)
ioloop.IOLoop.instance().start()

   def handle_request()
       do_something()
       if io_counter == max_calls:
            ioloop.IOLoop.instance().stop()

但是,该服务声称我使用的是相同的连接。

如何在每次通话中使用不同的连接?

【问题讨论】:

  • 每个请求都是使用不同的套接字发出的,因此每个请求实际上是不同的连接。也许代理服务要求您使用不同的 IP 地址发出请求?
  • 不,他们没有。因为这是他们的服务——他们需要提供一个轮换代理 ID。在这种情况下我需要 force_instance=True 吗?
  • 我不能说。这个问题可能会有所帮助 - stackoverflow.com/q/21499722/1925257
  • 谢谢。将看到如何从这里开始

标签: python python-2.7 proxy tornado


【解决方案1】:

您想禁止libcurl 重用连接。快速回答是CURLOPT_FORBID_REUSE

复制

在 virtualenv 中执行pip install proxy.py tornado。打开两个终端窗口并激活 virtualenv。

test.py

import pycurl
from tornado import gen, ioloop, httpclient

urls = ['https://httpbin.org/uuid', 'https://httpbin.org/uuid']
proxy_config = {'proxy_host': '127.0.0.1', 'proxy_port': 8899}

def prepare(curl):
    # curl.setopt(pycurl.FORBID_REUSE, 1)
    pass   

@gen.coroutine
def main():
    client = httpclient.AsyncHTTPClient()
    for url in urls:
        kwargs = {}
        kwargs.update(proxy_config)
        kwargs['prepare_curl_callback'] = prepare
        response = yield client.fetch(url, **kwargs)
        print(response.body)

if __name__ == '__main__':
    httpclient.AsyncHTTPClient.configure(
        'tornado.curl_httpclient.CurlAsyncHTTPClient')
    ioloop.IOLoop.instance().run_sync(main)

#1 窗口

$ python test.py

#2 窗口

$ proxy.py --log-level DEBUG 2>&1 | grep -P "(Closing proxy|Proxying connection)"

第二个窗口应该输出如下内容:

2017-10-20 19:03:53,091 - DEBUG - pid:30914 - Proxying connection <socket._socketobject object at 0x7fc90f0fe0c0> at address ('127.0.0.1', 55202)
2017-10-20 19:03:53,695 - DEBUG - pid:30914 - Closing proxy for connection <socket._socketobject object at 0x7fc90f0fe0c0> at address ('127.0.0.1', 55202)

解决方案

现在取消注释curl.setopt(pycurl.FORBID_REUSE, 1),你会看到:

2017-10-20 19:05:19,492 - DEBUG - pid:30931 - Proxying connection <socket._socketobject object at 0x7f66de66e0c0> at address ('127.0.0.1', 55214)
2017-10-20 19:05:19,890 - DEBUG - pid:30931 - Closing proxy for connection <socket._socketobject object at 0x7f66de66e0c0> at address ('127.0.0.1', 55214)
2017-10-20 19:05:19,893 - DEBUG - pid:30932 - Proxying connection <socket._socketobject object at 0x7f66de66e280> at address ('127.0.0.1', 55218)
2017-10-20 19:05:20,279 - DEBUG - pid:30932 - Closing proxy for connection <socket._socketobject object at 0x7f66de66e280> at address ('127.0.0.1', 55218)

【讨论】:

  • 我不明白为什么这个答案被否决了。它似乎是正确的。
【解决方案2】:

我使用虚拟服务器尝试了您的示例,并且从未重复使用套接字。但是连接仍然打开。

尝试使用标头 Connection: closeProxy-Connection: close 指示服务器/代理在处理请求后关闭连接:

headers = {
  'Connection': 'close',
  'Proxy-Connection': 'close'
}

for url in urls:
  client = httpclient.AsyncHTTPClient(force_instance=True)
  client.fetch(url, callback=handle_response, headers=headers, **config)

【讨论】:

  • 'Connection': 'close',没有帮助。将尝试代理连接
猜你喜欢
  • 2020-02-10
  • 2021-03-25
  • 2021-04-07
  • 2015-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多