本文档用于客户在使用云聚通产品时指导定位和排查问题。
1. 业务性能问题常见原因及排障方法
本节主要介绍用户在使用聚合、实时加速时,业务效果未达到预期时的常见原因和排障方法。
业务效果未达预期的现象。例如:推流/拉流视频卡顿或花屏或丢帧。
1.1 常见原因
1.1.1 加速模式选择不合适
加速模式配置不合适,例如应使用实时模式,配置了聚合模式。需根据业务类型及性能需求选择合适的加速模式,具体配置建议咨询腾讯运维人员。
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 日志分析
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 -hUsage of /usr/local/bin/mp-speeder/udping:-C intping count-I stringbind interface name-c stringprobe address, IP:PORT-i durationping interval (default 1s)-l intpayload length-logLevel stringlog level, default info-o output to shell-v show version-w durationping timeout (default 1s)
具体参数配置建议:
-c stringprobe 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=falselink_only=falseudp_target=""# 存储检查结果check_results=()warning_results=()error_results=()# 函数:检查进程是否运行check_process() {local process_name=$1if pgrep -f "$process_name" > /dev/null; thenecho -e "${GREEN} ├─ [OK] 进程 $process_name 正在运行${NC}"check_results+=("[4] $process_name 进程检查 PASS")elseecho -e "${RED} ├─ [FAIL] 进程 $process_name 未运行${NC}"error_results+=("[4] $process_name 进程检查 FAIL")fi}# 函数:检查网卡是否存在并启动check_interface() {local interface=$1if ip link show "$interface" &> /dev/null; thenif ip link show "$interface" | grep -q "UP"; thenecho -e "${GREEN} └─ [OK] 网卡 $interface 已启动且状态正常${NC}"check_results+=("[5] 网卡检查 PASS")elseecho -e "${RED} └─ [FAIL] 网卡 $interface 存在但未启动${NC}"error_results+=("[5] 网卡检查 FAIL")fielseecho -e "${RED} └─ [FAIL] 网卡 $interface 不存在${NC}"error_results+=("[5] 网卡检查 FAIL")fi}# 函数:检查 rp_filtercheck_rp_filter() {if sysctl net.ipv4.conf.mp_tun0.rp_filter | grep -q "net.ipv4.conf.mp_tun0.rp_filter = 1"; thenecho -e "${RED} └─ [FAIL] rp_filter 未关闭${NC}"error_results+=("[7] rp_filter 检查 FAIL")elseecho -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"; thenlocal 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"; thenecho -e "${GREEN} ├─ [OK] 路由表 $table_num 中存在正确的默认路由${NC}"elseecho -e "${RED} ├─ [FAIL] 路由表 $table_num 中未找到正确的默认路由${NC}"has_error=truefielseecho -e "${RED} ├─ [FAIL] 未找到策略规则: from 198.18.0.1${NC}"has_error=truefifor 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" ]; thenecho -e "${YELLOW} ├─ [WARN] 网卡 $iface 未配置IP地址,无法通过此网卡加速,建议检查${NC}"continuefi# 检查策略规则是否存在if ip rule | grep -q "from $ip_addr lookup"; thenlocal 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"; thenecho -e "${GREEN} ├─ [OK] 路由表 $table_num 配置正确${NC}"elseecho -e "${RED} ├─ [FAIL] 路由表 $table_num 中未找到路由${NC}"has_error=truefielseecho -e "${YELLOW} ├─ [WARN] 未找到网卡 $iface ($ip_addr) 的策略规则,可能影响加速效果,建议开启SDK策略路由管理${NC}"fidoneif [ "$has_error" = true ]; thenerror_results+=("[8] 策略路由检查 FAIL")elsecheck_results+=("[8] 策略路由检查 PASS")fi}# 函数:检查 speeder 状态check_speeder_status() {local responseresponse=$(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'; thenecho -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")elseecho -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"; thenecho -e "${GREEN} ├─ [OK] 引流规则 mp_route_mark 检查通过${NC}"check_results+=("[9] iptables-引流规则 PASS")elseecho -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; thenecho -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_erradd_err=$(iptables -t $test_table -A $test_args 2>&1)if [ $? -ne 0 ]; thenecho -e "${RED} ├─ [FAIL] iptables 添加测试规则失败: ${add_err}${NC}"error_results+=("[9] iptables-功能验证 FAIL")elsedel_err=$(iptables -t $test_table -D $test_args 2>&1)if [ $? -ne 0 ]; thenecho -e "${RED} ├─ [FAIL] iptables 删除测试规则失败: ${del_err}${NC}"echo -e "${RED} │ 请手工清理残留: iptables -t ${test_table} -D ${test_args}${NC}"error_results+=("[9] iptables-功能验证 FAIL")elseecho -e "${GREEN} ├─ [OK] iptables 功能验证通过(测试规则添加/删除均成功)${NC}"check_results+=("[9] iptables-功能验证 PASS")fififi# -------- 子项 3:nat 表 MARK 冲突扫描 --------# 扫描 iptables -t nat -nvL 中 target 列为 MARK 的规则,如果存在则提示用户排查local nat_output nat_mark_linesnat_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" ]; thenecho -e "${YELLOW} └─ [WARN] 检测到 nat 表中存在 MARK 规则,请排查是否会影响 SDK 的 mangle 表 0x1/0xf mark:${NC}"echo "$nat_mark_lines" | sed 's/^/ /'warning_results+=("[9] iptables-NAT MARK冲突 WARN")elseecho -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 secondslocal responseresponse=$(@BIN_DIR@/wg show)if echo "$response" | grep -q "latest handshake"; thenecho -e "${GREEN} ├─ [OK] wireguard 虚拟口状态正常${NC}"elseecho -e "${RED} ├─ [FAIL] wireguard 虚拟口状态异常${NC}"return 1fi# 检查路由表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" ]; thenecho -e "${RED} ├─ [FAIL] 无法从 wireguard 配置中获取接口名或允许的 IP${NC}"return 1fi# 检查路由表local routing_tables=$(ip route)local expected_route="$allowed_ips dev $interface_name scope link"if echo "$routing_tables" | grep -q "$expected_route"; thenecho -e "${GREEN} ├─ [OK] 路由表中存在正确的路由: $expected_route${NC}"elseecho -e "${RED} ├─ [FAIL] 路由表中未找到正确的路由: $expected_route${NC}"return 1fi# 检查endpoint是否符合198.18.x.x形式local endpoint=$(echo "$response" | grep "endpoint:" | awk '{print $2}')if echo "$endpoint" | grep -q "198.18."; thenecho -e "${GREEN} ├─ [OK] endpoint符合198.18.x.x形式${NC}"elseecho -e "${RED} ├─ [FAIL] endpoint不符合198.18.x.x形式${NC}"return 1fi# 检查引流规则# 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是MARKlocal 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"; thenecho -e "${RED} ├─ [FAIL] OUTPUT 链中缺少必要的 chain${NC}"return 1fi# 确认 mp_route_bypass 在第一位if ! iptables -L OUTPUT 1 -nv -t mangle | grep -q "mp_route_bypass"; thenecho -e "${RED} ├─ [FAIL] mp_route_bypass 不在 OUTPUT 链的第一位${NC}"return 1fi# 2. 检查 mp_route_bypass 链中的规则if ! iptables -L mp_route_bypass -nv -t mangle | grep -q "ACCEPT.*$allowed_ips"; thenecho -e "${RED} ├─ [FAIL] mp_route_bypass 链中缺少目标为 $allowed_ips 的 ACCEPT 规则${NC}"return 1fi# 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"; thenecho -e "${RED} ├─ [FAIL] mp_l3_route 链中缺少目标为 $endpoint 的 MARK 规则${NC}"return 1fiecho -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" ]; thenecho -e "${YELLOW} └─ [WARN] 无法获取远程时间,跳过时间检查${NC}"return 0filocal remote_ts=$(date -d "$remote_time" +%s 2>/dev/null || echo "")local local_ts=$(date +%s)if [ -z "$remote_ts" ] || [ -z "$local_ts" ]; thenecho -e "${YELLOW} └─ [WARN] 时间转换失败,跳过时间检查${NC}"return 0filocal diff=$((local_ts - remote_ts))local abs_diff=${diff#-} # 取绝对值if [ $abs_diff -gt 300 ]; thenecho -e "${RED} └─ [FAIL] 时间偏差过大:${diff}秒(建议使用 ntpdate 同步)${NC}"error_results+=("[1] 时间检查 FAIL")return 0elif [ $abs_diff -gt 120 ]; thenecho -e "${YELLOW} └─ [WARN] 时间偏差较大:${diff}秒${NC}"warning_results+=("[1] 时间检查 WARN")return 0elseecho -e "${GREEN} └─ [OK] 时间正常(偏差 ${diff}秒)${NC}"check_results+=("[1] 时间检查 PASS")return 0fi}# 函数:检查关键资源文件(警告级别)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[@]}"; doif [ -f "$file" ] && [ -s "$file" ]; thenecho -e "${GREEN} ├─ [OK] $file 存在且非空${NC}"elsemissing_files+=("$file")echo -e "${YELLOW} ├─ [WARN] $file 缺失或为空${NC}"fidoneif [ ${#missing_files[@]} -gt 0 ]; thenecho -e "${YELLOW} └─ [WARN] 发现 ${#missing_files[@]} 个文件问题(警告级别)${NC}"local missing_list=$(printf '%s, ' "${missing_files[@]}")missing_list=${missing_list%, } # 去掉末尾逗号warning_results+=("[3] 资源文件检查 WARN (缺失: ${missing_list})")elseecho -e "${GREEN} └─ [OK] 所有资源文件正常${NC}"check_results+=("[3] 资源文件检查 PASS")fireturn 0}# 函数:检查证书是否正常check_certificate() {echo -e "${BLUE}[2] 检查证书...${NC}"# 通过 HTTPS 请求验证系统证书链是否正常local curl_outputcurl_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; thenecho -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 issueecho -e "${RED} └─ [FAIL] 证书验证失败(curl exit code: $curl_exit),请检查系统 CA 证书${NC}"error_results+=("[2] 证书检查 FAIL")elseecho -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=0local link_direct_fail_count=0local 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; thenecho -e "${GREEN}[OK] 成功${NC}"elseecho -e "${RED}[FAIL] 失败${NC}"((link_direct_fail_count++))fi# 加速测试(强制走 mp_tun0)echo -n " │ └─ 加速测试(mp_tun0)... "if ip link show mp_tun0 &> /dev/null; thenif curl -s --max-time 5 --connect-timeout 3 --interface mp_tun0 "https://www.baidu.com" >/dev/null 2>&1; thenecho -e "${GREEN}[OK] 成功${NC}"elseecho -e "${RED}[FAIL] 失败${NC}"((link_fail_count++))fielseecho -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" ]; thenudp_target="${acc_gateway}:8888"fifiif [ -n "$udp_target" ]; thenecho " ├─ UDP 链路测试(目标:$udp_target)"local udp_host="${udp_target%%:*}"local udp_port="${udp_target##*:}"local udpping_tool="@BIN_DIR@/udping"local use_nc=falselocal has_udping=falselocal has_nc=false[ -x "$udpping_tool" ] && has_udping=truecommand -v nc &>/dev/null && has_nc=true# 优先使用 udping(自研工具,能准确测出 RTT 和丢包率);缺失时降级使用 ncif [ "$has_udping" = "true" ]; thenuse_nc=falseelif [ "$has_nc" = "true" ]; thenecho -e "${YELLOW} │ ├─ [WARN] 未找到 udping 工具(预期路径: $udpping_tool)${NC}"echo -e "${YELLOW} │ │ 将降级使用 nc 进行 UDP 测试,结果仅供参考${NC}"echo -e "${YELLOW} │ │ 建议重新执行部署脚本确保 udping 正确安装${NC}"use_nc=trueelseecho -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++))fiif [ "$use_nc" = "true" ]; then# 使用 nc 进行 UDP 连通性测试(结果仅供参考,判 WARN 不判 FAIL)echo -n " │ ├─ 直连测试(nc)... "local nc_responsenc_response=$(echo "ping" | timeout 3 nc -u -w 2 "$udp_host" "$udp_port" 2>/dev/null)if [ -n "$nc_response" ]; thenecho -e "${GREEN}[OK] 成功${NC}"elseecho -e "${RED}[FAIL] 失败${NC}"((link_warn_count++))fiecho -n " │ └─ 加速测试(mp_tun0, nc)... "if ip link show mp_tun0 &>/dev/null; thenlocal 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" ]; thenecho -e "${GREEN}[OK] 成功${NC}"elseecho -e "${RED}[FAIL] 失败${NC}"((link_warn_count++))fielseecho -e "${YELLOW}[WARN] mp_tun0 网卡不存在${NC}"((link_warn_count++))fielif [ "$has_udping" = "true" ]; then# 使用 udping 进行测试,-C 3 发送3个包后停止echo -n " │ ├─ 直连测试(udping)... "local udping_outputudping_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}"elseecho -e "${RED}[FAIL] 失败${NC}"((link_direct_fail_count++))fiecho -n " │ └─ 加速测试(mp_tun0, udping)... "if ip link show mp_tun0 &>/dev/null; thenudping_output=$("$udpping_tool" -c "$udp_target" -I mp_tun0 -C 3 2>&1)if [ $? -eq 0 ] && echo "$udping_output" | grep -q "Rx:[1-9]"; thenlocal 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}"elseecho -e "${RED}[FAIL] 失败${NC}"((link_fail_count++))fielseecho -e "${YELLOW}[WARN] mp_tun0 网卡不存在${NC}"((link_warn_count++))fifielseecho -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. 全部成功 → PASSif [ $link_fail_count -gt 0 ]; thenecho -e "${RED} └─ [FAIL] 业务链路检查失败(加速测试失败 $link_fail_count 项,业务受影响)${NC}"error_results+=("[10] 业务链路检查 FAIL (加速测试失败)")return 1elif [ $link_direct_fail_count -gt 0 ]; thenecho -e "${YELLOW} └─ [WARN] 业务链路检查完成(直连失败 $link_direct_fail_count 项,加速正常)${NC}"warning_results+=("[10] 业务链路检查 WARN (直连失败但加速正常)")return 0elif [ $link_warn_count -gt 0 ]; thenecho -e "${YELLOW} └─ [WARN] 业务链路检查完成(含 $link_warn_count 项警告)${NC}"warning_results+=("[10] 业务链路检查 WARN")return 0elseecho -e "${GREEN} └─ [OK] 业务链路检查完成${NC}"check_results+=("[10] 业务链路检查 PASS")return 0fi}# 函数:生成汇总报告generate_summary_report() {echo "=========================================="echo -e "${BLUE}检查结果汇总:${NC}"local total_checks=$(( ${#check_results[@]} + ${#warning_results[@]} + ${#error_results[@]} ))if [ ${#check_results[@]} -gt 0 ]; thenecho -e "${GREEN}[PASS] 正常项(${#check_results[@]}/$total_checks):${NC}"for result in "${check_results[@]}"; doecho " $result"donefiif [ ${#warning_results[@]} -gt 0 ]; thenecho -e "${YELLOW}[WARN] 警告项(${#warning_results[@]}/$total_checks):${NC}"for result in "${warning_results[@]}"; doecho " $result"donefiif [ ${#error_results[@]} -gt 0 ]; thenecho -e "${RED}[FAIL] 错误项(${#error_results[@]}/$total_checks):${NC}"for result in "${error_results[@]}"; doecho " $result"donefiif [ ${#error_results[@]} -eq 0 ] && [ ${#warning_results[@]} -eq 0 ]; thenecho -e "${GREEN}所有检查项均正常!${NC}"fi}# 解析命令行参数while [[ "$#" -gt 0 ]]; docase $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=trueshift;;--link-only)link_only=trueshift;;--udp-target)udp_target="$2"shift 2;;*)echo -e "${RED}[FAIL] 未知参数: $1${NC}"exit 1;;esacdone# 清空结果数组check_results=()warning_results=()error_results=()echo "开始系统检查..."echo "----------------------------------------"# 新增检查项放在最前面check_local_timecheck_certificatecheck_resource_files# 如果指定了 --link-only,则只执行链路相关检查if [ "$link_only" = true ]; thenecho -e "${BLUE}快速链路检查模式...${NC}"check_business_linkgenerate_summary_reportexit 0fiecho -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_statusecho -e "${BLUE}[7] 检查rp_filter配置...${NC}"check_rp_filterecho -e "${BLUE}[8] 检查策略路由配置...${NC}"check_policy_routingecho -e "${BLUE}[9] iptables 检查...${NC}"check_iptables_rules# 如果指定了 --l3-check 参数,则执行 L3 功能检查if [ "$l3_check" = true ]; thenecho -e "${BLUE}[L3] 检查 L3 功能...${NC}"check_l3_functionalityfiecho -e "${BLUE}[10] 检查业务链路连通性...${NC}"check_business_linkecho "----------------------------------------"# 生成汇总报告generate_summary_report# 根据错误结果决定退出码if [ ${#error_results[@]} -gt 0 ]; thenexit 1elseexit 0fi
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 部分链路因网络质量差被禁用
解决方案:
更换网络质量差的物理链路进行测速。
调整链路禁用条件,调大以下参数(例如:高于链路实际时延),让所有链路尽量参与聚合。
注意:默认参数兼顾带宽及时延等综合性能,此调整仅用于测试极限聚合带宽。
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
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 后观察是否打通,如程序恢复则可将该命令固化到启动云聚通的脚本中。