首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
OPPO Watch
ksc010
V2EX  ›  Python

非常奇怪的 requests 库请求 flask 的问题,会有一个超时

  •  
  •   ksc010 · 152 天前 · 3028 次点击
    这是一个创建于 152 天前的主题,其中的信息可能已经有所发展或是发生改变。
    >>> flask.__version__
    '1.0.2'
    >>> requests.__version__
    '2.22.0'

    -------------------

    requests 请求 flask 提供的接口 会有一个 2s 的延迟,即使这个接口嘛都不做 直接返回'ok'

    也就是 requests 开始请求到收到响应的数据至少需要 2s
    但是 若给 requests 设置一个超时参数比如 1s 这延迟就会减少到 1s
    设置 0.2 就会减少到 0.2
    requests.post(apiurl, json=jsondata, timeout=(0.2, 3.2))
    这个延迟应该是 connect 的超时
    当然直接 post(xxxxx, timeout=0.2) 也可以
    17 条回复    2019-12-29 17:09:08 +08:00
    ksc010
        1
    ksc010   152 天前
    还有一个情况就是
    requests 请求 nginx 正常
    浏览器请求 flask 正常
    privatezcoding
        2
    privatezcoding   152 天前   ❤️ 1
    你电脑是不是开了代理
    ksc010
        3
    ksc010   152 天前
    @privatezcoding 对 但是不是系统代理 需要显示的指定端口
    wuwukai007
        4
    wuwukai007   152 天前   ❤️ 1
    打个断点看下 flask 接受请求的事件是不是延迟了,用 urllib 和 curl 都请求下试试呢
    gwy15
        5
    gwy15   152 天前 via Android   ❤️ 1
    我上次写单元测试也遇到这个问题,后来发现是 DNS 花了 2s。楼主换成裸 ip 试试
    ksc010
        6
    ksc010   152 天前
    @wuwukai007
    curl 和浏览器一样 没有延迟

    requests 就不行
    requests.get('http://localhost:8080',timeout=2).text 就这一行代码 明显感觉延迟了

    --------------------
    flask 启动参数
    app.run(port=self.port, host=self.host, threaded=True)
    lenqu
        7
    lenqu   152 天前   ❤️ 1
    或者 f12 查看一下开发工具里统计的延迟
    ksc010
        8
    ksc010   152 天前
    @gwy15 擦 果然是
    localhost 换成 127.0.0.1 就好了
    gwy15
        9
    gwy15   152 天前   ❤️ 1
    @ksc010
    我上次就是这么写的,localhost 换成 127.0.0.1 之后就没问题了
    lenqu
        10
    lenqu   152 天前
    @gwy15 难道是返回 fstab 解析的问题?
    smallpython
        11
    smallpython   152 天前
    把 localhost 转换为 127.0.0.1 这件事情是谁做的?为什么会有两秒的延迟
    ksc010
        12
    ksc010   152 天前
    @gwy15 之所以没往 dns 这方面想
    是因为记得 请求内网服务器上的接口也是慢(通过内网 ip 10.1.1.22:8080 )
    然后一直测试本地的接口(通过 localhost:8080 )
    在你说直接使用 ip 之后 又测试了下内网服务器接口 发现速度正常了(这个可能是其他的问题引起的 但是现在没有复现)

    总之非常感谢
    wybhdxfx
        13
    wybhdxfx   152 天前
    学习了,平常我也习惯用 127.0.0.1,少用 localhost。
    ClericPy
        14
    ClericPy   152 天前
    看标题没看懂... 看到最后才知道说的是啥...

    也不知道什么时候开始, Windows10 和 macOS 默认的 hosts 里都有一句 ipv6 版本的 localhost, 不确定是自带的还是被什么改的
    gwy15
        15
    gwy15   152 天前   ❤️ 3
    我跟踪了一下,跟踪到了
    `urllib3.util.connection.create_connection`
    这个函数里面。

    这个函数做的是根据 host 和 port 建立 socket 连接。当使用 localhost 的时候,会调用
    `for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM)`
    这样一个循环。对于 `localhost`,会返回两个结果:

    + ::1 (ipv6 下的 localhost)
    + 127.0.0.1 (ipv4 下的 localhost)

    根据循环,会首先尝试连接 `::1`,而如果 flask 使用的是默认的 host 或是 0.0.0.0,只会监听 ipv4 的请求,因此 ipv6 会抛出 NewConnectionError,而后继续尝试 ipv4 的请求。这就是两秒延迟的原因。

    解决方法:
    + 使用 app.run(host='::') 调试,使 flask 监听 ipv6,这样第一个尝试的 `::1` 也可以正常连接。
    + 使用 requests.get('127.0.0.1'), 避免 DNS 解析。
    nznd
        16
    nznd   152 天前
    让我想到了这个帖子 /t/623596
    从这之后我的本地测试全部是指定内网 ip, 不再用 localhost 了
    deplives
        17
    deplives   149 天前
    很早之前在 sof 上我就看到一个问题大概类似,底下回答基本上都是不要用 localhost 虽然那个问题我没遇到过,但从那之后我也不用 localhost 了
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1669 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:43 · PVG 07:43 · LAX 16:43 · JFK 19:43
    ♥ Do have faith in what you're doing.