碎碎念
技术圈总有一种“喜新厌旧”的倾向,觉得 HTTP/2 一定比 HTTP/1.1 好,HTTPS 一定比 HTTP 高级。
但这次经历狠狠地给我上了一课:没有最好的协议,只有最适合的场景。 对于高并发的小文件请求(比如加载网页图片、CSS),HTTP/2 是神;但对于简单粗暴的大文件管道传输(比如网盘上传),老旧的 HTTP/1.1 反而因为没有复杂的流控机制,跑得更快更欢。
现实世界里倒是迎来了好消息:网站备案初审今天顺利通过了! 目前已经正式进入 ICP 工信部审查阶段。看着进度条往前走,感觉离“正规军”的身份越来越近了。
现在的 8090 端口通了,HTTPS 也没问题了。下一步计划等 ICP 号下来,立马去攻克 公安部备案。虽然折腾,但看着这个“数字家园”从黑户变成双证齐全的合法公民,这种养成系的快乐确实无可替代。
周末愉快,继续折腾!
前言
刚刚搞定了浏览器 HSTS 强制跳转的“幽灵”问题,原本以为我的 HomeLab 终于可以完美运行在 HTTPS 的保护伞下了。
然而,现实总是喜欢在你不经意的时候给你一记重锤。当我兴冲冲地打开 OpenList 网盘,准备上传一部刚才下载的 4K 电影(测试内网速度)时,两个意想不到的问题接踵而至:
文件传不上去:大文件直接报错,小文件却正常。
速度慢到令人发指:原本 HTTP 下能跑满 10MB/s 的内网带宽,换了 HTTPS 后竟然跌到了 1.5MB/s。
这就好比给法拉利换了一把防盗锁,结果车门打不开,好不容易打开了,最高时速被锁死在 20 码。
正文内容
第一关:解决“上传失败” (413 Error)
现象: 上传几 KB 的文本文件一切正常,但只要上传超过 1MB 的图片或压缩包,进度条还没开始跑就直接报红,浏览器控制台显示 413 Request Entity Too Large。

原因: 这是一个 Nginx 的经典“新手坑”。Nginx 默认的 client_max_body_size(允许客户端请求的最大体积)只有 1M。这是为了防止恶意攻击占满服务器带宽,但对于网盘或博客应用来说,这个限制简直是灾难。
解决方案: 在 Nginx 配置文件中(server 或 location 块),手动解除这个封印。
Nginx
# 设置为 0 表示不限制大小,或者按需设置为 100m, 10g 等
client_max_body_size 0;
第二关:解决“速度暴跌” (HTTP/2 的锅)
现象: 解决了 413 错误后,文件能传了,但速度极其感人。
HTTP 协议下:上传速度稳定在 10MB/s(跑满百兆上行)。
HTTPS 协议下:上传速度断崖式下跌,只有 1.5MB/s 左右。
排查过程: 起初我怀疑是 SSL 加密消耗了太多性能,或者硬盘写入跟不上。于是我一边上传一边在服务器运行 top 命令监控:
CPU:Nginx 占用仅 1.7%,空闲率 98% -> 排除算力瓶颈。
IO:wa (IO Wait) 仅 0.3% -> 排除硬盘瓶颈。

