You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTTP2协议文件上传超时/速度慢问题求助及Nginx配置优化需求

环境信息

  • nginx版本:nginx/1.23.3
  • JS上传工具:axios
  • 接口URI:/fp01/upload

测试情况

使用HTTP协议(http1.1)上传,一切正常

图片描述

使用HTTPS协议(http1.1)上传,一切正常

图片描述

使用HTTP2协议上传,出现超时

图片描述

当前Nginx配置(/fp01/为文件上传接口)

server {
  listen 80;
  listen 443 ssl http2;

  ssl_certificate /usr/local/nginx/conf/ssl/key.cer;
  ssl_certificate_key /usr/local/nginx/conf/ssl/key.key;

  ssl_session_timeout 5m;
  # 空闲连接的超时时间
  http2_idle_timeout 5s;
  # 每个 HTTP/2 连接允许的最大并发流量数量
  http2_max_concurrent_streams 100;
#  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_protocols TLSv1.2;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  ssl_prefer_server_ciphers on;
  ssl_stapling on;
  ssl_stapling_verify on;

  server_name  localhost;

  charset utf-8;
  client_max_body_size 100M;
  client_body_buffer_size 512k;

  proxy_set_header REMOTE-HOST $remote_addr;
  proxy_set_header X-Real-IP    $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-NginX-Proxy true;
  proxy_pass_request_headers on;

  gzip  on;
  #低于1kb的资源不压缩
  gzip_min_length 1k;
  #压缩级别1-9,越大压缩率越高,同时消耗cpu资源也越多,建议设置在5左右。
  gzip_comp_level 5;
  #需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片.
  gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
  #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
  gzip_disable "MSIE [1-6]\.";
  #是否添加“Vary: Accept-Encoding”响应头
  gzip_vary on;

  proxy_connect_timeout 120s;
  proxy_read_timeout 120s;
  proxy_send_timeout 120s;
  send_timeout 120s;

  # 转发时带上所有请求头
  underscores_in_headers on;

  ### 删除文件接口
  location /fp01/ {
    proxy_pass http://127.0.0.1:31600/;
    proxy_set_header Host $http_host;
  }
}

后续测试与问题

将超时时间设置为600000后,HTTP2协议下上传成功,但速度远低于预期。通过Fiddler抓包发现,同时发送4个请求仅占用1个TCP连接。

以下是curl测试结果:

