Android Developer

数据上报机制

特点

  • 及时,近乎实时上报
  • 批量上报,同时规避大数量单次上报
  • 很好的解决埋点数据大量密集涌入的情况
  • 耗时操作剥离主线程,不影响用户的正常操作
  • 处理线程异常,增强应用稳定性
  • 利用RxJava和OKHttp已有线程池,不显式增加新线程
  • 重试机制支持,增加重试时机,保证之前失败数据达到数据平台

实时上报机制

先举一个例子

  • 将埋点数据比作乘客
  • 将数据平台比作目的地
  • 而App的上报请求就是客车
  • App则是负责发车的调度这

当调度者(App) 发现有一个乘客(埋点数据)时,就安排这个乘客上车,然后开始计时

  • a.如果超过5分钟(举例需要),没有新的乘客乘车,就立即发车,被送达到目的地
  • b.如果5分钟内,有新的乘客过来,就重新计时,按照a,b情况去匹配操作
  • c.特殊情况,如果发车时,乘客过多,调度者会安排多辆客车立即发车(不再走a,b情况处理)。

调度者通过反复上面的操作,就会将乘客源源不断地送达到目的地

分批切块逻辑

  • 为了规避大量数量(洪水般)数据单次上报带来的问题,我们队数据进行分批切块处理
  • 分批切块处理后的每块的数据顺序保持原数据的顺序,比如[1,2,3,4,5,6,7,8,9,10] 以3为一块的容量,可以分为[1,2,3], [4,5,6], [7,8,9], [10]

失败处理

  • 无网络时收集的请求会写入文件
  • 请求失败的数据会写入文件
  • 网络请求恢复用户进入前台应用启动时会上报失败的数据
  • 具体实现的数据持久化处理,可以参考AsyncDataPersister

线程策略

  • 关于执行线程并没有严格的限制
  • 考虑到App的稳定性,我们结合RxJava的相关处理机制,将字符串与实例对象转换等,放在了工作者线程。
  • 但是写入失败数据和读取失败数据,由于是IO耗时,我们也放在了工作者线程。
  • 网络请求,我们利用了OKHttp的自有线程,并没有进行外部线程控制

不足与问题

  • 极端情况下,可能会造成某些数据丢失(之前的实现方式也有问题)
  • 分批切块的阈值缺少实践验证是否为最佳数值
  • 实时上报检测时间阈值可能并非最佳

调试日志

adb logcat |grep --color=always -E "BufferedUsageEventUploader|UsageEventUploadManger|SecooDataUploader|AsyncDataPersister"