既没算加密,也没写硬盘,那 Nginx 在干嘛?它在“等”。
真凶:HTTP/2 的流控机制 为了追求现代化,我在配置 HTTPS 时顺手(实际上是抄别人作业的时候)开启了 http2。 虽然 HTTP/2 对网页加载(多路复用)有奇效,但它在处理大文件上传(单一长连接大数据流)时,由于复杂的窗口更新(Window Update)机制,客户端和服务器需要频繁交互确认“还能发多少”,导致大量时间浪费在握手上,而不是传输数据。
解决方案: 返璞归真,去掉 http2,回退到更简单粗暴但适合持续传输的 HTTP/1.1。
修改 Nginx 配置文件:
Nginx
# 修改前:listen 5244 ssl http2;
# 修改后:去掉 http2
listen 5244 ssl;
重载配置后,奇迹发生了:上传速度瞬间回到了 9-10MB/s 的满速状态!
终极配置
结合以上两个坑,以及针对家庭宽带 MTU 的分片优化,总结出了一套适合 HomeLab(Halo/AList/OpenList)的 Nginx 最佳配置:
Nginx
server {
# 1. 【速度核心优化】去掉 http2
# 这一步是解决上传速度慢(从 1.5MB/s -> 10MB/s)的关键
listen 8091 ssl;
server_name www.yanchang.cc;
ssl_certificate /etc/nginx/ssl/www.yanchang.pem;
ssl_certificate_key /etc/nginx/ssl/www.yanchang.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# 2. 【网络层优化】减小 SSL 缓冲区
# 适配家庭宽带 MTU,减少丢包和卡顿
ssl_buffer_size 4k;
# 3. 【解除封印】解除上传大小限制
# 虽然你写了 1000m,但 0 (不限制) 是更通用的写法
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:8090; # Halo 的端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 4. 【IO 性能优化】关闭缓冲
# Halo 上传附件、主题包时,直接转发,不写临时文件,速度更快
proxy_request_buffering off;
proxy_buffering off;
# 5. 【连接稳定性】增加超时时间
# 防止上传大主题包或备份文件时超时
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
# ========================================================
# 6. 【HSTS 修复】这两行绝对不能删!
# 这是为了防止浏览器强制把你的 8090 端口跳转到 HTTPS
# ========================================================
proxy_hide_header Strict-Transport-Security;
add_header Strict-Transport-Security "max-age=0" always;
}
}PhotoPrism 相册服务报错刷屏主力是: WebSocket connection to 'wss://yanchang.cc:2343/api/v1/ws' failed
1. 报错原因分析
现象:你的浏览器试图建立 WebSocket 连接(
wss://),用于实时通信(比如 Halo 的控制台日志、PhotoPrism 的索引进度等),但连接建立失败,一直在无限重连。原因:Nginx 默认只转发标准的 HTTP 请求。当浏览器发起 "Upgrade" 请求试图把 HTTP 升级为 WebSocket 协议时,如果 Nginx 没有显式配置转发 Upgrade 头,它就会把这个请求拦截下来,导致连接失败。
其他报错(如
maps.photoprism.app和translate.google.com):这些是网络问题。PhotoPrism 试图加载地图,Halo/浏览器试图加载谷歌翻译,但因为众所周知的网络原因(服务器在国内无法连接谷歌/外部地图源),导致连接超时。这部分通常不影响核心功能,可以忽略。
解决方案
我们需要修改 2343 端口 的 Nginx 配置文件,在 location / 块中显式开启 WebSocket 支持。
请使用以下修复版配置(在之前的终极版基础上,加入了 WebSocket 专用配置):
server {
# 1. 【端口与协议】
# 使用 2343 端口 (SSL),强制 HTTP/1.1 以确保大文件传输速度
listen 2343 ssl;
server_name www.yanchang.cc;
# 2. 【证书配置】
ssl_certificate /etc/nginx/ssl/www.yanchang.pem;
ssl_certificate_key /etc/nginx/ssl/www.yanchang.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# 3. 【网络分片优化】适配家庭宽带 MTU
ssl_buffer_size 4k;
# 4. 【解除限制】允许上传超大视频/照片
client_max_body_size 0;
location / {
# 指向 PhotoPrism 内部端口 (通常是 2342)
proxy_pass http://127.0.0.1:2342;
# 标准头部
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# =======================================================
# 5. 【关键修复】WebSocket 支持
# PhotoPrism 的索引进度条、通知都需要这个,否则会一直报错
# =======================================================
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 6. 【IO 性能优化】关闭缓冲
# 照片视频直接直通后端,不写 Nginx 临时文件
proxy_request_buffering off;
proxy_buffering off;
# 7. 【长连接超时】大幅延长
# PhotoPrism 处理 AI 识别和转码非常慢,给足 1 小时超时时间
proxy_connect_timeout 3600s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
send_timeout 3600s;
}
}