有赞移动性能监控平台(一)
前言
随着移动端业务复杂度的提升,开发同学在编写业务的时候往往容易忽略性能问题,虽然有赞移动端自研了 APM ,但是 APM 采集的都是线上的数据,无法在 QA 与开发阶段提前发现问题,为了保障软件的稳定性,需要补齐线下监控能力,避免性能问题上线对商家经营过程造成影响。
一、架构设计
整体基于 APM 现有框架迭代线下监控能力,并在端上开发 AWACS 可视化工具,通过全局悬浮窗,并结合提醒能力(弹窗与 Toast 提示)实时通知测试人员进行问题查看,同时后台也会定时分析测试环境采集的性能数据,进行管理与分配。
QA 同学基于 Appium 补齐了 UI 主流程 case ,通过自动化测试最大程度确保每次应用发版的稳定。而设备自动化回归流程可以与线下监控完美的结合起来,首先每个版本可以确保运行在同一款设备上,其次每个版本运行的主流程用例基本上保持一致,这样就为应用“前后”版本性能数据分析对比提供了两个参照条件。性能问题上报后,除了微信Robot通知相关干系人解决问题外,还基于移动端 mPaaS 搭建了问题管理与分配平台,便于跟进与追踪。

二、监控指标分析
2.1 阶段数据
2.1.1 方法耗时分析
原理

分析详情

2.1.2 网络状况分析
原理
public Response intercept(Chain chain) throws IOException {Request request = chain.request();Response response = null;String url = getRequestUrl(request.url());if (!TextUtils.isEmpty(url)) {AppSegmentCache.INSTANCE.setRequestStart(url);long startNs = System.nanoTime();try {response = chain.proceed(request);} catch (Exception e) {throw e;}long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);AppSegmentCache.INSTANCE.setRequestEnd(url, tookMs);}return chain.proceed(request);}
分析详情

2.2 流量
2.2.1 原理
OkHttpHook
internal object OkHttpHook {public val globalNetworkInterceptor = Interceptor { chain ->... ...// 计算repsonse length(流量大小)// 读取response content(如果是gzip需要解压)// 流量内容写入文件中val fileUrl = File(file, URLEncoder.encode(SimpleDateFormat("yyyy-MM-dd-HH:mm:ss-SSS").format(Date()) + "-" + netPackInfo.url))fileUrl.writeText(netPackInfo.toString())... ...}
HttpUrlConnectHook
public object HttpUrlConnectHook {fun proxy(httpUrlConnection: URLConnection): URLConnection {try {return hookOkHttpURLConnection(httpUrlConnection)} catch (e: Exception) {e.printStackTrace()}return urlConnection}}private fun hookOkHttpURLConnection(httpUrlConnection: URLConnection): URLConnection {val builder = OkHttpClient.Builder()val mClient = builder.retryOnConnectionFailure(true)... ....build()val strUrl = httpUrlConnection.url.toString()val url = URL(strUrl)val protocol = url.protocol.toLowerCase(Locale.ROOT)if (protocol.startWith("http", ignoreCase = true)) {return HttpUrlFactory.OkHttpURLConnection(url, mClient)} else urlConnection}
2.2.2 分析详情

2.3 页面耗时
2.3.1 原理
页面监控开始时机
public void watchActivity(Activity activity) {watchWithMonitorView(activity.getClass().getName(), activity.getWindow().getDecorView());... ...if (activity instanceof android.support.v4.app.FragmentActivity) {((FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(new FragmentLifecycleCallbacks() {public void onFragmentViewCreated(android.support.v4.app.FragmentManager fm, final android.support.v4.app.Fragment f, View v,Bundle savedInstanceState) {watchWithMonitorView(f.getClass().getName(), v);}}), true);}... ...}
页面监控结束时机
public void watchWithMonitorView(final String className, final View view) {final long startTime = System.currentTimeMillis();final WeakReferenceviewWeakReference = new WeakReference<>(view); final ViewTreeObserver.OnDrawListener onDrawListener = new ViewTreeObserver.OnDrawListener() {Boolean first = true;public void onDraw() {if (startTime != 0 && first && viewWeakReference.get() != null) {... ...}};view.getViewTreeObserver().addOnDrawListener(onDrawListener);}
2.3.2 分析详情

三、后台问题分析
分析工作流程(阶段数据分析举例):

四、线下AWACS工具

五、问题管理与分配平台
5.1 问题列表

5.2 问题详情


六、未来规划
评论
