现在那个网站做推广效果会好点,山东省住房和建设厅注册中心网站,食品网站模板,营销活动策划方案背景
移动互联网时代#xff0c;移动端极大部分业务都需要通过App和Server之间的数据交互来实现#xff0c;所以大部分App提供的业务功能都需要使用网络请求。如果因为网络请求慢或者请求失败#xff0c;导致用户无法顺畅的使用业务功能#xff0c;会对用户体验造成极大影…背景
移动互联网时代移动端极大部分业务都需要通过App和Server之间的数据交互来实现所以大部分App提供的业务功能都需要使用网络请求。如果因为网络请求慢或者请求失败导致用户无法顺畅的使用业务功能会对用户体验造成极大影响。
此外EMAS对外提供的APM之前并不包括网络监控功能而网络性能监控作为移动端性能监控的重要组成部分我们急需补全这部分能力来完善APM的产品功能进一步满足客户的需求。 “阿里巴巴应用研发平台 EMAS 是国内领先的云原生应用研发平台移动App、H5应用、小程序、Web应用等基于广泛的云原生技术Backend as a Service、Serverless、DevOps、低代码等致力于为企业、开发者提供一站式的应用研发管理服务涵盖开发、测试、运维、运营等应用全生命周期。” 问题与挑战
网络性能监控在端上主要包括数据采集和数据上报。我们希望能尽可能采集有用的信息来帮助客户发现、定位和解决网络性能问题。我们面临如下问题和挑战
•首先要解决的是网络请求过程中哪些阶段会影响请求性能如果发现网络性能有问题需要采集哪些数据来帮助用户去定位和解决问题。
• android上主流的网络框架有okhttp2、okhttp3、okhttp4、volley、retrofit、httpclient和系统提供的httpurlconnection等在我们不确定客户使用哪个网络库的哪个版本的情况下如何尽量采集有用的信息。
• 网络请求各个阶段的数据采集都是离散的如何保证单个请求各个离散的监控数据能够串联起来不和其他请求的监控数据混在一起。
• 由于弱网环境下的网络请求日志往往更有价值需要尽可能将异常的网络请求日志数据上报到服务端。
• 并发网络请求时需要确保在日志上传时尽量不影响客户正常业务。
实现方案
网络性能监控在端上的具体实现主要包含两大模块 • 数据采集 • 数据上报 其中数据采集是整个SDK框架的核心。
整体架构概览 接入层 网络监控属于高可用产品的一部分采用高可用统一接入的方式接入。插件层 高可用目前框架是通过插件式的方式集成各个业务实现networkmonitor plugin集成到APM中补充APM中网络监控部分。逻辑层 主要负责采集控制、数据管理、缓存管理和数据上报。拦截器层 整个网络监控的核心。为了采集更多的信息我们选择使用字节码注入技术来实现网络请求监控功能。对OkHttp、HttpClient和HttpUrlConnection分别实现Interceptor去采集不同网络库中网络请求各个阶段的数据并在请求结束时完成采集进行上报。此外通过自定义gradle plugin的方式为各个网络库实现Injector和开关控制在应用构建阶段将Interceptor中各个采集的方法注入到对应网络库字节码的埋点位置从而实现在运行时网络请求各个阶段采集需要的数据。
数据采集
采集哪些数据
首先需要确定采集的数据范围来帮助我们及时发现网络请求的性能和异常等情况另一方面也需要有额外的数据来辅助排查问题。所以我们采集的数据主要包括四个部分 • 基础数据。 • 性能数据。 • 异常信息。 • 事件序列数据。
基础数据 • 请求url对请求做聚合运算。 • 目标IP地址对于多出口IP的客户支持IP地址维度的数据分析。 • dns解析结果请求url的域名解析ip列表用于分析是否存在域名劫持的问题。 • http code根据http code确定请求状态。 • 上行流量包括整个请求上行header和body的总的流量包含重试和重定向的上行流量。用于监控上行流量开销。 • 下行流量包括整个请求下行header和body的总的流量包含重试和重定向的下行流量。用于监控下行流量开销。 • 网络库类型及版本对于客户更换网络库或者升级网络库版本的情况可以提供前后的网络数据的差异。
性能数据
性能数据主要是采集整个网络请求中各个阶段的耗时情况来定位慢请求发生的阶段。下图列举了http请求可能出现的各个阶段。 所以性能数据部分需要采集下述各个阶段的耗时数据
•整个网络请求耗时 •dns耗时 •建连耗时 •TLS建连耗时 •数据上行耗时 •header上行耗时 •body上行耗时 •数据下行耗时 •header下行耗时 •body下行耗时
异常信息
异常信息主要是收集网络请求各阶段出现异常时的异常栈的信息。比如常见的java.net.UnknownHostException、java.net.SocketTimeoutException等。
事件序列数据
事件序列数据主要是收集网络请求各阶段的监控事件的信息另外对于特定网络库的一些特殊的事件的监控比如okhttp的连接复用、自动重定向和失败重试等对网络耗时有影响的机制。最后将这些事件按时间顺序排列。
比如在okhttp上dns被劫持的场景我们通过基础数据中的目标IP地址去判断dns劫持情况这个目标IP地址是在建立连接的时候去采集的。如果第一个请求发生了dns劫持的情况那这个请求我们能正常识别的dns劫持已经发生。如果后续的网络请求复用了这个连接因为不会再去建立连接所以基础数据中没有目标IP地址这时候就需要使用事件序列数据中的连接复用事件中的连接的url和目标IP地址来判断是不是被劫持的请求。
如何采集数据
字节码插桩原理
字节码插桩涉及到Android的打包构建流程。首先我们看下Android应用程序的打包流程如下图 从上图可知我们只需要在 javac 之后 dex 之前遍历所有的字节码文件并按照一定的规则过滤修改就可以实现字节码的插桩。
从Android Gradle 1.5.0 开始Google官方提供了Transform API。通过Transform API允许第三方以插件的形式在Android应用程序打包成dex文件之前的编译过程中操作.class文件。 Android编译器中的TaskManager将每个Transform串起来第一个Transform接收来自javac编译的结果以及已经拉取到本地的第三方sdkjar、aar还有resource资源。这些编译的中间产物在Transform组成的链条上流动每个Transform节点可以对class进行处理再传递给下一个Transform。常见的混淆、Desugar等的实现就是封装在一个个Transform中。而自定义的Tranform会插入到这个Transform链条的最前面所以开启混淆的情况下通过自定义Transform对字节码进行修改也是先修改字节码再混淆。
网络库调研
除了系统自带的网络库HttpUrlConnection在android平台还有很多优秀的第三方网络库大部分App开发会使用第三方的网络库来发起网络请求。 从上表中主流网络库的底层实现来看我们只要支持OkHttp、HttpUrlConnection和HttpClinet的数据采集就能满足主流网络库的性能监控需求。 我们对应用市场上Top1000的App进行了分析按集成数量排序依次是okhttp3okhttp4、volleyHttpUrlConnection、okhttp2和httpclient。其中okhttp网络库占比将近80%所以我们优先实现了okhttp网络库的监控实现。
okhttp网络库的监控实现
okhttp网络库家族主要包括okhttp2、okhttp3和okhttp4。其中okhttp3版本分布众多底层实现变化也最多而okhttp2的底层实现和okhttp3的早期版本相近okhttp4是okhttp3的kotlin版本的实现。所以我们主要介绍下okhttp3上的监控实现。 上图是okhttp3.12.0版本的实现框架我们在网络库的具体逻辑里注入代码来采集需要的数据。
okhttp3版本众多从3.0.0-3.14.9已经有超过40个版本对于每一个代码注入的位置都需要确保再各个版本上能正常工作。所以实现okhttp3的无痕埋点版本适配需要耗费大量的工作。
数据上报
数据上报除了需要考虑加密、鉴权、压缩等方面还需要能确保尽可能少的丢失日志同时还需要控制资源的占用来降低对上层业务的影响。具体实现主要包括两方面
• 缓存支持内存缓存和磁盘缓存两级缓存。需要实现业务隔离多个业务使用缓存功能时可以做到互不影响。 • 上报由于APM产生的日志较多为了控制并发数和内存我们使用了一个业务共享的线程池和调度队列。调度队列最多缓存10条批量日志如果超出10条会立即将日志放入磁盘缓存。另外在上报前提供了日志预处理的开放接口方便业务层对日志做处理比如抽样、聚合等功能。
后续计划
EMAS网络性能监控已经对外开放产品详情https://www.aliyun.com/product/emascrash/apm 后续我们会根据客户实际需求去逐步完善功能。下一步计划实现的需求包括 • 支持HttpUrlConnection、HttpClient等网络库。 • 支持body数据的采集上报让客户可以感知、定位和解决在网络连通性正常但服务端下发异常数据导致端上业务出现异常的问题。 • 支持日志数据端上预聚合降低服务端存储压力。 • 支持socket请求的监控。
欢迎大家积极留言提出你们的宝贵意见和建议非常感谢钉钉搜索35248489加入阿里云云原生应用研发平台EMAS技术交流群探讨最新最热门的应用研发技术和实践。 原文链接 本文为阿里云原创内容未经允许不得转载。