帮你快速理解、总结文档立即下载

FAQ

最近更新时间:2026-09-07 14:32:30
我的收藏
本文档用于客户在使用云聚通产品时指导定位和排查问题。

1. 业务性能问题常见原因及排障方法

本节主要介绍用户在使用聚合、实时加速时,业务效果未达到预期时的常见原因和排障方法。
业务效果未达预期的现象。例如:推流/拉流视频卡顿或花屏或丢帧。

1.1 常见原因

1.1.1 加速模式选择不合适

加速模式配置不合适,例如应使用实时模式,配置了聚合模式。需根据业务类型及性能需求选择合适的加速模式,具体配置建议咨询腾讯运维人员。
加速模式查询方法请参见 1.2.1 加速模式及接入网关 IP 查询

1.1.2 业务参数设置不合适

业务相关参数:业务相关设置不合适,常见的有:
MSS 过大导致 UDP 分包传输降低性能。
直播推流容忍时延设置低于链路工作 RTT 导致链路不参与聚合或丢包。
云聚通算法相关参数,默认配置参数一般可满足需求,有特殊需求咨询腾讯运维人员。

1.1.3 网络环境差(弱网)

业务在大部分场景及大部分时间都正常,仅在某些物理位置或某些高峰时段的业务效果不达预期,可能是当前网络环境差不足以满足业务需求。
在部分链路或者全部链路的网络质量差的情况下(例如时延过高,时延抖动大,丢包率高),可能出现如下问题:
聚合模式
各链路的聚合带宽,低于业务带宽需求,则当前网络环境不满足业务需求,需更换物理链路或增加物理链路。
部分链路被禁用,剩余链路的聚合带宽低于业务带宽需求,则当前网络环境不满足业务需求,需要更换链路或增加物理链路。
聚合链路带宽满足业务带宽需求,但偶尔会出现卡顿、丢包、乱序,则可能是当前网络质量突然变差导致(抖动、丢包、时延)。
实时模式
被选择的发包链路带宽仍低于业务需求,则当前网络环境不满足业务需求,需更换终端位置或更换物理链路。
被选择的发包链路时延过大,或者抖动大,不满足业务需求,则当前网络环境不满足业务需求,需更换终端位置或更换物理链路。
链路切换频繁,时延抖动不满足业务需求,则当前网络环境不满足业务需求,需更换终端位置或更换物理链路。
说明:
为排查和确认当前网络环境是否存在网络环境差的问题,可通过以下其中一个或多个方式进行排查和确认。

1.2 排障方法

1.2.1 加速模式及接入网关 IP 查询

curl -s -X 'GET' 'http://127.0.0.1:9801/api/v2/client/mp-speeder' -H 'accept: */*' -H 'Content-Type: application/json'
scheduleMode(加速模式)
bonding:聚合
fastSwitching:实时
redundant:双发
accGateway(接入网关 IP)

1.2.2 流量监控

登录 腾讯云控制台,可查看选定设备的实时网络状态。包括上行流量、下行流量、上行速率、下行速率、丢包、时延。
检查各链路的速率,是否出现速率下降严重或掉 0 等异常现象。
检查各链路的时延、丢包率,是否出现时延激增或抖动大(例如:时延从 80ms 增加到 300ms)、丢包率激增(例如:从几乎不丢包到丢包率 10%以上 )。
说明:
可通过 1.2.3 SDK 日志分析 进一步印证。

1.2.3 SDK 日志分析

SDK 日志本地文件存储路径:/var/log/mp-sdk.log 以及 /var/log/mp-speeder.log
日志常用分析指标及故障判断方法如下:
注册失败,搜索关键字:"sdk register failed",下述为 datakey 失效导致的注册失败问题。
触发链路禁用,搜索关键字:"potentiallyFailed"。
链路禁用后恢复,搜索关键字:"potentiallyOK"。
datakey 在不同设备复用导致加速连接中断,搜索关键字:"close session by controller"。
激活 path,搜索关键字:"Enable PathID"。
关闭 path,搜索关键字:"Close PathID"。

1.2.4 udpping 测速

udpping 工具是加速网关服务,该工具原理是通过指定的网口按指定频率发送探测包到指定探测点,收集链路时延变化情况。可用于对比物理链路和加速链路的时延。
/usr/local/bin/mp-speeder/udping -h
Usage of /usr/local/bin/mp-speeder/udping:
-C int
ping count
-I string
bind interface name
-c string
probe address, IP:PORT
-i duration
ping interval (default 1s)
-l int
payload length
-logLevel string
log level, default info
-o output to shell
-v show version
-w duration
ping timeout (default 1s)
具体参数配置建议:
-c string
probe address, IP:PORT
说明:
其中,IP 可以通过“加速模式及接入网关 IP 查询”获取探测网关的 IP,PORT 使用8888。
udpping 工具使用举例:
评估指定网卡(例如 eth0)到指定探测点(例如:接入网关 IP 49.7.248.202)的 RTT 时延。下述命令含义:指定采集 eth0 网卡访问49.7.248.202网关的时延,探测报文长度200字节,每0.1s 一个探测,总计探测100次。
参考命令:/usr/local/bin/mp-speeder/udping -C 100 -I eth0 -c 49.7.248.202:8888 -i 0.1s -l 200
评估加速链路的 RTT 时延。下述命令含义:采集 SDK 访问49.7.248.202网关的加速链路时延,探测报文长度200字节,每0.1s 一个探测,总计探测100次。
参考命令:/usr/local/bin/mp-speeder/udping -C 100 -I mp_tun0 -c 49.7.248.202:8888 -i 0.1s -l 200

