上海 9929 优选低延迟路径: GOST MTCP + ECMP 启动预热

11 天前
 zcp19970603

测试机器环境:利群上海 9929 、xTom 软银 JP 。

0.优选后测试结果截图

RTT 延迟不抽卡,维持稳定不波动不断流。单线程测速能跑起来。

1. 问题背景

部分跨境/跨运营商线路 [本文特指上海 9929 宽带,存在多条 4837 & 9929 混合 ECMP: 据传联通将该业务外包给第三方公司,在后端接入了多条 AS4837 (普通联通骨干网)和 AS9929 (联通精品网)线路] 存在明显的 ECMP ( Equal-Cost Multi-Path ):ICMP ping 稳定,但不同 TCP 连接的 RTT 会落在两个甚至多个明显不同的档位(例如一部分 ~33ms ,一部分 ~51ms )。每次新建 TCP 都可能重新参与 ECMP 哈希,导致普通端口转发下不同业务连接分别落在快路/慢路,延迟随连接波动。

2. 核心思路

在 GOST MTCP 启动阶段选出一条低延迟外层 TCP ,后续所有业务长期复用这一条连接,而不是在运行期间持续探测、清理慢连接。

任意 TCP 客户端 → 前置 GOST :12000 → 单个长期 MTCP session ( 4 MiB Stream / 32 MiB Receive )
  → 启动阶段检测并只保留低延迟外层 TCP → 远端 GOST :11000 → 目标 TCP 服务

GOST MTCP 把多个逻辑 TCP stream 复用在同一条外层 TCP 上,因此 ECMP 抽路的影响从"每个业务连接抽一次"收敛为"MTCP 外层连接建立时抽一次"。

本人曾尝试同时维持多条 MTCP TCP 、定期探测 RTT 、ss -K 踢慢路,但存在两个问题:一是 ss -K 会影响该 session 上承载的所有逻辑 stream ;二是踢掉后重建的连接会重新参与 ECMP ,仍可能抽到慢路,形成"抽路—清理"死循环。最终方案改为:只配置一个 MTCP node ,正常只允许一个 outer TCP ,仅在启动阶段做 ECMP 预热,命中快路后停止干预,运行期间不跑周期检测、不定时 kill 、不主动重建

3. MTCP 缓冲区参数

单 stream 缓冲区过小会限制吞吐,需按 BDP 估算。例如 RTT≈33ms 、目标带宽≈400Mbps 时,BDP ≈ 400Mbps × 0.033s ≈ 1.65MiB ,因此 4 MiB Stream Buffer 较为宽裕:

mux.maxFrameSize: 32768        # 32 KiB
mux.maxReceiveBuffer: 33554432 # 32 MiB
mux.maxStreamBuffer: 4194304   # 4 MiB

4. 远端 GOST 配置

远端只需监听 :11000,实际转发目标由前置 GOST 的 forwarder 指定。

/root/gost/remote.yaml

services:
- name: mtcp-server
  addr: :11000
  handler:
    type: relay
  listener:
    type: mtcp
    metadata:
      mux.version: 2
      mux.keepaliveDisabled: false
      mux.keepaliveInterval: 10s
      mux.keepaliveTimeout: 30s
      mux.maxFrameSize: 32768
      mux.maxReceiveBuffer: 33554432
      mux.maxStreamBuffer: 4194304

5. 前置 GOST 配置

前置监听 :12000,通过 chain-mtcp 走 MTCP dialer 连到远端。

services:
- name: tcp-entry
  addr: :12000
  handler:
    type: tcp
    chain: chain-mtcp
  listener:
    type: tcp
  forwarder:
    nodes:
    - name: target
      addr: 127.0.0.1:2345

chains:
- name: chain-mtcp
  hops:
  - name: remote
    nodes:
    - name: remote-mtcp
      addr: 203.0.113.20:11000
      connector:
        type: relay
      dialer:
        type: mtcp
        metadata:
          mux.version: 2
          mux.keepaliveDisabled: false
          mux.keepaliveInterval: 10s
          mux.keepaliveTimeout: 30s
          mux.maxFrameSize: 32768
          mux.maxReceiveBuffer: 33554432
          mux.maxStreamBuffer: 4194304

