url 调用内部函数导致超时
call internal function by url causes timeout
因为当我尝试通过本地主机调用函数时URL,会导致超时错误吗?
示例代码:
import tornado.ioloop
import tornado.web
import requests
import os
from threading import Timer, Thread
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
class TestTornado(tornado.web.RequestHandler):
def get(self):
url = "http://localhost:8888"
requests.get(url, timeout=5)
self.write("OK!")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
(r"/test", TestTornado),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
我尝试调用 http://127.0.0.1:8888/test,但生成了此错误:
`
Traceback (most recent call last):
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/tornado/web.py", line 1590, in _execute
result = method(*self.path_args, **self.path_kwargs)
File "server.py", line 14, in get
requests.get(url, timeout=5)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/sessions.py", line 524, in request
resp = self.send(prep, **send_kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/sessions.py", line 637, in send
r = adapter.send(request, **kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/adapters.py", line 529, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='localhost', port=8888): Read timed out. (read timeout=5)
`
进行此调用的正确方法是什么?
这是一个请求错误。
将此代码粘贴到您的程序中:
来自 requests.packages.urllib3.exceptions 导入 InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests
是一个 同步 库,而 Tornado 是一个 异步 框架。你不应该从 Tornado IOLoop
线程中调用像 requests.get()
这样的阻塞同步函数。您必须使 get()
成为协程并从线程池调用 requests.get()
:
async def get(self):
resp = await IOLoop.current().run_in_executor(None, lambda: requests.get(...))
或将 requests
的使用替换为类似 Tornado 的 AsyncHTTPClient
:
的非阻塞等价物
async def get(self):
client = tornado.httpclient.AsyncHTTPClient()
resp = await client.fetch(url, ...)
因为当我尝试通过本地主机调用函数时URL,会导致超时错误吗?
示例代码:
import tornado.ioloop
import tornado.web
import requests
import os
from threading import Timer, Thread
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
class TestTornado(tornado.web.RequestHandler):
def get(self):
url = "http://localhost:8888"
requests.get(url, timeout=5)
self.write("OK!")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
(r"/test", TestTornado),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
我尝试调用 http://127.0.0.1:8888/test,但生成了此错误:
`
Traceback (most recent call last):
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/tornado/web.py", line 1590, in _execute
result = method(*self.path_args, **self.path_kwargs)
File "server.py", line 14, in get
requests.get(url, timeout=5)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/sessions.py", line 524, in request
resp = self.send(prep, **send_kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/sessions.py", line 637, in send
r = adapter.send(request, **kwargs)
File "/home/mpimentel/envtornado/lib/python3.6/site-packages/requests/adapters.py", line 529, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='localhost', port=8888): Read timed out. (read timeout=5)
`
进行此调用的正确方法是什么?
这是一个请求错误。
将此代码粘贴到您的程序中:
来自 requests.packages.urllib3.exceptions 导入 InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests
是一个 同步 库,而 Tornado 是一个 异步 框架。你不应该从 Tornado IOLoop
线程中调用像 requests.get()
这样的阻塞同步函数。您必须使 get()
成为协程并从线程池调用 requests.get()
:
async def get(self):
resp = await IOLoop.current().run_in_executor(None, lambda: requests.get(...))
或将 requests
的使用替换为类似 Tornado 的 AsyncHTTPClient
:
async def get(self):
client = tornado.httpclient.AsyncHTTPClient()
resp = await client.fetch(url, ...)