1.2.5 UDP 打流

UDP 打流使用 iperf3 服务,为常用的网络测速服务。UDP 打流可作为辅助工具观察链路带宽、丢包率变化情况。需自行部署 iperf3客户端和服务。
UDP 打流使用举例:
评估指定网卡(eth0)到 IP(x.x.x.x)的 UDP 传输带宽。其中 x.x.x.x 是提供 Iperf3 服务的 IP,服务端口是 5201。
参考命令:iperf3 -c x.x.x.x -p 5201 -u -b 100M -B eth0
评估加速链路的 UDP 带宽。其中 x.x.x.x 是提供 Iperf3 服务的 IP,服务端口是 5201。
参考命令:iperf3 -c x.x.x.x -p 5201 -u -b 100M -B 192.18.0.1

1.2.6 网络测量回调监听 API

网络测量回调监听 API 可获得带内各链路的 RTT、速率、丢包率指标,测量结果与业务同步,需用户自行保存 API 回调结果。
查询流量统计接口。
curl -X 'GET' 'http://127.0.0.1:9801/api/v2/client/flowStatistics' -H 'accept: application/json' -H 'all: true'

2. Linux SDK 常见问题排障方法

2.1 无法启动加速或加速后流量不通

2.1.1 执行一键检测脚本

当遇到无法启动加速或加速后流量不通时,运行一键检测脚本,并根据检测结果进行修正。直到所有检查结果正常。
Linux 一键检测脚本支持如下检测能力:
检查本地时间
检查本地证书
检查加速配置是否存在
检测加速状态(关键进程、策略路由、引流规则)。
检查业务连通性
检测 rp_filter 配置。
检测 L3 功能配置。
v0.16.1 及以后版本的检测脚本已默认放置在这个目录:/usr/local/bin/mp-speeder/mp_check.sh,如安装时有指定目录,则 mp_check.sh 应在指定的 BIN 目录下。(如果该目录下无 mp_check.sh,可将以下文件拷入该目录执行)。
#!/bin/bash

# 设置颜色输出
YELLOW='\\033[0;33m'
GREEN='\\033[0;32m'
RED='\\033[0;31m'
BLUE='\\033[0;34m'
NC='\\033[0m' # No Color

# 全局变量
interfaces=""
l3_check=false
link_only=false
udp_target=""

# 存储检查结果
check_results=()
warning_results=()
error_results=()

# 函数:检查进程是否运行
check_process() {
local process_name=$1
if pgrep -f "$process_name" > /dev/null; then
echo -e "${GREEN} ├─ [OK] 进程 $process_name 正在运行${NC}"
check_results+=("[4] $process_name 进程检查 PASS")
else
echo -e "${RED} ├─ [FAIL] 进程 $process_name 未运行${NC}"
error_results+=("[4] $process_name 进程检查 FAIL")
fi
}

# 函数:检查网卡是否存在并启动
check_interface() {
local interface=$1
if ip link show "$interface" &> /dev/null; then
if ip link show "$interface" | grep -q "UP"; then
echo -e "${GREEN} └─ [OK] 网卡 $interface 已启动且状态正常${NC}"
check_results+=("[5] 网卡检查 PASS")
else
echo -e "${RED} └─ [FAIL] 网卡 $interface 存在但未启动${NC}"
error_results+=("[5] 网卡检查 FAIL")
fi
else
echo -e "${RED} └─ [FAIL] 网卡 $interface 不存在${NC}"
error_results+=("[5] 网卡检查 FAIL")
fi
}

# 函数:检查 rp_filter
check_rp_filter() {
if sysctl net.ipv4.conf.mp_tun0.rp_filter | grep -q "net.ipv4.conf.mp_tun0.rp_filter = 1"; then
echo -e "${RED} └─ [FAIL] rp_filter 未关闭${NC}"
error_results+=("[7] rp_filter 检查 FAIL")
else
echo -e "${GREEN} └─ [OK] rp_filter 已关闭${NC}"
check_results+=("[7] rp_filter 检查 PASS")
fi
}

# 函数:检查策略路由
check_policy_routing() {
local has_error=false
# 检查策略规则是否存在
if ip rule | grep -q "from 198.18.0.1 lookup"; then
local table_num=$(ip rule | grep "from 198.18.0.1 lookup " | awk '{print $NF}')
echo -e "${GREEN} ├─ [OK] 找到策略规则: from 198.18.0.1 lookup $table_num${NC}"
# 检查路由表中的默认路由
if ip route show table "$table_num" | grep -q "default dev mp_tun0"; then
echo -e "${GREEN} ├─ [OK] 路由表 $table_num 中存在正确的默认路由${NC}"
else
echo -e "${RED} ├─ [FAIL] 路由表 $table_num 中未找到正确的默认路由${NC}"
has_error=true
fi
else
echo -e "${RED} ├─ [FAIL] 未找到策略规则: from 198.18.0.1${NC}"
has_error=true
fi

for iface in $interfaces; do
# 获取网卡IP地址
local ip_addr=$(ip addr show $iface | awk '/inet / {print $2}' | cut -d/ -f1|head -n 1)
if [ -z "$ip_addr" ]; then
echo -e "${YELLOW} ├─ [WARN] 网卡 $iface 未配置IP地址,无法通过此网卡加速,建议检查${NC}"
continue
fi
# 检查策略规则是否存在
if ip rule | grep -q "from $ip_addr lookup"; then
local table_num=$(ip rule | grep "from $ip_addr lookup" | awk '{print $NF}')
echo -e "${GREEN} ├─ [OK] 找到网卡 $iface ($ip_addr) 的策略规则: lookup $table_num${NC}"
# 检查路由表中是否有路由
if ip route show table "$table_num" | grep -q "dev $iface"; then
echo -e "${GREEN} ├─ [OK] 路由表 $table_num 配置正确${NC}"
else
echo -e "${RED} ├─ [FAIL] 路由表 $table_num 中未找到路由${NC}"
has_error=true
fi
else
echo -e "${YELLOW} ├─ [WARN] 未找到网卡 $iface ($ip_addr) 的策略规则,可能影响加速效果,建议开启SDK策略路由管理${NC}"
fi
done
if [ "$has_error" = true ]; then
error_results+=("[8] 策略路由检查 FAIL")
else
check_results+=("[8] 策略路由检查 PASS")
fi
}