/ # curl -v --http2 'https://mydoname.com/fp01/upload' \
>   -X 'PUT' \
>   -H 'authority: mydoname.com' \
>   -H 'authorization: bearer b41a181d-6f2b-4246-9d77-f7ad96c43383' \
>   -F 'hash="000000"' \
>   -F 'file=@"rootfs.ext2"' \
>   --trace-time
05:08:54.043222 *   Trying 183.2xx.xxx.xx:443...
05:08:54.081110 * Connected to mydoname.com (183.2xx.xxx.xx) port 443 (#0)
05:08:54.081420 * ALPN: offers h2,http/1.1
05:08:54.081720 * TLSv1.3 (OUT), TLS handshake, Client hello (1):
05:08:54.091087 *  CAfile: /cacert.pem
05:08:54.091144 *  CApath: none
05:08:54.125776 * TLSv1.3 (IN), TLS handshake, Server hello (2):
05:08:54.125906 * TLSv1.2 (IN), TLS handshake, Certificate (11):
05:08:54.126402 * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
05:08:54.126562 * TLSv1.2 (IN), TLS handshake, Server finished (14):
05:08:54.126823 * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
05:08:54.126919 * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
05:08:54.127056 * TLSv1.2 (OUT), TLS handshake, Finished (20):
05:08:54.164470 * TLSv1.2 (IN), TLS handshake, Finished (20):
05:08:54.164537 * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
05:08:54.164581 * ALPN: server accepted h2
05:08:54.164625 * Server certificate:
05:08:54.164681 *  subject: C=CN; ST=xxx; L=xxx; O=xxx; CN=mydoname.com
05:08:54.164727 *  start date: Feb 28 02:57:27 2023 GMT
05:08:54.164771 *  expire date: Feb 28 02:57:27 2024 GMT
05:08:54.164820 *  subjectAltName: host "mydoname.com" matched cert's "mydoname.com"
05:08:54.164868 *  issuer: C=CN; O=China Financial Certification Authority; CN=CFCA OV OCA
05:08:54.164911 *  SSL certificate verify ok.
05:08:54.165081 * using HTTP/2
05:08:54.165187 * h2h3 [:method: PUT]
05:08:54.165231 * h2h3 [:path: /fp01/upload]
05:08:54.165274 * h2h3 [:scheme: https]
05:08:54.165316 * h2h3 [:authority: mydoname.com]
05:08:54.165359 * h2h3 [user-agent: curl/8.0.1-DEV]
05:08:54.165401 * h2h3 [accept: */*]
05:08:54.165444 * h2h3 [authority: mydoname.com]
05:08:54.165487 * h2h3 [authorization: bearer b41a181d-6f2b-4246-9d77-f7ad96c43383]
05:08:54.165530 * h2h3 [content-length: 10486062]
05:08:54.165573 * h2h3 [content-type: multipart/form-data; boundary=------------------------dce527c313b24353]
05:08:54.165620 * Using Stream ID: 1 (easy handle 0x7fd0bb760aa0)
05:08:54.165718 > PUT /fp01/upload HTTP/2
05:08:54.165718 > Host: mydoname.com
05:08:54.165718 > user-agent: curl/8.0.1-DEV
05:08:54.165718 > accept: */*
05:08:54.165718 > authority: mydoname.com
05:08:54.165718 > authorization: bearer b41a181d-6f2b-4246-9d77-f7ad96c43383
05:08:54.165718 > content-length: 10486062
05:08:54.165718 > content-type: multipart/form-data; boundary=------------------------dce527c313b24353
05:08:54.165718 > 
05:08:55.586694 * We are completely uploaded and fine
05:08:56.270729 < HTTP/2 200 
05:08:56.270788 < server: nginx/1.23.3
05:08:56.270832 < date: Wed, 12 Apr 2023 05:08:56 GMT
05:08:56.270876 < content-type: application/json
05:08:56.270921 < content-length: 70
05:08:56.270964 < vary: Origin
05:08:56.271022 < vary: Access-Control-Request-Method
05:08:56.271065 < vary: Access-Control-Request-Headers
05:08:56.271108 < expires: 0
05:08:56.271151 < cache-control: no-cache, no-store, max-age=0, must-revalidate
05:08:56.271194 < x-xss-protection: 1; mode=block
05:08:56.271237 < pragma: no-cache
05:08:56.271279 < x-frame-options: DENY
05:08:56.271322 < x-content-type-options: nosniff
05:08:56.271365 < referrer-policy: no-referrer
05:08:56.271408 < 
{
    "code":4,
    "filename":"中体量数据.gdb.zip",
    "hash":"000000"
05:08:56.271486 * Connection #0 to host mydoname.com left intact
}/ # 

问题求助

  1. 如何优化HTTP2协议下的文件上传速度?
  2. 如何让/fp01/upload接口强制使用HTTP1.1协议?

解决方案

1. 优化HTTP2文件上传速度的方法

  • 调整HTTP2空闲超时时间:当前http2_idle_timeout 5s过短,大文件上传时易触发超时,建议调整为60s或更长:
    http2_idle_timeout 60s;
    
  • 增大客户端请求缓冲区:client_body_buffer_size 512k对于大文件上传偏小,可调整为分段缓冲区,比如:
    client_body_buffer_size 10M;
    
    减少磁盘IO次数,提升传输效率。
  • 优化TCP参数:在server块中添加以下配置,提升底层传输性能:
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
  • 检查后端服务并发能力:确保后端(127.0.0.1:31600)能同时处理多个HTTP2流请求,避免单流阻塞拖慢整体速度。
  • 调整HTTP2并发流上限:若后端支持更高并发,可适当调大http2_max_concurrent_streams,比如设置为200。

2. 强制/fp01/upload接口使用HTTP1.1的方法

有两种常用配置方式:

方式一:单独配置特定URI的location
# 优先匹配上传接口,强制使用HTTP1.1
location = /fp01/upload {
    proxy_pass http://127.0.0.1:31600/upload;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}

# 处理/fp01/下的其他请求
location /fp01/ {
    proxy_pass http://127.0.0.1:31600/;
    proxy_set_header Host $http_host;
}
方式二:使用map指令批量匹配

在http块中添加规则:

http {
    map $request_uri $force_http11 {
        ~^/fp01/upload 1;
        default 0;
    }
    # ... 其他http配置 ...
}

然后在server块的location中应用:

location /fp01/ {
    proxy_pass http://127.0.0.1:31600/;
    proxy_set_header Host $http_host;
    if ($force_http11) {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

注:proxy_set_header Connection ""用于清除HTTP2连接中的Connection头,避免协议冲突。


内容的提问来源于stack exchange,提问作者何呵呵

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:37:02