十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用FRP把ADB远程调试通道接回研发环境:车载中控屏问题排查实战

用FRP把ADB远程调试通道接回研发环境:车载中控屏问题排查实战 想先从一个真实场景说起。去年有一批车机在客户那边出现“偶发性黑屏重启”视频拍回来十几条研发部开了一下午会猜了七八个方向——电源时序、屏幕背光驱动、系统内存压力、第三方应用崩溃——但没有一个人能给出定论。原因很简单手里没有现场那台设备的 ADB。这种场景做车载中控屏研发的朋友应该都不陌生。客户现场的 Android 车机一旦出问题最常见的路径是售后录视频、拍照片、导日志文件回传但这些流程到研发手里往往已经丢掉了关键的原始现场信息。于是我们把目光放到了“把 ADB 这条调试通道直接从客户现场接回研发环境”上用的工具是 FRP走的是 ADB 自带的网络调试协议。整套链路折腾完之后感觉这完全可以作为车载团队的日常远程调试基础设施来用。这篇文章就围绕这条链路展开FRP 在这里面到底扮演什么角色公网侧和车机侧分别怎么配连上之后日常调试怎么用以及我实测过程中踩过的那些坑。1. 客户现场的疑难杂症为什么必须把 ADB 接回研发环境1.1 一个典型场景售后传回来的视频救不了急车载中控屏的问题有个特点大部分是偶发的、环境相关的。比如客户反映“导航用着用着屏幕闪一下”售后到现场看的时候可能等半小时都不复现比如“蓝牙电话听完之后多媒体没声音”这问题可能跟某个特定手机型号、某个特定通话时间点都有关。售后能做的就是拍视频、拍照片、把用户描述整理成工单。但这些信息到研发手里基本只能靠猜。真正能定位问题的数据都在系统里面。崩溃栈、ANR 日志、system_server 的异常输出、当前窗口焦点变化、内存压力曲线——这些只有通过 ADB 才能拿到。没有 ADB就像医生看病不让量体温、不让拍片子只能听病人描述“我大概哪里不舒服”。我自己经历过的例子一台车机偶发性重启售后录了视频能看出来是重启了但没人知道重启前系统里发生了什么。后来我们通过 ADB 连上去抓了几天的 logcat才看到是某个后台服务在特定网络环境下触发了内核 panic。如果没有 ADB这个问题可能要在客户现场换好几台整机才能蒙对方向。1.2 ADB 在车机问题排查里到底能干什么ADBAndroid Debug Bridge的价值不只是“敲几条命令”它是个完整的调试通道logcat实时看系统日志、应用日志、崩溃栈还能按缓冲区区分 main、system、crash、events。车机问题里最常见的 app crash、native crash、ANR几乎都能从这里找到线索。dumpsys查询系统服务的内部状态。比如dumpsys window能看当前焦点窗口是什么dumpsys meminfo能查内存占用dumpsys battery能看电池/电源状态dumpsys package能查应用安装情况。车机上很多“界面卡在某页”“应用退到后台后被杀”的问题都靠它来确认现场状态。screencap / screenrecord直接把车机屏幕截下来或录下来不需要现场人员配合。input远程注入触摸、按键、滑动事件。研发可以直接在远程环境里“动手操作”车机复现操作路径。push / pull往车机里推调试 APK、配置文件或者把车机里的数据库、日志拉回来。这些能力组合起来基本等于把研发的工位搬到了车机面前。1.3 只靠“现场人员协助”的常见做法为什么不够用在没有远程 ADB 通道的时候团队通常尝试过这些办法让售后/客户在车机上装日志抓取 App。听起来可行但很多问题在 App 启动之前就发生了而且用户场景多变装个 App 等于让用户当测试员数据质量很难保证。OTA 一个带 debug 的固件给客户升级。这个流程太慢通常要法务、质量、售后好几道审批。而且问题固件可能根本装不上或者升级本身就把现场情况给覆盖了。研发人员打飞的去现场。这是最后的兜底方案成本高、周期长而且人到了现场不一定能复现可能就白跑一趟。这些办法的共同问题是它们都是“一次性”的而问题排查往往是迭代的——看了日志产生新假设需要再抓另一份数据再调一次参数再试一次复现路径。如果没有一个持续在线的调试通道每次迭代都意味着几天的沟通成本。2. 为什么选 FRP 作为这条 ADB 回传链路的管道2.1 FRP 的原理一句话把内网服务挂到公网端口FRP 是个开源内网穿透工具全称 Fast Reverse Proxy。核心思路很简单一台有公网 IP 的服务器上跑frps内网设备上跑frpcfrpc 主动向外连接 frps并在 frps 上注册一个“代理”。之后任何人访问 frps 的某个端口流量就会被 frps 原样转发给 frpcfrpc 再把流量转给内网设备上指定的本地端口。放到我们的场景里就是车机上的 adbd 监听 5555 端口frpc 把车机的 5555 端口映射到公网 VPS 的 15555 端口研发在办公室执行adb connect VPS_IP:15555就连上了客户现场那台车机的 adbd。关键点在于车机不需要有公网 IP只要能主动访问到公网 VPS 就行。绝大多数车机在客户现场都是走 Wi-Fi 或者 4G/5G 网络都在 NAT 后面没有入站连接条件。FRP 这种“反向代理”方式恰好解决这个问题。2.2 和直连端口映射、商业远程软件、自研通道对比刚开始做技术选型的时候我们也对比过几个方案方案优点缺点结论运营商专线/公网 IP延迟低、稳定客户现场没条件装成本太高不可行商业远程桌面向日葵/TeamViewer 等能看屏幕、能远程操作拿不到 ADB 通道、权限受限、车机需要额外装 App可辅助但不能替代 ADB自研云通道车机端 Agent完全可控工作量大要自己做心跳、加密、协议解析重了前期不划算FRP轻量、开源、只转发 TCP、配置简单自己负责服务端安全选定方案为什么 ADB 特别适合走 FRP因为 ADB 的网络模式本质就是 TCP。开启adb tcpip 5555之后adbd 就在 5555 端口上监听FRP 只管做 TCP 流量转发完全不关心上层协议内容。ADB 的握手、认证、命令交互都是建立在 TCP 之上的所以 FRP 对 ADB 是完全透明的不存在协议兼容问题。2.3 整条链路的拓扑结构把上面这些串在一起完整链路是这样的客户现场车机 adbd 监听 127.0.0.1:5555 ↑ frpc车机上运行主动连接公网 VPS 的 7000 端口 ↓ 公网 VPSfrps 运行 接收 frpc 注册开放 15555 端口 ↓ 研发 PC adb connect VPS_IP:15555 → 流量经 frps 转发 → frpc → 车机 adbd链路里每个节点职责单一车机跑 adbd 和 frpcVPS 只做流量转发研发 PC 只需要标准 ADB 工具。没有复杂的协议转换没有额外的中间层。3. 公网侧准备FRP 服务端和研发连接环境3.1 VPS 选型与基础安全配置FRP 服务端最好放在离车机现场比较近的机房这样能降低 RTT。如果车机大部分在华东就选华东的节点如果全国分散选一个中部节点可能更均衡。配置不用太高1 核 1G 内存跑 frps 绰绰有余但带宽建议 5Mbps 以上因为后面截屏、拉日志都走这条链路。VPS 操作系统我选的是 Ubuntu 22.04 LTSDebian 系在包管理上比较顺手。拿到机器后第一件事不是装 frps而是先改 SSH 端口、禁用密码登录、配好防火墙。别小看这一步公网机器暴露 22 端口默认口令很容易被爆破尤其是这种以后要承载调试链路的机器安全底线不能松。3.2 新版 frps.toml 配置与启动方式FRP 在 0.52 版本之后把配置格式从 INI 改成了 TOML。网上大量教程还在用老的 INI 写法我强烈建议新部署直接用 TOML因为后续版本已经逐步放弃对老格式的支持。下面是我在用的 frps.toml# /etc/frp/frps.toml bindPort 7000 auth.method token auth.token 这里替换成强随机字符串 webServer.addr 0.0.0.0 webServer.port 7500 webServer.user admin webServer.password 这里替换成另一组强密码这里解释下几个配置项的用途bindPort 7000是 frpc 回连的端口可以改成不常见的端口不过因为后面有 token 做认证端口本身不是最关键的。auth.token是 frpc 连接 frps 时的凭证建议用openssl rand -hex 32生成一串 64 位十六进制随机字符串。千万别用 admin/123456 这种。webServer是 frps 自带的面板能看当前有哪些代理在线、流量多少。这个只建议在排查问题时打开平时可以把端口限制为研发出口 IP。启动方式我用 systemd 托管保证 VPS 重启后 frps 能自动起来。配置文件放在/etc/frp/frps.tomlservice 文件内容如下[Unit] DescriptionFRP Server Afternetwork.target [Service] Typesimple ExecStart/usr/local/bin/frps -c /etc/frp/frps.toml Restartalways RestartSec5 [Install] WantedBymulti-user.target之后执行systemctl daemon-reload systemctl enable frps systemctl start frpsVPS 防火墙如果用的是云厂商的安全组也是类似配置需要放行这么几个端口7000/tcp给 frpc 回连15555/tcp以及后续规划的其它 ADB 映射端口给研发连接7500/tcp给面板。这里建议在云控制台的安全组里直接把 ADB 映射端口来源 IP 限制成研发团队的出口 IP 段而不是对全公网开放。3.3 研发本机 ADB 环境准备与连接验证研发 PC 这侧不需要装 frpc只需要标准的 ADB 工具。Android SDK Platform-Tools 里自带 adbmacOS 上也可以用 Homebrew 装android-platform-toolsLinux 发行版仓库里一般也有adb包。装好之后先确认版本和连接状态adb version然后测试连接adb connect VPS_IP:15555 adb devices如果看到状态是unauthorized说明车机端弹了 RSA 授权确认框需要去车机上点一下允许如果看到device链路就通了。第一次连接成功的时候我还记得整个调试群都热闹了一下——因为这意味着客户现场那台反复出问题的车机现在就在我们的工位上。4. 车机侧落地ADB 开启、frpc 部署、断线自愈4.1 先把车载设备的 ADB 网络调试跑起来车机这侧的准备工作核心是把 adbd 切到 TCP 监听模式。普通 Android 设备在“开发者选项”里能直接开“无线调试”但车载中控屏的固件千差万别很多没有暴露这个开关。通用的做法是先用 USB 连上一台调试电脑执行adb tcpip 5555这条命令会让 adbd 在 5555 端口开始监听 TCP 连接。执行完之后USB 线就可以拔掉了车机变成一个“ADB over TCP”的调试目标。需要注意Android 11 及以上引入了无线调试配对流程adb pair部分新版本固件里传统的adb tcpip 5555可能仍然可用但有些定制系统会限制必须在设置界面里手动配对。如果遇到这种情况解决办法是连 USB 时先把ro.adb.secure相关配置调成允许调试或者走配对流程拿到 pairing code 后再做 FRP 转发。总之先把“车机本机能够被远程 adb connect”这一步跑通再谈 FRP。另外车机必须保证在客户现场能联网。如果是走 Wi-Fi要确保 Wi-Fi 不会在息屏后掉线很多车机有“WLAN 休眠策略”要设置成“始终连接”。如果走 4G/5G 模组要确认 APN 配置正确、没有停机限速。4.2 frpc 客户端的配置与部署frpc 是单个可执行文件官方 Release 页面会区分linux_amd64、linux_arm64、windows_amd64等版本。车载中控屏的 CPU 架构常见的是 ARM 或者 ARM64选型时要注意adb shell getprop ro.product.cpu.abi比如输出是arm64-v8a就下载frp_x.x.x_linux_arm64.tar.gz。如果没有合适的现成版本也可以考虑交叉编译但一般官方 Release 已经覆盖全了。把 frpc 推送到车机上adb push frpc /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frpc这里有一个非常容易踩的坑Android 的/data/local/tmp分区在很多固件上是以 noexec 方式挂载的直接运行会报Permission denied。解决办法有几个把 frpc 放到/data/data/某个已有应用的包名/目录下应用私有目录通常允许执行或者放到/system/xbin/需要 system 分区可写车机工程机一般可以 remount如果是已经 root 的开发机直接把 frpc 放进/system/xbin/是最省心的。frpc 的 TOML 配置如下# /data/local/tmp/frpc.toml serverAddr VPS公网IP serverPort 7000 auth.method token auth.token 和frps.toml里一致 [[proxies]] name car-001-adb type tcp localIP 127.0.0.1 localPort 5555 remotePort 15555注意localIP这块有人会写成车机的 Wi-Fi IP其实没必要因为 frpc 就跑在车机本机上访问127.0.0.1就够了还能避免多网卡路由问题。启动/data/local/tmp/frpc -c /data/local/tmp/frpc.toml然后回到研发 PCadb connect VPS_IP:15555如果adb devices里出现device说明整条链路已经打通。4.3 守护进程与掉线自愈车机现场的运行环境和实验室完全不同。Wi-Fi 不稳定、4G 信号切换、系统休眠、用户熄屏任何一个因素都可能导致 frpc 断开或者 adbd 退出。所以车机侧的 frpc 不能是一次性命令必须有一个守护机制。我实测下来最简单有效的方式是写一个循环脚本#!/system/bin/sh while true; do /data/local/tmp/frpc -c /data/local/tmp/frpc.toml echo frpc exited, restart in 5 seconds sleep 5 done把它存成frpc_guard.sh丢到车机上用nohup后台启动。这样 frpc 因为断网、被杀进程等各种原因退出后5 秒内会自动重新拉起来。更讲究一点的做法是注册成 Android 系统服务或者用 init 脚本管理但那需要在固件层做定制适合量产预埋方案。对于研发阶段的临时调试上面的 shell 循环完全够用。另外还要注意 adbd 本身的稳定性。有时候车机和调试电脑之间 USB 没插好或者 adbd 崩溃TCP 5555 端口就没人监听了。此时 frpc 还活着但连上后adb devices可能一直显示offline。判断方法是adb shell echo ok看是否返回如果不通就需要去现场或者用带外方式比如车机的另一个管理通道重启 adbd。这也是我在实际项目里比较头疼的问题之一后面在稳定性章节里再细说。4.4 量产预埋还是售后现场临时部署这里有一个策略问题frpc 是预埋到量产固件里还是等车出了问题再现场部署预埋到量产固件优点是车真出问题时链路已经在不用等现场人员配合缺点是有安全风险——每一台车都有一个能通过 FRP 访问到 ADB 的入口如果 token 泄露或者 VPS 被攻破后果很严重。如果要这么做至少要做到每一台车独立的 token 和端口、ADB 授权白名单、远程调试开关按需开启。售后现场临时部署适合小批量问题车风险低但响应慢需要现场人员愿意配合做 USB 连接。我们的做法是先临时部署解决眼前问题同时推动固件团队把“远程调试代理”做成一款可独立安装、可停用的预置系统应用平时不启用只有售后申请后才下发凭证。这个路线比较稳妥也符合车规安全的要求。5. 连接成功之后研发这侧最常用的一套调试流程5.1 一键连接脚本与多设备端口规划当链路通了之后研发侧需要解决“多辆车同时在线”的管理问题。我们是这样规划的每一辆车分配一个独立的 remote_port形成一张简单的映射表。车辆编号remote_port负责人car-00115555张三car-00215556李四car-00315557王五然后给每个人配一个一键连接脚本#!/bin/bash # connect_car.sh 用法: ./connect_car.sh 15555 adb connect VPS_IP:$1 adb devices这样研发不用记 IP、不用记端口只需要知道车辆编号对应的端口。5.2 抓 logcat 与崩溃日志连上之后最频繁的操作就是抓日志。常用命令# 抓完整日志带线程时间信息 adb logcat -v threadtime car001_full.log # 单独抓崩溃缓冲区 adb logcat -b crash -v threadtime car001_crash.log # 抓 main system 缓冲区 adb logcat -b main -b system -v threadtime实测下来空闲状态下的 logcat 输出量大约 1-5KB/s走 5Mbps 的 VPS 完全没压力。但如果车机处于满日志输出状态比如在做视频编解码、导航语音播报持续抓几个小时后文件会很大。建议启动 logcat 时带上过滤器比如只看特定进程或者特定 tagadb logcat -v threadtime | grep -E system_server|AndroidRuntime|FATAL车机问题排查中ANR 也是个高频场景。/data/anr/目录下会有 traces 文件可以直接拉回来adb pull /data/anr/ car001_anr/5.3 截屏、录屏与界面状态采集远程调试时看到车机屏幕上的内容是刚需。截屏命令adb exec-out screencap -p screen.png注意用exec-out而不是shell screencap前者是二进制安全传输不会因为终端转义把 PNG 搞坏。1080p 分辨率的截屏 PNG 通常在 2-5MB 左右5Mbps 带宽下大约要 10 秒左右可以接受。需要记录连续操作过程时用录屏adb shell screenrecord /sdcard/record.mp4 --time-limit 30 adb pull /sdcard/record.mp4另外判断当前车机停在哪个界面上dumpsys window很好用adb shell dumpsys window | grep -E mCurrentFocus|mFocusedApp输出里能看到当前焦点窗口是哪个应用、哪个 Activity。遇到“界面卡住不动”“应用退到后台找不到”这类问题这一条命令基本能定位方向。5.4 远程执行命令与文件互传远程操作车机是复现问题路径的关键。输入事件注入# 模拟点击坐标 adb shell input tap 400 800 # 模拟滑动 adb shell input swipe 200 600 800 600 500 # 模拟按键 adb shell input keyevent KEYCODE_HOME adb shell input keyevent KEYCODE_BACK文件互传之间有时候需要临时推一个测试 APKadb install test.apk adb push config.xml /sdcard/ adb pull /data/data/com.example/databases/db.db ./如果现场车机已经启动了某个自动复现脚本配合adb shell am start、am force-stop这些命令就能远程完成一轮完整的复现-抓日志-分析循环。6. 这条链路的稳定性与安全性调优6.1 反复掉线、连上就断的排查实测中遇到最头疼的问题是“链路通了但用着用着就断了”。总结下来有以下几类原因车机 Wi-Fi 休眠。很多车机为了省电会在息屏或几分钟无操作后断开 Wi-Fifrpc 随之掉线。对策是在车机设置里找到 Wi-Fi 高级选项把“休眠时保持 Wi-Fi 连接”设为始终如果车机系统把这个选项藏起来了可能要改系统设置项wifi_sleep_policy。更重要的是在 frpc 守护脚本里加一层网络检测比如 ping 不通 VPS 就重新拉起 Wi-Fi。adbd 状态异常。TCP 模式下 adbd 偶尔会假死表现为 frpc 在线、adb connect能连上但任何命令都卡住。判断方法是用adb shell echo ok做个超时探测。遇到假死简单粗暴的方法是去现场重启但这不符合远程调试的初衷。后来我们在工程固件里加了一个系统服务定时检查 adbd 状态异常就自动重启 adbd。frpc 进程被杀。Android 系统在内存压力大时会杀后台进程。frpc 这种独立可执行文件不在应用管理框架内但可能被 LMK 或其他清理机制处理。守护脚本 每 5 秒重启能兜住大部分情况。6.2 ADB RSA 授权弹窗问题这是远程调试最容易卡住的地方。普通 USB 连接调试时电脑的 ADB 公钥会自动下发车机上弹窗问“是否允许 USB 调试”点一下允许就行。但远程链路里弹窗出现在车机上现场没人点。有两个解决办法预置研发机器的公钥到车机。把研发电脑上的~/.android/adbkey.pub内容追加到车机的/data/misc/adb/adb_keys文件里重启 adbd 后新连接就不需要弹窗确认。追加命令adb push adbkey.pub /data/local/tmp/ adb shell cat /data/local/tmp/adbkey.pub /data/misc/adb/adb_keys adb shell chown system:system /data/misc/adb/adb_keys adb shell pkill adbd # 或者系统服务重启 adbd设置ro.adb.secure0。这个属性关闭 ADB 认证任何能连到端口的人都能直接获得 root 权限的 ADB 访问。仅适合工程调试机量产固件千万别这么干。我们的经验是研发阶段的工程用车机可以预置好研发团队所有电脑的公钥量产售后场景用独立的调试开关。6.3 带宽、延迟对远程调试的影响公网 VPS 的带宽和延迟决定了远程调试的体验上限。延迟如果车机在西北VPS 在华东冬天开个adb shell命令可能等 1-2 秒才有返回用起来很煎熬。解决办法是尽量选离车机最近的云节点或者用一个简单的测速脚本评估多个节点再决定。带宽截屏、拉大文件时带宽不够会明显拖慢节奏。1080p 截屏 2-5MB5Mbps 带宽约 10 秒如果是项目高峰期几个人同时拉日志带宽会被抢光。VPS 带宽尽量选 10Mbps 以上成本不高但体验好很多。批量执行代替逐条交互延迟高的时候逐条敲命令很痛苦。建议把常见操作组合成 shell 脚本一条adb shell跑完减少往返次数。比如诊断信息采集adb shell logcat -d -v threadtime /sdcard/logcat_full.txt; dumpsys meminfo /sdcard/meminfo.txt; dumpsys window /sdcard/window.txt adb pull /sdcard/logcat_full.txt adb pull /sdcard/meminfo.txt adb pull /sdcard/window.txt6.4 访问控制与最小暴露原则最后聊安全。FRP 把 ADB 暴露到公网本质上是在攻击面上开了一个口子。一定要遵守最小暴露原则非默认端口frps 的bindPort和 ADB 的remotePort都别用默认值越不显眼越好。强 token每个车机用独立的 token万一某个现场设备丢了可以单独吊销不影响其它车。防火墙白名单在 VPS 安全组里把 ADB 映射端口15555 等限制为研发团队出口 IP 段frps 面板端口只对特定管理 IP 开放。及时关闭调试完成、问题闭环后关掉 frpc 进程必要时回收 VPS 上的映射端口。别让一台已经交付客户的车长期保持 ADB 公网可达状态。审计日志frps 自带连接日志定期检查有没有异常来源 IP 尝试连接。最后再分享一点经验这套链路从搭建到稳定运行前后迭代了好几轮。最初我们也想过要不要做一个更“高大上”的远程调试平台但后来发现 FRPADB 的组合已经解决了 90% 的问题。真正难的不是技术而是让每个环节都具备无人值守的稳定性——车机侧掉线能自愈研发侧有统一的端口规划现场人员不需要参与技术操作。如果你也在做车载中控屏的远程调试建议先从一台工程车跑通链路再逐步推广千万别一上来就在量产固件里预埋 frpc安全和运维的压力会大得多。
返回列表