# 函数:检查 speeder 状态
check_speeder_status() {
local response
response=$(curl -s -X 'GET' 'http://127.0.0.1:9801/api/v2/client/mp-speeder' -H 'accept: */*' -H 'Content-Type: application/json')
if echo "$response" | grep -q '"ready":true'; then
echo -e "${GREEN} ├─ [OK] speeder 正在运行且加速状态正常${NC}"
# 提取加速网卡列表
interfaces=$(echo "$response" | sed -n 's/.*"interfaces":\\[\\([^]]*\\)\\].*/\\1/p' | sed 's/"//g' | sed 's/:[0-9]*//g' | tr ',' ' ')
echo -e "${GREEN} └─ [OK] 加速网卡列表: $interfaces${NC}"
check_results+=("[6] 加速状态检查 PASS")
else
echo -e "${RED} └─ [FAIL] speeder 未运行或加速状态异常${NC}"
error_results+=("[6] 加速状态检查 FAIL")
fi
}

# 函数:iptables 检查(引流规则 + 功能验证 + NAT MARK 冲突扫描)
check_iptables_rules() {
# -------- 子项 1:mp_route_mark 引流规则检查 --------
if iptables -L mp_route_mark -nv -t mangle 2>/dev/null | grep -q "0x1/0xf"; then
echo -e "${GREEN} ├─ [OK] 引流规则 mp_route_mark 检查通过${NC}"
check_results+=("[9] iptables-引流规则 PASS")
else
echo -e "${YELLOW} ├─ [WARN] 未检查到引流规则,请确认是否符合预期${NC}"
warning_results+=("[9] iptables-引流规则 WARN")
fi

# -------- 子项 2:iptables 功能验证(添加+删除测试规则) --------
# 前置:确认 mp_route_mark 链存在,避免在错误的环境上做写入测试
if ! iptables -t mangle -L mp_route_mark -n &>/dev/null; then
echo -e "${YELLOW} ├─ [WARN] mp_route_mark 链不存在,跳过 iptables 功能验证${NC}"
warning_results+=("[9] iptables-功能验证 SKIP")
else
# 测试规则参数(用不易冲突的私网 IP + 高位端口)
# 注意: -t <table> 必须紧跟 iptables 命令,位于 -A/-D 之前,才是规范写法
local test_table="mangle"
local test_args="mp_route_mark -s 192.168.77.11/24 -p tcp --sport 12349 -j MARK --set-mark 0x1/0xf --wait"
local add_err del_err
add_err=$(iptables -t $test_table -A $test_args 2>&1)
if [ $? -ne 0 ]; then
echo -e "${RED} ├─ [FAIL] iptables 添加测试规则失败: ${add_err}${NC}"
error_results+=("[9] iptables-功能验证 FAIL")
else
del_err=$(iptables -t $test_table -D $test_args 2>&1)
if [ $? -ne 0 ]; then
echo -e "${RED} ├─ [FAIL] iptables 删除测试规则失败: ${del_err}${NC}"
echo -e "${RED} │ 请手工清理残留: iptables -t ${test_table} -D ${test_args}${NC}"
error_results+=("[9] iptables-功能验证 FAIL")
else
echo -e "${GREEN} ├─ [OK] iptables 功能验证通过(测试规则添加/删除均成功)${NC}"
check_results+=("[9] iptables-功能验证 PASS")
fi
fi
fi

# -------- 子项 3:nat 表 MARK 冲突扫描 --------
# 扫描 iptables -t nat -nvL 中 target 列为 MARK 的规则,如果存在则提示用户排查
local nat_output nat_mark_lines
nat_output=$(iptables -t nat -nvL 2>/dev/null)
# awk 匹配 target 列(第3列)为 MARK 的行,最多输出 5 行防刷屏
nat_mark_lines=$(echo "$nat_output" | awk '$3 == "MARK"' | head -5)
if [ -n "$nat_mark_lines" ]; then
echo -e "${YELLOW} └─ [WARN] 检测到 nat 表中存在 MARK 规则,请排查是否会影响 SDK 的 mangle 表 0x1/0xf mark:${NC}"
echo "$nat_mark_lines" | sed 's/^/ /'
warning_results+=("[9] iptables-NAT MARK冲突 WARN")
else
echo -e "${GREEN} └─ [OK] nat 表中未检测到 MARK 规则${NC}"
check_results+=("[9] iptables-NAT MARK冲突 PASS")
fi
}