最终链路:TCP 客户端 → 前置:12000 → GOST TCP Handler → GOST MTCP Dialer → 203.0.113.20:11000 → 远端 GOST Relay → 127.0.0.1:2345(示例目标地址,可替换为任意内网/本机地址)。本质是 TCP → MTCP 隧道 → TCP

6. 判断 ECMP 快路 / 慢路

ss -tin "dst 203.0.113.20:11000"

重点看 minrtt: 字段而非当前 rtt(当前 RTT 会受排队、突发流量、重传、ACK 延迟等临时因素影响,minrtt 更能反映这条 TCP 最初命中的基础路径)。例如某线路快路 32~34ms 、慢路 50~52ms ,可设 THRESH=40minrtt < THRESH 判为 FAST ,否则判为 SLOW 。

7. 启动预热脚本 mtcp-prewarm.sh

脚本只负责启动阶段选路,逻辑要点:

完整代码(支持多目标、支持自定义触发命令 PREWARM_CMD,含 {DST} {PORT} {TRIGGER} 占位符,各阈值/超时均可用环境变量覆盖):

#!/usr/bin/env bash

# GOST MTCP ECMP 启动预热
#
# 默认用法:
#   ./mtcp-prewarm.sh <目标 IP> <目标端口>
#
# 多目标:
#   ./mtcp-prewarm.sh <IP1> <PORT1> <IP2> <PORT2> ...
#
# 为不同目标指定不同的本地触发入口:
#   ./mtcp-prewarm.sh \
#     203.0.113.20:11000@127.0.0.1:12000 \
#     198.51.100.20:11000@127.0.0.1:13000
#
# 默认触发入口:
#   PREWARM_ADDR=127.0.0.1:12000
#
# 自定义触发命令:
#   PREWARM_CMD='your command' ./mtcp-prewarm.sh ...
#
# PREWARM_CMD 可使用占位符:
#   {DST}      当前目标地址
#   {PORT}     当前目标端口
#   {TRIGGER}  当前本地触发入口
#
# 设计目标:
#   只在启动/维护阶段运行。
#   严格单连接模式:目标地址同时出现超过 1 条 ESTAB TCP 时立即报错退出,
#   不自动清理任何连接,避免把异常运行态误判为预热成功。
#   如果唯一 MTCP 外层 TCP 的 minrtt >= THRESH ,则断开并主动触发重建。
#   连续 STABLE_REQUIRED 次确认唯一连接低于阈值后退出,不再碰现有连接。

set -uo pipefail

THRESH="${THRESH:-40}"
MAX_ROUNDS="${MAX_ROUNDS:-30}"
SETTLE="${SETTLE:-2}"
EMPTY_WAIT="${EMPTY_WAIT:-1}"
STABLE_REQUIRED="${STABLE_REQUIRED:-2}"
PREWARM_ADDR="${PREWARM_ADDR:-127.0.0.1:12000}"
PREWARM_HOLD="${PREWARM_HOLD:-0.3}"
TRIGGER_TIMEOUT="${TRIGGER_TIMEOUT:-3}"
KILL_WAIT="${KILL_WAIT:-2}"
PREWARM_CMD="${PREWARM_CMD:-}"

ts() {
    date '+%F %T'
}

log() {
    echo "[$(ts)] $*"
}

