精选文章

29. 稳定性治理

2021-01-15 · 稳定性

29. 稳定性治理

稳定性治理的目标是“可追溯、可定位、可恢复”。核心要素:崩溃采集、日志埋点、异常防护、灰度回滚。

一、崩溃类型与常见来源

  • 访问越界(数组下标错误)
  • 强解包失败
  • UI 在子线程更新
  • 循环引用导致内存异常
  • 解析异常或空数据导致崩溃

二、崩溃捕获基础

1. Uncaught Exception

func handleException(_ exception: NSException) {
    print("Exception: \(exception.name) \(exception.reason ?? "")")
}

NSSetUncaughtExceptionHandler { exception in
    handleException(exception)
}

2. Signal 捕获

import Foundation

func handleSignal(_ signal: Int32) {
    print("Signal: \(signal)")
}

signal(SIGABRT) { _ in handleSignal(SIGABRT) }
signal(SIGSEGV) { _ in handleSignal(SIGSEGV) }
signal(SIGBUS)  { _ in handleSignal(SIGBUS)  }

说明:以上只用于收集信息,真正的线上需要结合崩溃上报服务与符号化。

三、符号化流程

  • 构建时保存 dSYM
  • 崩溃日志使用 dSYM 符号化
  • 线上崩溃必须确保 build 与 dSYM 对应

四、日志与埋点

1. 基础日志封装

enum LogLevel: String { case info, warn, error }

struct Logger {
    static func log(_ level: LogLevel, _ message: String) {
        print("[\(level.rawValue)] \(message)")
    }
}

2. 关键流程打点

struct Trace {
    static func event(_ name: String, params: [String: String]) {
        print("event=\(name) params=\(params)")
    }
}

五、常见防护策略

1. 数组越界保护

extension Array {
    subscript(safe index: Int) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

2. 主线程检查

func assertMainThread() {
    assert(Thread.isMainThread)
}

3. Optional 兜底

let title = response.title ?? ""

六、崩溃回溯与定位

  • 崩溃点附近的用户操作
  • 设备型号与系统版本
  • 网络状态与请求链路

将这些维度打进日志,可以大幅缩短排查时间。

七、灰度与回滚

  • 新功能先小流量灰度
  • 线上异常迅速关闭开关
  • 保留回滚版本,避免全量崩溃

稳定性是工程能力,不是单次修复。持续监控与可回滚策略是关键。

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

上一篇 下一篇