# 函数:检查 L3 功能
check_l3_functionality() {
# 检查wireguard虚拟口状态
# /usr/local/bin/mp-speeder/wg show
# interface: 09yg7kk9di
# public key: ISh0Y01aQ3dig5gyuivFnQe8lxi8Sdp3epNReVIYVSI=
# private key: (hidden)
# listening port: 55368

# peer: RzZ9m8lgMVeFzILbkfLmlM9I3ZBuGoP4hrfe78Vjzg0=
# endpoint: 198.18.0.5:10001
# allowed ips: 192.168.18.0/28
# latest handshake: 1 minute ago
# transfer: 3.66 MiB received, 17.26 MiB sent
# persistent keepalive: every 15 seconds
local response
response=$(@BIN_DIR@/wg show)
if echo "$response" | grep -q "latest handshake"; then
echo -e "${GREEN} ├─ [OK] wireguard 虚拟口状态正常${NC}"
else
echo -e "${RED} ├─ [FAIL] wireguard 虚拟口状态异常${NC}"
return 1
fi

# 检查路由表
local interface_name=$(echo "$response" | grep "interface:" | awk '{print $2}')
local allowed_ips=$(echo "$response" | grep "allowed ips:" | awk '{print $3}')

if [ -z "$interface_name" ] || [ -z "$allowed_ips" ]; then
echo -e "${RED} ├─ [FAIL] 无法从 wireguard 配置中获取接口名或允许的 IP${NC}"
return 1
fi

# 检查路由表
local routing_tables=$(ip route)
local expected_route="$allowed_ips dev $interface_name scope link"
if echo "$routing_tables" | grep -q "$expected_route"; then
echo -e "${GREEN} ├─ [OK] 路由表中存在正确的路由: $expected_route${NC}"
else
echo -e "${RED} ├─ [FAIL] 路由表中未找到正确的路由: $expected_route${NC}"
return 1
fi

# 检查endpoint是否符合198.18.x.x形式
local endpoint=$(echo "$response" | grep "endpoint:" | awk '{print $2}')
if echo "$endpoint" | grep -q "198.18."; then
echo -e "${GREEN} ├─ [OK] endpoint符合198.18.x.x形式${NC}"
else
echo -e "${RED} ├─ [FAIL] endpoint不符合198.18.x.x形式${NC}"
return 1
fi

# 检查引流规则
# iptables -L -nv -t mangle 的结果中必须存在以下规则
# 1、OUTPUT链中有mp_route_bypass、mp_route_mark、mp_l3_route三个chain,且mp_route_bypass必须在第一个
# 2、mp_route_bypass链中需要有这样一条规则,destination为allowed_ips,target是ACCEPT
# 3、mp_l3_route链中需要有这样一条规则,destination为endpoint,target是MARK
local mangle_rules=$(iptables -L OUTPUT -nv -t mangle)
# 1. 检查 OUTPUT 链中的 chain 顺序
if ! echo "$mangle_rules" | grep -q "mp_route_bypass" || \\
! echo "$mangle_rules" | grep -q "mp_route_mark" || \\
! echo "$mangle_rules" | grep -q "mp_l3_route"; then
echo -e "${RED} ├─ [FAIL] OUTPUT 链中缺少必要的 chain${NC}"
return 1
fi
# 确认 mp_route_bypass 在第一位
if ! iptables -L OUTPUT 1 -nv -t mangle | grep -q "mp_route_bypass"; then
echo -e "${RED} ├─ [FAIL] mp_route_bypass 不在 OUTPUT 链的第一位${NC}"
return 1
fi

# 2. 检查 mp_route_bypass 链中的规则
if ! iptables -L mp_route_bypass -nv -t mangle | grep -q "ACCEPT.*$allowed_ips"; then
echo -e "${RED} ├─ [FAIL] mp_route_bypass 链中缺少目标为 $allowed_ips 的 ACCEPT 规则${NC}"
return 1
fi

# 3. 检查 mp_l3_route 链中的规则
endpoint=$(echo "$endpoint" | awk -F ':' '{print $1}')
if ! iptables -L mp_l3_route -nv -t mangle | grep -q "$endpoint.*MARK.*0x1/0xf"; then
echo -e "${RED} ├─ [FAIL] mp_l3_route 链中缺少目标为 $endpoint 的 MARK 规则${NC}"
return 1
fi

echo -e "${GREEN} └─ [OK] iptables 规则检查通过${NC}"
return 0
}