usage() {
    cat <<'USAGE'
用法:
  ./mtcp-prewarm.sh <目标 IP> <目标端口>
  ./mtcp-prewarm.sh <IP1> <PORT1> <IP2> <PORT2> ...
  ./mtcp-prewarm.sh <目标 IP:端口 @触发 IP:端口> [...]

示例:
  ./mtcp-prewarm.sh 203.0.113.20 11000

  ./mtcp-prewarm.sh \
    203.0.113.20 11000 \
    198.51.100.20 11000

  ./mtcp-prewarm.sh \
    203.0.113.20:11000@127.0.0.1:12000 \
    198.51.100.20:11000@127.0.0.1:13000

可配置环境变量:
  THRESH=40
  MAX_ROUNDS=30
  SETTLE=2
  EMPTY_WAIT=1
  STABLE_REQUIRED=2
  PREWARM_ADDR=127.0.0.1:12000
  PREWARM_HOLD=0.3
  TRIGGER_TIMEOUT=3
  KILL_WAIT=2
  PREWARM_CMD='自定义触发命令'

PREWARM_CMD 占位符:
  {DST} {PORT} {TRIGGER}
USAGE
}

is_fast() {
    awk -v r="$1" -v t="$THRESH" 'BEGIN { exit !(r < t) }'
}

split_trigger() {
    local trigger="$1"
    TRIGGER_HOST="${trigger%:*}"
    TRIGGER_PORT="${trigger##*:}"

    if [[ -z "$TRIGGER_HOST" || -z "$TRIGGER_PORT" || "$TRIGGER_HOST" == "$TRIGGER_PORT" ]]; then
        return 1
    fi

    case "$TRIGGER_PORT" in
        ''|*[!0-9]*) return 1 ;;
    esac

    return 0
}

trigger_reconnect() {
    local dst="$1"
    local port="$2"
    local trigger="$3"
    local cmd=""

    log "${dst}:${port} trigger=${trigger}"

    if [[ -n "$PREWARM_CMD" ]]; then
        cmd="${PREWARM_CMD//\{DST\}/$dst}"
        cmd="${cmd//\{PORT\}/$port}"
        cmd="${cmd//\{TRIGGER\}/$trigger}"
        timeout "$TRIGGER_TIMEOUT" bash -lc "$cmd" >/dev/null 2>&1 || true
        return
    fi

    if ! split_trigger "$trigger"; then
        log "${dst}:${port} 无效触发入口: ${trigger}"
        return
    fi

    timeout "$TRIGGER_TIMEOUT" bash -c \
        "exec 3<>/dev/tcp/${TRIGGER_HOST}/${TRIGGER_PORT}; sleep ${PREWARM_HOLD}" \
        >/dev/null 2>&1 || true
}

count_established() {
    local dst="$1"
    local port="$2"

    ss -ntH "dst ${dst}:${port}" 2>/dev/null |
        awk '$1 == "ESTAB" { n++ } END { print n + 0 }'
}

show_established() {
    local dst="$1"
    local port="$2"

    ss -ntpH "dst ${dst}:${port}" 2>/dev/null |
    awk '$1 == "ESTAB" {
        printf("  local=%s peer=%s", $4, $5)
        for (i=6; i<=NF; i++) printf(" %s", $i)
        printf("\n")
    }'
}

get_flows() {
    local dst="$1"
    local port="$2"
    local lport=""
    local line=""
    local local_ep=""

    ss -tinH "dst ${dst}:${port}" 2>/dev/null |
    while IFS= read -r line; do
        if [[ "$line" == ESTAB* ]]; then
            local_ep=$(awk '{print $4}' <<<"$line")
            lport="${local_ep##*:}"
            continue
        fi

        if [[ -n "$lport" && "$line" =~ minrtt:([0-9.]+) ]]; then
            echo "${lport} ${BASH_REMATCH[1]}"
            lport=""
        fi
    done
}

kill_flow() {
    local dst="$1"
    local port="$2"
    local lport="$3"
    local minrtt="$4"

    log "${dst}:${port} KILL sport=${lport} minrtt=${minrtt}ms"
    ss -K "dst ${dst}:${port} sport = :${lport}" >/dev/null 2>&1 || true
}

