昨晚想用 emby看个电影,一直卡加载,于是再弄一下反代。让我疑惑的是,搞好反代之后依然是卡加载。即使我特地挑了一台带宽比较大的 vps 当反代。

于是我觉得可能是软件的问题,看了下 emby 有没有更新,发现没有更新。于是重装了下恢复默认设置,看不了。又看了下是不是 emby 设置有问题,搞了下视频渲染、图形接口、还有硬件加速。结果还是卡加载。
才发现emby这里要设置下

才发现emby这里要设置下

让我很疑惑,如果直接在 vps 上面用 wegt 下载 emby 的视频速度还挺快,用 idm 在本机上下载也是挺快的,但为什么就是一直加载呢?


今天早上起来又研究了下,换了台 ping emby 源站延迟比较低的美西 vps 反代就能正常观看了。


Emby 一直转圈加载的问题不在于网络带宽,而在于网络延迟(Latency)以及Emby播放器在这种高延迟网络下所采用的流媒体协议(HLS)

和 sfpt 传输文件夹龟速一样,emby 加载半天的原因也是单次传输的固定开销过大。

sfpt 每次传输文件需要在应用层重复“打开-操作-关闭”交互过程,所以文件夹的 n 个小文件就要重复 n 次。

如果是 cubic 的话。

  1. 把一整个视频文件,在服务器端“虚拟地”切成无数个几秒钟长短的小文件(视频切片),然后播放器一个一个地去请求、下载、播放。
  2. 连接刚建立时,它并不知道链路有多宽,所以它会从一个非常小的“拥塞窗口”(可以理解为初始速度)开始发送数据。
  3. 为了确认网络能够承受,它必须等待接收方(播放器)发回一个“确认收到了”的回执(ACK 包),然后才能把“窗口”加倍,提高速度。
  4. 因为整个代理链条(从播放器到VPS,再到源站)的端到端总延迟非常高,这个“确认回执”就需要很长时间才能返回给源站服务器。这就导致了TCP的“提速过程”极其缓慢。
  5. 那个几秒钟的小切片文件本身非常小。往往在 TCP 的拥塞窗口还没来得及扩大到能利用 10 MB/s 带宽的程度时,这个小切片就已经传输完毕了
  6. 紧接着,播放器又去请求下一个小切片,于是 TCP 又开始了一轮全新的、从零开始的“慢启动”和“漫长等待”。

因为我是 bbr+fq。每一次独立的HTTP请求(比如请求一个HLS切片),都需要经过一次TCP的“三次握手”。这个过程至少需要消耗一个RTT的时间,而在此期间,没有任何应用数据被传输。对于HLS这种需要成百上千次请求的协议,这部分固定的时间开销会迅速累积。简单来说就是 延迟*n

像 idm 和 wget 这种。wget 是单分片,在下载一个文件时,默认只会建立一个TCP连接,发起一次HTTP请求,然后就专心致志地、连续不断地接收数据流,直到整个文件下载结束。Idm 则是并行分片,但也就 8 片分片。而hls 这种是成百上千片,串行分片,效率就低了很多。

综上所述,emby 反代选择和源站延迟更低的 vps 更加重要。

这里解释下 bbr+fq:
bbr 能主动探测网络链路的最大容量和网络的最低延迟。瓶颈带宽 (Bottleneck Bandwidth),往返时间 (Round-trip Time)。
FQ 的全称是 FairQueuing(公平队列)。它会把不同的网络连接(视频流、网页、游戏数据等)放进各自的队列里,然后像发牌一样,公平地、轮流地从每个队列里取出数据包发送出去。这样就确保了下载大文件的请求不会完全阻塞需要快速响应的游戏或SSH请求。

Caddy 的反代设置

your.domain.com { # 这里写你用的域名
        reverse_proxy https://target.domain:443 { # 这里写反代的域名
                header_up Host {host}
        }
}
# /etc/caddy/Caddyfile

your.domain.com {
    reverse_proxy http://direct.zox.show {
        transport http {
            read_timeout 600s
            dial_timeout 10s
        }
        flush_interval -1
        header_up Host {upstream_host}
    }
}