eggjs / egg

🥚 Born to build better enterprise frameworks and apps with Node.js & Koa
https://eggjs.org
MIT License
18.91k stars 1.82k forks source link

一个 API 在请求第一次成功之后重复请求都超时 #4583

Open yunsii opened 3 years ago

yunsii commented 3 years ago

What happens?

一个神奇的 API 在服务启动后调用第一次时正常,等一下再调用 API 就都是超时了,奇怪的是我用 insomnia 随便怎么请求都不会报超时的。封装的其他 API 不会这样,分析测试了好久都没搞明白,所以不清楚是哪个环节出了问题,希望能够解答,谢谢。

image

最小可复现仓库

https://github.com/theprimone/egg-demo

复现步骤,错误日志以及相关配置

  1. 浏览器访问 http://127.0.0.1:7002/test?gid=1
  2. 稍等片刻再次访问则响应超时

image

相关环境信息

atian25 commented 3 years ago

可能是你代码逻辑问题,也可能是对方接口有做判断, postman 和 curl 请求的 headers 不一定一样,可以抓包分析下。

yunsii commented 3 years ago

可能是你代码逻辑问题,也可能是对方接口有做判断, postman 和 curl 请求的 headers 不一定一样,可以抓包分析下。

代码逻辑已经最简了,应该不可能。headers 我也试过就用 insomnia 请求日志里边打印的 headers 也是一样的问题 :joy: 另外如果出现这个超时的错误之后我马上重启 egg 还是能稳定复现这个问题,第一次成功,稍等片刻就都超时了。

JasinYip commented 3 years ago

我把你代码拉下来测过了,这个就是对方服务的问题,响应太慢了,要不然就是他们故意限制调用频率之类的。

你要不让他们修复这个问题,要不延长你的超时时间。如果这个数据是固定的,做个缓存,降低一下调用频率,try-catch 一下失败了重试。

yunsii commented 3 years ago

你要不让他们修复这个问题,要不延长你的超时时间。如果这个数据是固定的,做个缓存,降低一下调用频率,try-catch 一下失败了重试。

我也考虑过是不是有频率限制或者对于 headers 的检查,但我用 insomnia 客户端或者浏览器直接发起请求 https://api.snh48.com/m/getmtickets.php?gid=1 测试,随便怎么请求也都没碰到过响应超时的情况。要不你试试看?

JasinYip commented 3 years ago

@theprimone 确实和你说的一样,用浏览器是一切正常的。于是我推测两个可能,一是浏览器有 Cookie,二是 httpClient 的问题。通过测试带上 Cookie 请求问题依旧,配置 agent: falsehttpsAgent: falsekeep-alive 关闭,请求慢了一百多毫秒,但不再出现那个问题了,你要不也试试。

// app/service/index.js getData()
    const result = await this.ctx.curl(API, {
      method: 'GET',
      data: { gid },
      headers: {
        host: 'api.snh48.com',
        'user-agent':
          'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
        accept: '*/*',
      },
      agent: false,
      httpsAgent: false,
      dataType: 'text',
    });
yunsii commented 3 years ago

@JasinYip 试过是没问题了,所以能解释下什么原因吗?我业余折腾了两天,最后也怀疑是不是这个奇怪的 agent 配置的 _(:3J∠)_