prewarm_one() {
    local dst="$1"
    local port="$2"
    local trigger="$3"
    local stable=0
    local round total
    local flow lport minrtt
    local lock lockfd
    local socket_count kill_deadline

    case "$port" in
        ''|*[!0-9]*)
            log "错误: ${dst}:${port} 端口必须是数字"
            return 2
            ;;
    esac

    lock="/tmp/mtcp-prewarm-${dst//[^a-zA-Z0-9]/_}-${port}.lock"

    exec {lockfd}>"$lock"

    if ! flock -n "$lockfd"; then
        log "${dst}:${port} 已有预热任务运行,跳过"
        exec {lockfd}>&-
        return 0
    fi

    log "============================================================"
    log "MTCP ECMP prewarm start"
    log "target=${dst}:${port}"
    log "trigger=${trigger}"
    log "fast threshold=<${THRESH}ms"
    log "max rounds=${MAX_ROUNDS}"
    log "============================================================"

    for ((round=1; round<=MAX_ROUNDS; round++)); do

        socket_count="$(count_established "$dst" "$port")"

        if (( socket_count > 1 )); then
            log "============================================================"
            log "${dst}:${port} PREWARM ERROR"
            log "${dst}:${port} expected exactly 1 MTCP outer TCP, found ${socket_count}"
            log "${dst}:${port} multiple MTCP sessions detected"
            log "${dst}:${port} restart the corresponding GOST service"
            log "${dst}:${port} current established sockets:"

            show_established "$dst" "$port" |
            while IFS= read -r line; do
                log "$line"
            done

            log "============================================================"

            exec {lockfd}>&-
            return 3
        fi

        if (( socket_count == 0 )); then
            stable=0

            log "${dst}:${port} round=${round} no MTCP established flow"

            trigger_reconnect "$dst" "$port" "$trigger"

            sleep "$EMPTY_WAIT"
            continue
        fi

        mapfile -t flows < <(get_flows "$dst" "$port")

        total=${#flows[@]}

        if (( total == 0 )); then
            stable=0

            log "${dst}:${port} round=${round} one ESTAB flow exists but minrtt is not ready"

            sleep "$EMPTY_WAIT"
            continue
        fi

        if (( total > 1 )); then
            log "============================================================"
            log "${dst}:${port} PREWARM ERROR"
            log "${dst}:${port} inconsistent ss result"
            log "${dst}:${port} socket_count=${socket_count}, parsed_flows=${total}"
            log "${dst}:${port} no connection was modified"
            log "============================================================"

            exec {lockfd}>&-
            return 4
        fi

        flow="${flows[0]}"
        lport="${flow%% *}"
        minrtt="${flow##* }"

        log "---------------- ${dst}:${port} round ${round} ----------------"

        if is_fast "$minrtt"; then

            log "${dst}:${port} FAST sport=${lport} minrtt=${minrtt}ms"
            log "${dst}:${port} flows=1 fast=1 slow=0"

            ((stable++))

            log "${dst}:${port} single flow FAST, stable=${stable}/${STABLE_REQUIRED}"

            if (( stable >= STABLE_REQUIRED )); then

                socket_count="$(count_established "$dst" "$port")"

                if (( socket_count != 1 )); then
                    log "============================================================"
                    log "${dst}:${port} PREWARM ERROR"
                    log "${dst}:${port} final verification expected 1 MTCP outer TCP, found ${socket_count}"

                    if (( socket_count > 1 )); then
                        log "${dst}:${port} restart the corresponding GOST service"

                        show_established "$dst" "$port" |
                        while IFS= read -r line; do
                            log "$line"
                        done
                    fi

                    log "============================================================"

                    exec {lockfd}>&-
                    return 3
                fi

                log "${dst}:${port} PREWARM SUCCESS"
                log "${dst}:${port} verified single MTCP outer TCP with minrtt < ${THRESH}ms"

                exec {lockfd}>&-
                return 0
            fi

            sleep "$SETTLE"
            continue
        fi

        stable=0

        log "${dst}:${port} SLOW sport=${lport} minrtt=${minrtt}ms"
        log "${dst}:${port} flows=1 fast=0 slow=1"

        socket_count="$(count_established "$dst" "$port")"

        if (( socket_count != 1 )); then
            log "============================================================"
            log "${dst}:${port} PREWARM ERROR"
            log "${dst}:${port} flow count changed before kill"
            log "${dst}:${port} expected 1, found ${socket_count}"
            log "${dst}:${port} no connection was modified"

            if (( socket_count > 1 )); then
                log "${dst}:${port} restart the corresponding GOST service"

                show_established "$dst" "$port" |
                while IFS= read -r line; do
                    log "$line"
                done
            fi

            log "============================================================"

            exec {lockfd}>&-
            return 3
        fi

        kill_flow "$dst" "$port" "$lport" "$minrtt"

        kill_deadline=$((SECONDS + KILL_WAIT))

        while (( SECONDS < kill_deadline )); do

            socket_count="$(count_established "$dst" "$port")"

            if (( socket_count == 0 )); then
                break
            fi

            sleep 0.1
        done

        socket_count="$(count_established "$dst" "$port")"

        if (( socket_count > 1 )); then
            log "============================================================"
            log "${dst}:${port} PREWARM ERROR"
            log "${dst}:${port} multiple sessions appeared after kill: ${socket_count}"
            log "${dst}:${port} restart the corresponding GOST service"

            show_established "$dst" "$port" |
            while IFS= read -r line; do
                log "$line"
            done

            log "============================================================"

            exec {lockfd}>&-
            return 3
        fi

        if (( socket_count == 1 )); then
            log "============================================================"
            log "${dst}:${port} PREWARM ERROR"
            log "${dst}:${port} killed flow did not disappear within ${KILL_WAIT}s"
            log "${dst}:${port} no reconnect was triggered"
            log "${dst}:${port} check/restart the corresponding GOST service"

            show_established "$dst" "$port" |
            while IFS= read -r line; do
                log "$line"
            done

            log "============================================================"

            exec {lockfd}>&-
            return 5
        fi

        trigger_reconnect "$dst" "$port" "$trigger"

        log "${dst}:${port} waiting ${SETTLE}s for GOST reconnect..."

        sleep "$SETTLE"
    done

    log "============================================================"
    log "${dst}:${port} PREWARM TIMEOUT"

    socket_count="$(count_established "$dst" "$port")"

    log "${dst}:${port} established=${socket_count}"

    if (( socket_count > 1 )); then
        log "${dst}:${port} multiple MTCP sessions detected"
        log "${dst}:${port} restart the corresponding GOST service"

        show_established "$dst" "$port" |
        while IFS= read -r line; do
            log "$line"
        done
    fi

    mapfile -t flows < <(get_flows "$dst" "$port")

    for flow in "${flows[@]}"; do
        log "${dst}:${port} sport=${flow%% *} minrtt=${flow##* }ms"
    done

    log "============================================================"

    exec {lockfd}>&-
    return 1
}

