NodeJS 中 HTTP2 的一个诡异问题

340 天前
 iqoo

客户端和服务端都是 HTTP2 。

用 curl 从服务端下载数据可跑满服务器带宽(约 4MB/s ),用 NodeJS 的客户端下载只能跑到 1MB/s ,说明服务端没问题,可能是客户端的问题。

但奇怪的是,把客户端的测试 URL 换成网上某个 CDN 大文件时,也能达到很高的下载速度,这样看客户端也没问题。

这里附上精简后的代码。服务端:

import fs from 'fs'
import http2 from 'http2'

const h2Server = http2.createSecureServer({
  key: fs.readFileSync('ecc.key'),
  cert: fs.readFileSync('ecc.cer')
})

h2Server.on('stream', (stream) => {
  stream.on('error', () => {})
  stream.respond()

  const buf = Buffer.alloc(65536)
  const next = () => {
    stream.write(buf, err => {
      if (err) {
        stream.end()
      } else {
        next()
      }
    })
  }
  next()
}).listen(443)

客户端:

import http2 from 'http2'

const url = new URL('https://........')

const h2session = http2.connect(url, () => {
  const stream = h2session.request({
    ':path': url.pathname,
    ':authority': url.host,
  })
  stream.on('response', () => {
    let bps = 0
    stream.on('data', chunk => {
      bps += chunk.length
    })
    setInterval(() => {
      console.log('speed:', bps)
      bps = 0
    }, 1000)
  })
})

在本地跑看不出问题,毕竟本地通信带宽极大,放到服务器上就有问题了。不知是踩到哪个坑了。。。

1293 次点击
所在节点    程序员
8 条回复
july1995
340 天前
等一个大佬答复, 长长见识。
tool2d
340 天前
本地没问题,那肯定就是服务器机房触发了某种限速规则。

可以测试一下 http1 速度,我个人感觉和代码关系不大,http 是行业标准,nodejs 库不太可能出大问题。
iqoo
340 天前
@tool2d http1 没问题。和机房关系不大,测试了多个机房,都存在这个现象。

只要客户端和服务端都是 nodejs 的 http2 ,它们之间可能就会降速。尝试让双方都增加窗口大小也没用。
zbinlin
340 天前
抓个包来看下呀
luojiyin87
340 天前
捉包看网络收发窗口信息
rrfeng
340 天前
只能抓包看了
http2 有时候确实会带宽跑不起来。
dode
340 天前
wzy44944
339 天前
这种问题最好抓包看下窗口大小,要是接收端窗口太小的问题,可能是接收缓存设置的太小

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/943200

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX