崩溃监控、灰度发布与版本回滚
🚨 上线前要完善监控体系,上线后要有能力快速定位问题、逐步扩展和必要时回滚。
崩溃监控
常用 SDK 对比
| SDK | 特点 |
|---|---|
| Firebase Crashlytics | 免费、实时、Google 全平台 |
| Sentry | 开源、私有部署友好 |
| Bugly | 国内常用,聚合分析 |
集成 Crashlytics
// Application 中初始化
FirebaseCrashlytics.getInstance().apply {
setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)
setUserId(currentUser?.id ?: "anonymous")
}
// 手动记录非致命错误
try {
riskyOperation()
} catch (e: Exception) {
FirebaseCrashlytics.getInstance().recordException(e)
}
// 添加自定义上下文
FirebaseCrashlytics.getInstance().log("User clicked checkout")
FirebaseCrashlytics.getInstance().setCustomKey("cart_size", cartItems.size)
灰度发布
Google Play 分阶段发布
第一天:1% 用户
24h 无崩溃升场:5%
48h 后:25%
确认正常后:100%
功能开关灰度
class FeatureFlags {
private val remoteConfig = Firebase.remoteConfig
fun isNewCheckoutEnabled(): Boolean =
remoteConfig.getBoolean("enable_new_checkout")
suspend fun fetchAndActivate() {
remoteConfig.fetchAndActivate().await()
}
}
// 使用
if (featureFlags.isNewCheckoutEnabled()) {
showNewCheckout()
} else {
showOldCheckout()
}
版本回滚策略
应用层回滚(功能开关)
// 最快回滚:关闭功能开关,无需发布新版本
FeatureFlags.setOverride("enable_new_checkout", false)
强制更新与提示更新
val appUpdateManager = AppUpdateManagerFactory.create(context)
val appUpdateInfo = appUpdateManager.appUpdateInfo.await()
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
if (isCritical) {
// 强制更新:用户必须更新才能继续使用
appUpdateManager.startUpdateFlow(
appUpdateInfo, this,
AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()
)
} else {
// 柔性更新:弹窗提示
appUpdateManager.startUpdateFlow(
appUpdateInfo, this,
AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build()
)
}
}
上线后监控指标
| 指标 | 监控工具 | 预警阈值 |
|---|---|---|
| 崩溃率 | Crashlytics / Sentry | > 0.1% 立即回滚 |
| ANR 率 | Google Play Console | > 0.05% 警示 |
| 启动时间 | 自定义埋点 | > 5s 需优化 |
| 内存占用 | Firebase Perf | > 基线 20% 警示 |
常见误区
- 崩溃堆栈没有符号表,无法定位原始代码位置
- 灰度发布没有设置公共回滚计划,发现问题时间很长
- 发布版本后没有实时监控关键指标,依赖用户对问题反馈