declare -a TARGETS=()

if (( $# == 0 )); then
    usage
    exit 2
fi

if [[ "$1" == *"@"* ]]; then

    for spec in "$@"; do

        if [[ "$spec" != *"@"* ]]; then
            echo "错误: 混合参数格式不受支持"
            usage
            exit 2
        fi

        target="${spec%%@*}"
        trigger="${spec#*@}"

        dst="${target%:*}"
        port="${target##*:}"

        TARGETS+=("${dst}|${port}|${trigger}")
    done

else

    if (( $# % 2 != 0 )); then
        echo "错误: IP/端口参数必须成对出现"
        usage
        exit 2
    fi

    while (( $# > 0 )); do
        TARGETS+=("$1|$2|${PREWARM_ADDR}")
        shift 2
    done
fi

failed=0

for item in "${TARGETS[@]}"; do

    IFS='|' read -r dst port trigger <<<"$item"

    if ! prewarm_one "$dst" "$port" "$trigger"; then
        failed=1
    fi
done

if (( failed != 0 )); then
    log "one or more targets failed"
    exit 1
fi

log "all targets PREWARM SUCCESS"

exit 0

保存后校验语法:

chmod +x /root/mtcp-prewarm.sh
bash -n /root/mtcp-prewarm.sh

8. 使用方法

单目标手动执行:

THRESH=40 \
PREWARM_ADDR=127.0.0.1:12000 \
/root/mtcp-prewarm.sh 203.0.113.20 11000

若首次抽到慢路,脚本会 SLOW → KILL → 等旧连接消失 → 重新触发 直到命中快路并连续确认两次,输出 PREWARM SUCCESS

多目标一次执行:

./mtcp-prewarm.sh \
  203.0.113.20 11000 \
  198.51.100.20 11000

不同目标使用不同本地触发入口:

./mtcp-prewarm.sh \
  203.0.113.20:11000@127.0.0.1:12000 \
  198.51.100.20:11000@127.0.0.1:13000

若普通 TCP connect 无法触发实际业务链,可用 PREWARM_CMD 自定义触发命令:

PREWARM_CMD="timeout 1 bash -c 'exec 3<>/dev/tcp/127.0.0.1/12000; sleep 0.3'" \
./mtcp-prewarm.sh 203.0.113.20 11000

不同线路 RTT 档位不同时,建议用独立 systemd service 分别设置各自的 THRESH(例如线路 A 快路 33ms/慢路 51ms 用 THRESH=40,线路 B 快路 46ms/慢路 60ms 用 THRESH=52)。

9. systemd 集成

长期运行建议用 systemd 管理 GOST:开机启动、异常退出自动拉起、日志统一记录,并在每次启动后自动执行一次 ECMP 预热(ExecStartPost)。

前置 GOST (主线路):

cat >/etc/systemd/system/gost-mtcp-main.service <<'EOF'
[Unit]
Description=GOST MTCP Main
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/root/gost

ExecStart=/root/gost/gost -D -C /root/gost/cn.yaml

Environment="PREWARM_ADDR=127.0.0.1:12000"
Environment="THRESH=40"

ExecStartPost=/bin/bash -lc '/root/mtcp-prewarm.sh 203.0.113.20 11000 || true'

Restart=on-failure
RestartSec=2
TimeoutStartSec=120

KillSignal=SIGTERM

StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

启用与查看:

systemctl daemon-reload
systemctl enable --now gost-mtcp-main
systemctl status gost-mtcp-main --no-pager
journalctl -u gost-mtcp-main -n 100 -l --no-pager

ExecStartPost 末尾的 || true 是为了防止预热失败被 systemd 判定为启动失败,进而触发 Restart=on-failure 形成"启动→预热失败→service failed→重启→再次预热失败"的循环;加上 || true 后预热失败只写入 journal ,GOST 主进程照常运行,留给人工检查。

10. 验证与常见问题

验证只有一个 MTCP 且命中快路:

ss -ntp "dst 203.0.113.20:11000"   # ESTAB 数量应为 1
ss -tin "dst 203.0.113.20:11000"   # minrtt < THRESH

为什么 flows > 1 不自动处理? 严格模式下同一目标出现 ≥2 条 outer TCP 属于异常运行态(而非单纯"抽到慢路"),脚本报 PREWARM ERROR 并停止,不猜测删哪条;更安全的处理是 systemctl restart 对应服务,让 ExecStartPost 重新走一次干净预热。

为什么不再用 cron 周期性踢慢路? 一条 MTCP TCP 上可能承载多个业务 stream ,运行期间 ss -K 相当于主动重置整个 session 。原则改为:启动阶段允许检测/淘汰/重抽,正常运行阶段不主动干预;确需重建时用 systemctl restart 触发完整的启动预热流程。

运行一段时间后 RTT 变高怎么办? 需区分两种情况:若还是原来那条 MTCP TCP (本地端口不变)且 minrtt 仍处于原来的低延迟档,只是当前 rtt 因拥塞/重传等临时抖动升高,无需处理;若本地端口已变化,说明 MTCP 外层 TCP 已重新建立并可能重新抽到慢路,此时也不应重新引入周期性 FastPath ,而是通过 systemctl restart 重新走一次启动预热。

为什么 mtr -T 仍可能看到多条路径? mtr -T 每次探测都是新建 TCP 五元组,会重新参与 ECMP ,不会复用已建立的 GOST MTCP 连接,因此不能用它判断 MTCP 实际路径,应以 ss -tinminrtt 为准。

文中公网 IP 、端口均为示例,实际使用请按自己线路的 RTT 分布调整。

3161 次点击
所在节点    宽带症候群
17 条回复
kenX
11 天前
看起来不错,先赞后看。
shunia
11 天前
古法手搓的脚本,牛逼
Umbray
11 天前
思路可以,优化网络还要这么搞,联通实在一言难尽
yeh
11 天前
延时可以

就是这速度,还不如 非 9929 连 东京 aws……
rulagiti
11 天前
搞这么复杂效率也不高,可以魔改下 gost 或用 golang 重写个
dizhang
10 天前
9929 最近去甲骨文日本或者新加坡延迟很恐怖
baraja
10 天前
好像家宽 9929 到 sb 也这样,时而 30 时而 50 多。我还以为 50 多的是绕道北京了……
sharo580
10 天前
@baraja 我测试了,日本 sb 目测也不会炸,感觉像专用来和 9929 负载均衡的,正常炸的时候,9929 体系也能保证 50 多
Cert
10 天前
思路挺好的,为你点赞。
另外,北京联通家庭固定宽带有每个月 50 块钱的 AS9929 叠加包,你可以联系一下 V2EX 站里面的北京朋友,做个 AB Test ,这样有一个参照。
baraja
9 天前
@sharo580 9929 和 sb 还不错,但 50 多那个终归有点不好看,用 dmit tyo t1 能稳定在 30 几,也不用像楼主这么折腾,虽然探索精神值得点赞
Umbray
9 天前
4837 走 v6 到 sb 一样恐怖
sharo580
9 天前
@baraja 你是说的 ping 还是 tcping ,理论上应该都会分流把
zcp19970603
9 天前
@baraja dmit tyo t1 目前测下来 mtr -T 结果是稳定的,不需要像我这么折腾。但不好说以后会不会改路由
baraja
9 天前
@sharo580 前几个月,9929 改了路由,连亚太都走境外 ix ,附送 10099 。这次改动之后,sb akari 等从稳定 40 到 ecmp ;甲骨文东京从 40 到彻底废了,甲骨文韩国从垃圾变成香饽饽,32 和 46 ecmp 。dmit tyo ti 回程不走 ix+10099 ,走 bbtec 回 9929 ,似乎就保留了 sb 的优良传统
baraja
9 天前
@zcp19970603 dmit ti 确实有可能会改路由。hkg t1 现在稳定在 40 好几个月了(也是托上文所说的 9929 连 10099+ix 的福),之前 60 多(绕日本)还抖动。tyo t1 上个月放货买了台,绕新加坡去了,立马退货。不过现在看 lg 路由优化好了,估计能长期稳定在 40 以内
baraja
9 天前
@sharo580 我让 AI 写了个脚本,测 vps 到 ipv4.sha-9929.endpoint.nxtrace.org 的回程,
SB 快路径 (<45ms): 495 慢路径 (45-65ms): 497 其他: 8
akari 快路径 (<45ms): 502 慢路径 (45-65ms): 497 其他: 1
xtom_gen2 快路径 (<45ms): 503 慢路径 (45-65ms): 497 其他: 0
dmit_t1 快路径 (<45ms): 1000 慢路径 (45-65ms): 0 其他: 0
甲骨文春川 快路径 (<45ms): 678 慢路径 (45-65ms): 322 其他: 0

前三者回程路由都是 jpnap-10099-9929
dmit t1 回程不经过 10099 (去程经过),走 bbix-bbtec-9929
Rorysky
8 天前
太深奥了 学习

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

https://v2ex.ih06.com/t/1233477

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

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

© 2021 V2EX