14年客户端工程师创业踩坑:冷启动与基建实战复盘
|
V2EX 老哥们儿别点右上角,真不是来吹 MVP 的——上个月我删了三台闲置 Mac mini,顺手清空了 /var/log/tap/ 下所有带 “tunnel_v3” 的日志,清完才发现那其实是去年冷启动时写的代理层兜底脚本,早没用了,但没删,就那么挂着。这事儿本身不重要,重要的是,它和我们最初那套「全链路可观测」基建一样,挂着,不报错,不报警,也不做事。 我原以为监控覆盖了,结果灰度放量那天凌晨两点十七分,用户卡在 splash 页不动,而我们告警群 99+,全是 CI 流水线失败的红标——没人看,也没人配 mute 规则,就那么堆着。老张边啃食堂剩饭边切 SSH 进去查,发现是 DNSPod 解析超时,但我们埋的 DNS 采样点只在 App 启动时打一次,之后全靠系统缓存。他敲完 nslookup 的时候,手机响了,是运维小陈打来的,说 UPS 的嗡鸣声比平时高半度,机房空调刚换过压缩机,冷风还是那股子铁锈混臭氧味儿,低频噪音震得工位键盘托板微微发颤。 冷启动?不就是从零拉起一套能跑 demo 的东西么。半年前我连域名备案都没填完,先让实习生用 Flutter 写了个「加载中…」页面,挂到腾讯云 COS 上,加了 Cloudflare 免费版 CDN,CNAME 指过去那天下午三点十一分,我自己用三台不同运营商的真机测了一遍——都进了。我说成了。第二天上午九点,产品总监拉着运营、法务、市场,在会议室盯着大屏等转化数据,屏幕黑着,因为那个页面压根没接埋点 SDK。不是漏配,是根本没加。我打包时忘了 `--no-sound-null-safety` 的 flag,Flutter 2.10 在部分低端 Android 机上直接闪退,静默崩溃。这个我敢打包票:小米 Redmi Note 8 Pro,MIUI 12.5,debug 模式下白屏三秒后返回桌面,logcat 里只有一行 `D/FlutterActivityAndFragmentDelegate: Setting up for FlutterActivity`,再无后续。 基建不是搭积木。是拆雷。我们第一个上线的 feature 是「扫码登录」,背后硬塞进六个模块:动态权限、本地证书校验、WebRTC 信令桥、离线二维码缓存策略、iOS 的 ASAuthorizationController 补丁、Android 的 CameraX 预览裁剪回调重试。但你猜怎么着?第一个线上 bug 是「扫完码,弹出 SafariViewController 后立即黑屏」——只在 iOS 16.4 上出现,只在 A12 芯片以下设备复现。排查三天,结论是系统底层视频预览流和 WebView 渲染线程抢 GPU fence 信号。解决?禁掉预览,改用纯静态图片 + OCR。不是技术方案,是投降协议。我们当时把整个扫码模块封装成一个 CocoaPod,podspec 里写着 `s.dependency 'YYCache', '~> 1.0.4'`,但实际项目里 YYCache 根本没调用过——只是怕以后要用,先锁个版本占个位。这种「伪依赖」,后来在 gradle dependencies 里也抄了一份,名字改成 yycache-wrapper,连 git commit 都没提交过。 对讲机在我抽屉里躺了四个月。不是买来应急的,是上上家公司遗留的——他们用它喊机房巡检。我把它当镇纸压着一摞废弃的 SLO 设计图,其中一页写着「客户端 MTTR ≤ 十八秒」,下面画了道横线,横线后面潦草补了句:「前提:错误可被自动定位」。可我们连 crash 分类都是人工打标签的,因为 sentry 的 grouping logic 和我们的 stack trace 正则对不上。上周五我帮测试同学复现一个 oom,她录屏里显示内存曲线一路冲到 1.2G,而后台监控图上平得像尺子量过。我没说话,转身去茶水间泡咖啡,听见隔壁组在吵 Kotlin Coroutines 的 scope 生命周期问题,声音大得盖过了机房那边传来的 UPS 嗡鸣。 优胜劣汰站得住?站得住。不是因为谁技术强,是那些没在冷启动期把 build.gradle 里的 maven { url ‘xxx’ } 写死成内网地址的人,三天后就被推着改 CI 权限;是那些觉得“先用友盟撑三个月”的人,最后自己写了七版热更 patch,每版都要重走一遍苹果审核;是那些以为“灰度 1% 就是安全”的人,在第四天凌晨被运营电话叫醒,说“下载量爆了,但留存是负的”,我抓起电脑打开 console,发现 release 包里还留着 debug 级别的 OkHttp 日志开关——日志里明晃晃打印着 staging 的 auth token。这个我说不准,是不是真有人故意留着,还是 build cache 污染没清干净。 现在我在改 CI Pipeline。把 lint 阶段拆成 pre-commit 和 post-merge 两套,前者跑 fast-check,后者跑 full-check。中间加了一步:check-prod-secrets。不是扫描文件内容,是检查 git ls-files 输出里有没有匹配到 `prod.key|secret.token|apple_dev_account` 的路径。如果匹配上,Pipeline 直接 exit 1,并附一条 stderr:「检测到疑似生产密钥路径,请确认是否为误报(如 mock 文件名撞词),若非误报,请重命名并更新 .gitignore」。这事儿不智能,但管用。至少比去年我们靠人工翻 PR diff 强。老张昨天晚上九点还在改这个脚本,边改边念叨:“要是当时知道 Jenkinsfile 可以用 Kotlin DSL 写……算了,反正现在也没人会修。”
文章配图,仅供参考 对讲机还在抽屉里。我没扔。下次冷启动,也许会用上。也许不会。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


冷启动≠烧钱:用第一性原理重构科技增长链
数据驱动增长:客户端工程师的传媒网站优化实战
开源站长11年实战:素人冷启动30天破10万


