绝大多数移动应用程序都依赖于发出网络请求来提供成功的用户体验。然而,许多工程团队没有客户端网络监控。相反,他们完全依赖后端监控来了解整个系统中发生网络故障的位置。
这让您无法全面、甚至可能错误地了解移动用户的体验。请继续阅读,了解客户端网络监控为何如此重要,以及如果您仅从后端角度了解网络性能,您会错过什么。
并非所有请求都会到达您的后端服务器
您的后端只能测量实际到达服务器的网络请求的行为。以下是请求无法到达的几个原因。
没有网络连接
在某些情况下,移动用户可能并不清楚自己没有连接。例如,用户可以连接到 WiFi 接入点,但来自接入点的上行连接已断开或连接不稳定。
连接中断
即使您最初成功连接到后端服务器,也无法保证请求会成功完成。这种情况在移动应用中比在 PC 上发出的查询中更常见,因为移动连接质量更具动态性,容易出现中断或降级。虽然后端监控可能会捕捉到这种行为,但这不是您通常会优先考虑的问题。即使您这样做了,丢失连接的服务器也不会知道导致中断的原因。在客户端,您可以查看是否发生了什么事情,例如从 WiFI 切换到 WAN 失败,以及大约在同一时间建立的其他网络连接是否也失败。
DNS 解析失败
如果应用无法解析主机名,它将无法连接到您的后端服务器。此外,ISP 可能会忽略DNS条目的缓存规则,并将数据缓存数天甚至数周,这种情况并不常见。当您更改 DNS 设置时,您希望 DNS 条目的下游消费者遵守您设置的生存时间 (TTL),但没有什么可以阻止他们忽略 TTL。这意味着运行您的移动应用的设备会将主机名解析为可能不再使用的 IP 地址。
DNS 配置错误后,请求失败并出现 UnknownHostException。
并非所有请求都被后端服务器接受
即使您的应用程序可以连接到后端服务器,服务器也可能由于各种原因拒绝连接。
SSL 握手失败
这对于根证书已过期且没有可行后备方案的旧版 Android 设备尤其常见。另一种常见的失败情况是,用户将其设备上的时钟设置得太远,以至于您的 SSL 证书不再有效(在游戏中,必须在一定延迟后获得这些额外生命!)。也许您服务器上的数据收集可以对此提供一些可见性,但是这些数据通常很难从常用的代理服务器(如NGINX )中捕获。即使您可以检测到它,由于无法建立安全连接,您也不会有太多关于它发生在谁身上的信息。
这种错误在广告相关域名中经常发生。我们最近分析的一天发现,七家大型广告公司超过 1% 的域名网络请求出现 SSL 故障,这些请求分布在数百个应用程序中。
服务器因请求量过大而无法承受
通常,当后端出现问题并且您想了解对用户的影响时,您无法获得完整的信息。这是因为超载的服务器也是应该收集诊断信息的服务器。
并非所有请求都是针对您的后端服务器
使用后端可观察性工具,您可以在一定程度上了解发送到服务器的网络请求,但无法了解发送到第三方服务的请求。移动应用程序的许多重要部分都需要访问您无法直接控制的网络服务,例如:
-
支付提供商。
-
广告提供商。
-
地图服务。
-
内容分发网络 (CDN)。
-
基础设施即服务 (IaaS) 提供商。
-
单点登录 (SSO) 提供商。
您必须从客户端监控网络行为,以深入了解提供这些服务的 SDK 的运行情况。这些服务使用的域的错误率(无论是连接错误还是 HTTP 错误)通常高于第一方域。在某些情况下,由于配置错误在测试期间不易检测到,错误率达到或接近 100%。
如果没有客户端监控,您也无法了解请求的延迟及其所消耗的带宽。即使您投入时间和金钱来减少网络请求延迟,如果服务供应商没有进行同样的投资,您的应用程序的性能很可能会下降。
从后端角度来看并非所有指标都可用
后端可观察性工具只能测量它们所接触到的内容。它们无法报告的内容包括:
DNS 查找时间
DNS 解析针对您无法控制的服务器进行。它可能是 ISP 的 DNS 服务器,也可能是常用的全球 DNS 服务,如 Cloudflare 或Google。无论如何,您无法收集有关 DNS 解析延迟的数据,除非在您的移动应用程序中。
连接建立和响应传输
通常,Web 服务器会将响应时间记录为从套接字读取第一个字节到将最后一个字节写入套接字之间的时间。这不包括以下内容:
-
TCP 或 TLS 握手所花费的时间。
-
Web 服务器线程能够读取请求的第一个字节之前的时间。
-
操作系统的延迟导致响应数据传送到网络上。
服务器和移动应用之间的网络状况将影响实现握手和发送响应所需的总时间。如果连接不佳且带宽有限,则服务器记录的响应时间可能会过于乐观。Web 服务器会将其响应写入套接字,内核会缓冲该数据。因此,Web 服务器可以在响应完全离开机器之前声明它已完成响应。
Web 服务器完成向套接字传输响应和通过网络发送响应之间的时间差通常很小。但如果移动网络连接较差,这种差异可能会显著增加请求的总时间。只有从客户端的角度才能衡量用户体验到的真实响应时间。
请求排队时间
代码发起网络请求的时间并不一定等于底层库和操作系统 (OS) 向远程服务器发起请求的时间。例如,在 iOS 上,常用的 NSURLSession 类通过设置httpMaximumConnectionsPerHost来控制向主机发出的并发请求数;默认情况下,这会将使用 NSURLSession 实例的应用限制为 6 个并发请求。因此,如果您向单个主机发出 10 个请求,则后 4 个请求将不会启动,直到前 6 个请求中的一些请求完成为止。从被访问的后端服务器的角度来看,请求时间不包括请求在客户端排队的时间。同样,Android 上常用的 OkHttp 库也有setMaxRequestsPerHost来实现类似的行为,默认设置为 5。
完全完成网络请求的主要延迟可能不是服务器上的响应时间,并且最终用户的移动应用体验将受到上述因素导致的延迟的影响。
并非所有请求响应都会到达您的移动应用程序
您的服务器可以有效地处理请求,但用户仍然会感到不愉快。
代理可以阻止或改变移动应用程序接收的响应,就像后端服务器希望的那样。代理通常用于在您连接到公共 WiFi 时限制对互联网的访问。它们还包括根据您访问服务的 IP 地址限制访问的安全工具。
我们曾经遇到过这样的情况:他们的服务器发送的请求带有 200(OK)HTTP 状态代码,而他们的应用程序却出现了 429(请求过多)状态代码,并且 HTML 负载应该是JSON。在其中一个案例中,用于访问服务的 IP 被保护后端 API 的安全服务标记。因此,安全服务进行了干预,并用错误消息替换了响应。但是,安全服务默认返回 HTML 负载,就好像请求来自可以向用户显示此信息的浏览器一样。应用程序无法处理此问题,因为它需要 JSON 响应。
并非所有响应都可以由您的移动应用程序处理
如果您的后端 API 服务于多种客户端类型(网站、移动网络和移动应用),则有效负载很容易因某些移动设备的有限资源而配置错误。例如,某些大型有效负载可能会导致低端设备上的反序列化失败,导致应用内存耗尽并崩溃。当您向通常返回少量对象的响应的端点发出请求时,这种情况很容易发生,但对于某些查询参数将返回数千个对象。
另一种失败情况是,所传递数据的结构与移动应用程序的预期不一致。也许某些字段缺失,或者存在应用程序不知道的其他字段,这会导致应用程序在尝试解析响应负载时崩溃。这种失败类型的更微妙的变化是,当为给定字段传递了意外值时,例如,预期为秒的时间戳为毫秒,或者预期填充的值为空。这些可能不会导致解析期间立即崩溃,但最终使用它们填充的模型时可能会发生崩溃。
从后端的角度来看,只要数据已发送,所有这些网络请求响应都被视为成功。然而,重要的是数据在客户端得到正确解析,并且值的范围符合应用程序内置的期望。
并非所有请求都是孤立的
虽然您可以水平扩展后端服务并在各种地理位置部署实例,但您的移动应用程序在单个设备上运行,并且您无法控制网络连接。此网络管道由设备上的所有应用程序共享,您几乎无法控制此管道的质量。
理论上,您可以控制应用程序代码发出的并发请求数,但随着应用程序复杂性的增加,控制难度会越来越大。在许多情况下,网络管道没有足够的容量来支持所有并发请求所需的总带宽。
这意味着您的请求的持续时间并不相互独立。虽然理论上可以在后端监控中考虑这方面的某些方面,但历史上并没有这样做。可能受到其他并发请求影响的请求将看起来像是异常值,没有任何上下文来解释它们为什么是异常值。
您的移动应用程序发出的请求并非都是必要的
同样,随着移动应用程序的复杂性增加,人们开始转向模块化应用程序,这些应用程序通常由 10 多个独立开发的模块组成。在这些情况下,最大的挑战是避免重复网络请求。
重复网络请求
虽然从流程角度来看,独立开发应用程序的组件可能有意义,但它会使不同模块之间的协调和测试更具挑战性。您是否有一个负责所有网络访问的中央模块?还是允许模块自行发出请求?如果您有一个集中式网络访问模块,当多个模块大致同时请求相同信息时,它是否会进行协调?如果是这样,您如何确定已经请求的数据是否足够新?
这些问题很难回答,如果您在客户端中积极缓存数据,则更难全面测试这些场景。团队经常选择更安全、更简单的方法,即在每个模块中独立发出请求,这在许多情况下可能是正确的决定。但是,您应该(至少)了解应用程序在短时间内重复请求相同数据的频率。我们发现应用程序在几秒钟内向同一端点发出 10 次相同的 GET 请求。这可能没有必要,并且会损害最终用户体验、占用过多带宽并增加后端服务器的负载。
未使用和过时的第三方 SDK
在您的移动应用中,很容易意外地遗留不再使用、损坏或配置错误的第三方 SDK。例如,您的营销团队可能会免费试用新的分析 SDK,但当他们决定不再继续使用时,没有人告诉开发人员将其删除。这会导致无休止的不必要且可能失败的网络请求,从而延长启动时间并损害应用性能。这些减速可能不会导致崩溃或引发错误,并且您的后端监控将完全看不到它们。
如何了解客户端网络性能
通过监控客户端网络性能,您可以释放很多价值。也许您的应用程序没有严重的 DNS 查找问题(基于大多数用户所在的位置),或者您不太依赖第三方网络调用,但如果至少有一两种情况不适用于您的应用程序,我会感到有点惊讶。
要了解您错过了什么,请考虑将Embrace SDK添加到您的移动应用程序中。除了将数据发送到我们的托管服务之外,您还可以尝试使用带有OTel 导出器的 SDK ,它允许您在您选择的与 OTel 兼容的可观察性工具中收集移动遥测数据。