# 函数:检查本地时间
check_local_time() {
echo -e "${BLUE}[1] 检查本地时间...${NC}"
local remote_time=$(curl -sI https://www.baidu.com | grep -i '^date:' | sed 's/^Date: //' | head -1)
if [ -z "$remote_time" ]; then
echo -e "${YELLOW} └─ [WARN] 无法获取远程时间,跳过时间检查${NC}"
return 0
fi
local remote_ts=$(date -d "$remote_time" +%s 2>/dev/null || echo "")
local local_ts=$(date +%s)
if [ -z "$remote_ts" ] || [ -z "$local_ts" ]; then
echo -e "${YELLOW} └─ [WARN] 时间转换失败,跳过时间检查${NC}"
return 0
fi
local diff=$((local_ts - remote_ts))
local abs_diff=${diff#-} # 取绝对值
if [ $abs_diff -gt 300 ]; then
echo -e "${RED} └─ [FAIL] 时间偏差过大:${diff}秒(建议使用 ntpdate 同步)${NC}"
error_results+=("[1] 时间检查 FAIL")
return 0
elif [ $abs_diff -gt 120 ]; then
echo -e "${YELLOW} └─ [WARN] 时间偏差较大:${diff}秒${NC}"
warning_results+=("[1] 时间检查 WARN")
return 0
else
echo -e "${GREEN} └─ [OK] 时间正常(偏差 ${diff}秒)${NC}"
check_results+=("[1] 时间检查 PASS")
return 0
fi
}

# 函数:检查关键资源文件(警告级别)
check_resource_files() {
echo -e "${BLUE}[3] 检查关键资源文件...${NC}"
local files=(
"@BIN_DIR@/mp-sdk"
"@BIN_DIR@/mp-speeder"
"@CONF_DIR@/data/mp_client.json"
)
local missing_files=()
for file in "${files[@]}"; do
if [ -f "$file" ] && [ -s "$file" ]; then
echo -e "${GREEN} ├─ [OK] $file 存在且非空${NC}"
else
missing_files+=("$file")
echo -e "${YELLOW} ├─ [WARN] $file 缺失或为空${NC}"
fi
done
if [ ${#missing_files[@]} -gt 0 ]; then
echo -e "${YELLOW} └─ [WARN] 发现 ${#missing_files[@]} 个文件问题(警告级别)${NC}"
local missing_list=$(printf '%s, ' "${missing_files[@]}")
missing_list=${missing_list%, } # 去掉末尾逗号
warning_results+=("[3] 资源文件检查 WARN (缺失: ${missing_list})")
else
echo -e "${GREEN} └─ [OK] 所有资源文件正常${NC}"
check_results+=("[3] 资源文件检查 PASS")
fi
return 0
}

# 函数:检查证书是否正常
check_certificate() {
echo -e "${BLUE}[2] 检查证书...${NC}"
# 通过 HTTPS 请求验证系统证书链是否正常
local curl_output
curl_output=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 3 "https://www.baidu.com" 2>&1)
local curl_exit=$?

if [ $curl_exit -eq 0 ] && [ "$curl_output" -ge 200 ] 2>/dev/null && [ "$curl_output" -lt 400 ] 2>/dev/null; then
echo -e "${GREEN} └─ [OK] HTTPS 证书验证正常${NC}"
check_results+=("[2] 证书检查 PASS")
elif [ $curl_exit -eq 60 ] || [ $curl_exit -eq 77 ]; then
# exit 60: SSL certificate problem, exit 77: SSL CA cert issue
echo -e "${RED} └─ [FAIL] 证书验证失败(curl exit code: $curl_exit),请检查系统 CA 证书${NC}"
error_results+=("[2] 证书检查 FAIL")
else
echo -e "${YELLOW} └─ [WARN] HTTPS 请求异常(HTTP $curl_output, exit $curl_exit),可能是网络问题${NC}"
warning_results+=("[2] 证书检查 WARN")
fi
}

# 函数:检查业务链路连通性
check_business_link() {
# 结果计数器
# link_fail_count: 加速测试失败次数(严重,代表 SDK 加速链路不通)
# link_direct_fail_count: 直连测试失败次数(次要,通常是目标服务/网络问题)
# link_warn_count: 警告次数(工具缺失/网卡缺失/无法获取目标等)
local link_fail_count=0
local link_direct_fail_count=0
local link_warn_count=0

# TCP 默认测试(必测)
echo " ├─ TCP 链路测试(目标:https://www.baidu.com)"
# 直连测试(默认路由)
echo -n " │ ├─ 直连测试... "
if curl -s --max-time 5 --connect-timeout 3 "https://www.baidu.com" >/dev/null 2>&1; then
echo -e "${GREEN}[OK] 成功${NC}"
else
echo -e "${RED}[FAIL] 失败${NC}"
((link_direct_fail_count++))
fi
# 加速测试(强制走 mp_tun0)
echo -n " │ └─ 加速测试(mp_tun0)... "
if ip link show mp_tun0 &> /dev/null; then
if curl -s --max-time 5 --connect-timeout 3 --interface mp_tun0 "https://www.baidu.com" >/dev/null 2>&1; then
echo -e "${GREEN}[OK] 成功${NC}"
else
echo -e "${RED}[FAIL] 失败${NC}"
((link_fail_count++))
fi
else
echo -e "${YELLOW}[WARN] 网卡不存在${NC}"
((link_warn_count++))
fi
# UDP 测试:自动从加速状态接口获取 accGateway,或使用用户指定的目标
if [ -z "$udp_target" ]; then
# 自动获取 accGateway 作为 UDP 测试目标
local acc_response=$(curl -s -X 'GET' 'http://127.0.0.1:9801/api/v2/client/mp-speeder' -H 'accept: */*' -H 'Content-Type: application/json')
local acc_gateway=$(echo "$acc_response" | sed -n 's/.*"accGateway":"\\([^"]*\\)".*/\\1/p')
if [ -n "$acc_gateway" ]; then
udp_target="${acc_gateway}:8888"
fi
fi

if [ -n "$udp_target" ]; then
echo " ├─ UDP 链路测试(目标:$udp_target)"
local udp_host="${udp_target%%:*}"
local udp_port="${udp_target##*:}"
local udpping_tool="@BIN_DIR@/udping"
local use_nc=false
local has_udping=false
local has_nc=false

[ -x "$udpping_tool" ] && has_udping=true
command -v nc &>/dev/null && has_nc=true

# 优先使用 udping(自研工具,能准确测出 RTT 和丢包率);缺失时降级使用 nc
if [ "$has_udping" = "true" ]; then
use_nc=false
elif [ "$has_nc" = "true" ]; then
echo -e "${YELLOW} │ ├─ [WARN] 未找到 udping 工具(预期路径: $udpping_tool)${NC}"
echo -e "${YELLOW} │ │ 将降级使用 nc 进行 UDP 测试,结果仅供参考${NC}"
echo -e "${YELLOW} │ │ 建议重新执行部署脚本确保 udping 正确安装${NC}"
use_nc=true
else
echo -e "${YELLOW} │ └─ [WARN] udping 和 nc 均不可用,跳过 UDP 测试${NC}"
echo -e "${YELLOW} │ udping 预期路径: $udpping_tool(缺失请重新部署)${NC}"
echo -e "${YELLOW} │ 或安装 netcat 工具: apt install netcat / yum install nc${NC}"
use_nc=""
((link_warn_count++))
fi

if [ "$use_nc" = "true" ]; then
# 使用 nc 进行 UDP 连通性测试(结果仅供参考,判 WARN 不判 FAIL)
echo -n " │ ├─ 直连测试(nc)... "
local nc_response
nc_response=$(echo "ping" | timeout 3 nc -u -w 2 "$udp_host" "$udp_port" 2>/dev/null)
if [ -n "$nc_response" ]; then
echo -e "${GREEN}[OK] 成功${NC}"
else
echo -e "${RED}[FAIL] 失败${NC}"
((link_warn_count++))
fi

echo -n " │ └─ 加速测试(mp_tun0, nc)... "
if ip link show mp_tun0 &>/dev/null; then
local tun_ip=$(ip -4 addr show mp_tun0 2>/dev/null | grep -oP 'inet \\K[\\d.]+' | head -n1)
nc_response=$(echo "ping" | timeout 3 nc -u -w 2 -s "$tun_ip" "$udp_host" "$udp_port" 2>/dev/null)
if [ -n "$nc_response" ]; then
echo -e "${GREEN}[OK] 成功${NC}"
else
echo -e "${RED}[FAIL] 失败${NC}"
((link_warn_count++))
fi
else
echo -e "${YELLOW}[WARN] mp_tun0 网卡不存在${NC}"
((link_warn_count++))
fi
elif [ "$has_udping" = "true" ]; then
# 使用 udping 进行测试,-C 3 发送3个包后停止
echo -n " │ ├─ 直连测试(udping)... "
local udping_output
udping_output=$("$udpping_tool" -c "$udp_target" -C 3 2>&1)
if [ $? -eq 0 ] && echo "$udping_output" | grep -q "Rx:[1-9]"; then
# 提取 RTT 信息
local avg_rtt=$(echo "$udping_output" | grep -oP 'AvgRTT:\\K[0-9.]+')
local loss_rate=$(echo "$udping_output" | grep -oP 'LossRate:\\K[0-9.]+')
echo -e "${GREEN}[OK] 成功 (AvgRTT: ${avg_rtt:-N/A}μs, Loss: ${loss_rate:-N/A})${NC}"
else
echo -e "${RED}[FAIL] 失败${NC}"
((link_direct_fail_count++))
fi

echo -n " │ └─ 加速测试(mp_tun0, udping)... "
if ip link show mp_tun0 &>/dev/null; then
udping_output=$("$udpping_tool" -c "$udp_target" -I mp_tun0 -C 3 2>&1)
if [ $? -eq 0 ] && echo "$udping_output" | grep -q "Rx:[1-9]"; then
local avg_rtt=$(echo "$udping_output" | grep -oP 'AvgRTT:\\K[0-9.]+')
local loss_rate=$(echo "$udping_output" | grep -oP 'LossRate:\\K[0-9.]+')
echo -e "${GREEN}[OK] 成功 (AvgRTT: ${avg_rtt:-N/A}μs, Loss: ${loss_rate:-N/A})${NC}"
else
echo -e "${RED}[FAIL] 失败${NC}"
((link_fail_count++))
fi
else
echo -e "${YELLOW}[WARN] mp_tun0 网卡不存在${NC}"
((link_warn_count++))
fi
fi
else
echo -e "${YELLOW} └─ [WARN] 无法获取 UDP 测试目标(accGateway 为空),跳过 UDP 测试${NC}"
((link_warn_count++))
fi

# 结果判定:
# 1. 有加速测试失败(TCP-tun0 或 UDP-udping-tun0)→ FAIL(业务受影响)
# 2. 只有直连失败但加速正常 → WARN(网络/目标问题,加速仍可用)
# 3. 有 WARN 但无 FAIL → WARN
# 4. 全部成功 → PASS
if [ $link_fail_count -gt 0 ]; then
echo -e "${RED} └─ [FAIL] 业务链路检查失败(加速测试失败 $link_fail_count 项,业务受影响)${NC}"
error_results+=("[10] 业务链路检查 FAIL (加速测试失败)")
return 1
elif [ $link_direct_fail_count -gt 0 ]; then
echo -e "${YELLOW} └─ [WARN] 业务链路检查完成(直连失败 $link_direct_fail_count 项,加速正常)${NC}"
warning_results+=("[10] 业务链路检查 WARN (直连失败但加速正常)")
return 0
elif [ $link_warn_count -gt 0 ]; then
echo -e "${YELLOW} └─ [WARN] 业务链路检查完成(含 $link_warn_count 项警告)${NC}"
warning_results+=("[10] 业务链路检查 WARN")
return 0
else
echo -e "${GREEN} └─ [OK] 业务链路检查完成${NC}"
check_results+=("[10] 业务链路检查 PASS")
return 0
fi
}

# 函数:生成汇总报告
generate_summary_report() {
echo "=========================================="
echo -e "${BLUE}检查结果汇总:${NC}"
local total_checks=$(( ${#check_results[@]} + ${#warning_results[@]} + ${#error_results[@]} ))
if [ ${#check_results[@]} -gt 0 ]; then
echo -e "${GREEN}[PASS] 正常项(${#check_results[@]}/$total_checks):${NC}"
for result in "${check_results[@]}"; do
echo " $result"
done
fi
if [ ${#warning_results[@]} -gt 0 ]; then
echo -e "${YELLOW}[WARN] 警告项(${#warning_results[@]}/$total_checks):${NC}"
for result in "${warning_results[@]}"; do
echo " $result"
done
fi
if [ ${#error_results[@]} -gt 0 ]; then
echo -e "${RED}[FAIL] 错误项(${#error_results[@]}/$total_checks):${NC}"
for result in "${error_results[@]}"; do
echo " $result"
done
fi

if [ ${#error_results[@]} -eq 0 ] && [ ${#warning_results[@]} -eq 0 ]; then
echo -e "${GREEN}所有检查项均正常!${NC}"
fi
}

# 解析命令行参数
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--help)
echo "用法: $0 [选项]"
echo "选项:"
echo " -h, --help 显示帮助信息"
echo " -l, --l3-check 检查 L3 功能"
echo " --link-only 仅执行链路检查(快速测试)"
echo " --udp-target <目标> 指定 UDP 测试目标(格式:IP:PORT)"
exit 0
;;
-l|--l3-check)
l3_check=true
shift
;;
--link-only)
link_only=true
shift
;;
--udp-target)
udp_target="$2"
shift 2
;;
*)
echo -e "${RED}[FAIL] 未知参数: $1${NC}"
exit 1
;;
esac
done

# 清空结果数组
check_results=()
warning_results=()
error_results=()

echo "开始系统检查..."
echo "----------------------------------------"

# 新增检查项放在最前面
check_local_time
check_certificate
check_resource_files

# 如果指定了 --link-only,则只执行链路相关检查
if [ "$link_only" = true ]; then
echo -e "${BLUE}快速链路检查模式...${NC}"
check_business_link
generate_summary_report
exit 0
fi

echo -e "${BLUE}[4] 检查关键进程状态...${NC}"
# 检查 mp-sdk 进程
check_process "mp-sdk"

# 检查 mp-speeder 进程
check_process "mp-speeder"

echo -e "${BLUE}[5] 检查网卡状态...${NC}"
check_interface "mp_tun0"

echo -e "${BLUE}[6] 检查加速状态...${NC}"
check_speeder_status

echo -e "${BLUE}[7] 检查rp_filter配置...${NC}"
check_rp_filter

echo -e "${BLUE}[8] 检查策略路由配置...${NC}"
check_policy_routing

echo -e "${BLUE}[9] iptables 检查...${NC}"
check_iptables_rules

# 如果指定了 --l3-check 参数,则执行 L3 功能检查
if [ "$l3_check" = true ]; then
echo -e "${BLUE}[L3] 检查 L3 功能...${NC}"
check_l3_functionality
fi

echo -e "${BLUE}[10] 检查业务链路连通性...${NC}"
check_business_link

echo "----------------------------------------"

# 生成汇总报告
generate_summary_report

# 根据错误结果决定退出码
if [ ${#error_results[@]} -gt 0 ]; then
exit 1
else
exit 0
fi


2.1.2 一键排查异常结果及解决方案

检测内容
具体内容
检测异常结果项
解决方案
检查进程是否运行
-
进程未运行
1. SDK 进程不存在:配置了开机自启动,检查服务状态,也可以使用 Systemctl restart mp-sdk
2. mp-speeder 进程不存在:检查是否未调用 API 启动加速,调用 API 启动加速即可。
检查网卡是否存在
-
网卡存在但未启动
查看“检查 speeder 状态”。
-
网卡不存在
检查是否有 tun 内核模块(modinfo tun)。
检查 rp_filter
-
rp_filter 未关闭
sysctl -w net.ipv4.conf.mp_tun0.rp_filter=0。
检查策略路由
-
路由表中未找到正确的默认路由
重启 SDK。
-
未找到策略规则
重启 SDK。
检查基于源 ip 的策略规则是否存在
获取网卡 IP 地址
网卡未配置 IP 地址,无法通过此网卡加速,建议检查
建议关注,可不处理。
检查策略规则是否存在
路由表中未找到路由
重启 SDK。
未找到网卡的策略规则,可能影响加速效果,建议开启 SDK 策略路由管理
开启 SDK 策略路由管理。
检查 speeder 状态
-
未运行或加速状态异常
1. 调用 API 启动加速。
2. 启动失败,自查可能原因:datakey 失效,网络未连通。
3. 其他情况联系腾讯云运维人员。
检查 引流规则
-
未检查到引流规则,请确认是否符合预期
1. 确认是否调用 API 添加引流策略。
2. 添加失败一般为引流规则配置问题,例如 TCP、UDP 等拼写错误、端口号超过65536等,自查排除此类问题。
3. 其他情况联系腾讯云运维人员。
检查 L3 功能
检查 wireguard 虚拟口状态
wireguard 虚拟口状态异常
1. 无 wireguard 虚拟口可能是网络原因,与控制器失联,优先排除。
2. 其他情况联系腾讯云运维人员。
检查路由表
路由表中未找到正确的路由
1. 如果机器存在与 L3 相同的路由,需要形成 ECMP 场景,当前不支持。
2. 其他情况联系腾讯云运维人员。
检查 endpoint 是否符合198.18.x.x 形式
endpoint 不符合198.18.x.x 形式
联系腾讯云运维人员。
检查引流规则-检查 OUTPUT 链中的 chain 顺序
OUTPUT 链中缺少必要的 chain
联系腾讯云运维人员。
mp_route_bypass 不在 OUTPUT 链的第一位
此问题一般为用户手动添加了其他规则,请自查。
检查引流规则-检查 mp_route_bypass 链中的规则
mp_route_bypass 链中缺少目标的 ACCEPT 规则
此问题一般为用户手动删除了对应规则,请自查。
检查 mp_l3_route 链中的规则
mp_l3_route 链中缺少目标端的 MARK 规则
此问题一般为用户手动删除了对应规则,请自查。

2.2 Iperf 打流的聚合带宽达不到各链路带宽叠加性能

常见问题:
多网卡加速,性能不及各链路带宽之和。
单网卡加速,性能远低于不加速的链路带宽。

2.2.1 常见原因及解决方案

说明:
如果要分别测试物理链路和加速链路的带宽,请使用 iperf 的 -B 参数分别指定物理链路和加速链路测试,并且此时不能通过 sdk 的特定引流规则引流 iperf server 的 ip,否则 iperf 的 -B 参数不会生效,所有流量都会走加速链路。

2.2.1.1 部分链路因网络质量差被禁用

常见链路被禁用原因:链路 RTT 时延过大或抖动大、链路丢包。可通过 1.2.3 SDK 日志分析 确认链路网络时延、丢包以及禁用情况。
解决方案:
更换网络质量差的物理链路进行测速。
调整链路禁用条件,调大以下参数(例如:高于链路实际时延),让所有链路尽量参与聚合。
注意:默认参数兼顾带宽及时延等综合性能,此调整仅用于测试极限聚合带宽。
MaxRttDisableAggregation:聚合链路时延阈值。
MaxRttThreshold:链路故障检测阈值。

2.2.1.2 物联网卡问题

场景:有一路或者多路物联网卡参与加速,但是物联网卡没有对我们的服务器 ip 做过开白,会导致打流效果差,这一路会禁用。
解决方案:
更换网卡,使用普通的卡。
物联网卡对云聚通服务器 ip 开白。

2.2.1.3 终端设备的 CPU 能力受限

查询设备 CPU 核使用率,若各核 CPU 使用率都很高(如 90%),则说明性能受限于设备能力。
典型配置的性能,请咨询腾讯运维人员。

2.2.1.4 策略路由未正确配置

观察流量是否从多张加速网卡发出。
如果不是从多张加速网卡发出,通过以下方法确认是否配置了每张网卡的策略路由:
方法 1:执行一键检测脚本:检查是否配置了每张加速网卡的基于源 IP 的策略路由。并根据提示配置正确的策略路由。
方法 2:命令行查询 IP rule 及对应的策略路由。
正常会在对应路由表中配置默认路由。

2.2.1.5 多张加速网卡是同一运营商出口

如果蜂窝网络的多张 SIM 卡属于同一个运营商,多张卡可能接入同一个基站小区,受限于小区整体带宽容量,增加 SIM 数量可能不能增加总带宽。可考虑更换为其他运营商 SIM 增加总的链路带宽。
查询网卡的公网 IP 地址:
参考命令:curl --interface eth0 ip.sb
查询 IP 地址,请参见 运营商属性网站

2.2.1.6 socket buffer 低导致

打流时查看网络收发包状态,如果发现 udp 收发包 buffer error,可调大该值。
netstat -su 持续查看 iperf server socket buffer,关注是否存在 buffer error。
查看 socket buffer 大小。
调整 socket buffer 大小。
调整后重启加速。

2.2.1.7 硬件不支持加解密指令

解决方案:
关闭加解密功能。
/usr/local/etc/mp-speeder/mp_client_extend.conf 文件配置 -disableCrypto,关闭数据加解密功能。
使用支持加解密指令的硬件。

2.3 Iperf 打流出现断流

问题表现:测速聚合链路带宽,iperf TCP 打流过程中流量出现掉底现象。

2.3.1 参与聚合的链路全部弱网丢包

可通过 SDK 日志分析确认链路网络时延、丢包以及禁用情况。
日志检索关键词: potentiallyFailed。

2.3.2 移动网络在4G/5G 网络之间频繁切换

单张网卡的基础网络性能差,不加速时,也表现出时延抖动大、打流时出现断流的情况。
可通过4/5G 模组 AT 指令集,查看模组驻留的网络以及信号强度、信号质量。

2.4 策略路由问题

2.4.1 SDK 添加了多条重复的策略路由

可以查看是否存在重复拉起 SDK 的情况。
查看方式:通过查看 /var/log/mp-sdk.log,同一时刻是否有多次出现“Server started on ……”。

2.4.2 详细路由出错或者为空

可以查看是否存在脚本拉起程序时有重复关闭策略路由再开启策略路由的情况。
查看方式:通过查看 /var/log/mp-sdk.log中的policyRouteManagement 是否在开启加速时快速调用了关闭和开启。

2.5 防火墙问题

2.5.1 如发现业务不通,抓包 mp_tun0只有上行没有下行

可以执行 iptables -I INPUT -i mp_tun0 -j ACCEPT 后观察是否打通,如程序恢复则可将该命令固化到启动云聚通的脚本中。