问题描述

在使用域名请求接口时,有两个地方会出现超时,连接超时读取超时

关于接口服务器响应超时

可以在本地搭建测试环境。

  1. 搭建测试接口服务器
from bottle import Bottle, run
import time

app = Bottle()

# URL地址为 /sleep/需要睡眠的时长
@app.route("/sleep/<sleep:int>")
def spleepDef(sleep):
    time.sleep(sleep)
    return "sleep time is %s" % sleep
# 可更改 port 为需要监听的接口
run(app, host="0.0.0.0", port=8888, debug=True, reloader=True)

需要有bottle包,使用以下命令安装

pip install bottle
  1. 测试代码
from requests.adapters import HTTPAdapter
from requests import Session
import requests

session = Session()
# request 重试配置 重试一次
# 如果发生读取异常,则请求时间为 (重试次数+1) * 超时时间
# 例如 超时3秒,重试1次,则出现异常是请求时间为 6秒
session.mount("http://", HTTPAdapter(max_retries=1))
session.mount("https://", HTTPAdapter(max_retries=1))

for i in range(1, 4): # 请求3次,休眠时间依次增加
    url = "http://dn03:8888/sleep/%s" % i
    print(url)
    try:
        res = session.get(url, timeout=(2, 3))
    except requests.exceptions.Timeout as e:
        print("连接超时 %s" % e)
    except requests.exceptions.ConnectionError as e:
         print("读取数据超时 %s" % e)
    else:
        print(res.text)
    print()
  1. 测试读取超时

运行测试代码之后,出现以下情况

python response 相应时间 python resplit_python


python response 相应时间 python resplit_爬虫_02


python response 相应时间 python resplit_爬虫_03


python response 相应时间 python resplit_服务器_04

从上面的日志信息,可以看出API请求了3次,但是因为加了一次重试,web服务接受了4次请求,最后的错误是读取超时错误。

也就是说 requests.exceptions.ConnectionError 异常捕获到了读取超时错误。

测试连接超时错误

将2的代码改为一下方式,可以看到连接超时错误,元祖的第一个元素是连接超时

- res = session.get(url, timeout=(2, 3))
+ res = session.get(url, timeout=(0.0001, 3))

web服务器没有接收到任何请求

python response 相应时间 python resplit_连接超时_05

python response 相应时间 python resplit_服务器_06

从上述日志可以看出,如果是连接超时的错误,服务器是不会接收到请求的,而且会被requests.exceptions.Timeout捕获到。

还有网关的问题

如果requests连接到网关之后,网关请求后面的数据,此时超时的话,不会出现连接超时异常,只会出现读取超
,一个很简单的例子就是:还是上面的代码,测试读取超时处,打开Fiddler,此时会看到即使连接超时>
设置的非常非常小,还是不会出现连接超时的异常,能成功连接服务器,之后会出现读取超时。跟我们预想的情况不
一样。

所以我们需要非常小心这样的情况,在连接到网关之后,网关找相应的服务,服务进行业务操作,服务返回给网关,网
关返回给requests,这一段时间都是属于requests的读取超时内的