Frankom

家里两电信一移动三条宽带,单线程 上行成功聚合到 150M,从原先 50M

  •  
  •   Frankom · 1 day ago · 1217 views

    家里现在有三条宽带,两条电信一条移动,下行都还可以,但上行每条只有 40-60M 。家里放了台 NAS ,人在外面的时候经常要从上面拉文件,速度就卡在其中一条线的上行上,几个 G 的东西要等很久。

    先看三条线各自的情况(爱快线路测速):

    img

    三条加起来上行大约 150M 左右。

    之前也试过爱快的多线负载,但那个是按连接分流的,开多线程测速确实好看,可单个连接(比如传一个大文件)只会走其中一条线,上行还是 40-60M 。

    想让单个连接也叠加,就只能把这个连接的数据拆开,同时走三条线路发出去,再在另一头拼回来。所以另一头也得有个节点配合:家里这头负责拆,外面那头负责拼,思路和 MPTCP / OpenMPTCProuter 是一类的。拆和拼都在两头的节点上完成,NAS 和外面访问它的设备都不用动,跑的还是普通 TCP 。

    具体是把连接里的数据切成 16 KB 一段、按顺序编号,三条线各自按实测的速度和延迟去领下一段(快的线领得多),对面按编号排好再交出去;哪条线断了或者卡住,没确认的段换到别的线重发,所以掉一条线连接也不会断。大概实现思路:

    // 切成 16 KB 一段,头部写上编号和长度;每条线一个协程,发完一段再去领下一段,
    // 所以快的线自然领得多。接收端按编号排好顺序再交出去。
    func send(src io.Reader, lines []io.Writer) {
    	queue := make(chan []byte, len(lines))
    	go func() {
    		defer close(queue)
    		for seq := uint64(0); ; seq++ {
    			buf := make([]byte, 12+16<<10)
    			n, err := io.ReadFull(src, buf[12:])
    			if n > 0 {
    				binary.BigEndian.PutUint64(buf, seq)
    				binary.BigEndian.PutUint32(buf[8:], uint32(n))
    				queue <- buf[:12+n]
    			}
    			if err != nil {
    				return
    			}
    		}
    	}()
    	var wg sync.WaitGroup
    	for _, w := range lines {
    		wg.Add(1)
    		go func(w io.Writer) {
    			defer wg.Done()
    			for seg := range queue {
    				w.Write(seg)
    			}
    		}(w)
    	}
    	wg.Wait()
    }
    

    把这个思路用到我的自用面板上。两条电信有公网直连,移动那条没有公网,是靠 UDP 打洞连上的。下面是面板里家里这个节点的详情,两个地址是电信那两条,打洞 那一条就是移动:

    走聚合,三条连接就会一起用上:

    测试用的是 iperf3 单连接,测的是家里的上行。左边是不聚合(只走一条线),右边是三条聚合:

    • 不聚合:接收端平均 52.7 Mbits/sec
    • 聚合:接收端平均 146 Mbits/sec

    146 差不多就是三条上行加起来的 147 ,而且是单个 TCP 连接,不是多线程叠出来的。

    实测从家里 NAS 往外拉一个大文件,单个下载也能稳在 17 MB/s 左右,也就是 136 Mbps 上下:

    img

    目前用下来,在外面从 NAS 拉文件明显快了很多。

    9 replies  •  2026-11-05 19:14:30 +08:00
    LightningAlpaca
    1
    感觉这个方案只适合单线的大文件传输啊,还有被动态 qos 的影响会比较大,你们那边应该是 qos 规则比较宽松了
    Frankom
    Frankom
    OP
    1 day ago
    2
    @LightningAlpaca 聚合线路主要受益的就是单线,多线本来就能依靠配置负载均衡跑满,但多数场景下单线速度会更有用一些。实际上我两端是跨省的,上面的速度特意在昨天晚高峰时测试的,暂时没有明显遇到 qos ,也可能和我用 hy2 协议+端口跳跃有关。
    maoshen1234
    maoshen1234
    1 day ago
    3
    收藏了,看看有没有更方便的方式,比如部署在 NAS 或者 windows 上
    cjd6568358
    cjd6568358
    1 day ago
    4
    感觉很像 x-ray mux 反向场景?
    Frankom
    Frankom
    OP
    1 day ago
    5
    @maoshen1234 只要 nas 系统支持 docker 就可以部署。
    @cjd6568358 和 mux 原理不同的。我这场景是直连,没用到反向;反向也是可行的,对端老家同样可以借反向隧道进入我内网和作为上网流量出口。
    cctv180
    cctv180
    18h 27m ago
    6
    这样子把数据包分成多个 ip ,银行软件传说会报错。不知道真假
    LightningAlpaca
    LightningAlpaca
    10h 58m ago
    7
    @Frankom #2 应该是你们那出口比较宽松然后高位端口 qos 规则少一些,按理说 hy2 的话 udp 出省更加容易被 q 了
    kkk9
    kkk9
    4h 35m ago
    8
    你这样做基本告别联机游戏了……
    mm2x
    mm2x
    23 mins ago
    9
    呃,为啥不办一条 300M 上行的联通呢?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3023 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 64ms · UTC 11:37 · PVG 19:37 · LAX 03:37 · JFK 06:37
    ♥ Do have faith in what you're doing.