如果您的API监控在一个数据中心的服务器上运行,您只能看到部分情况。来自巴西的用户可能会收到500错误,而您在莫斯科的仪表板显示绿色状态“一切正常”。我们将分析哪些5个可用性指标无法在没有通过其他国家的真实外部IP请求的情况下测量,以及如何在没有复杂基础设施的情况下做到这一点。
为什么本地监控会误导
大多数团队通过UptimeRobot、Pingdom或自己的cron脚本设置API监控,该脚本每分钟向端点发送一次请求。问题在于,这些请求几乎总是来自一两个地区——通常是美国或欧洲,监控服务的服务器位于这些地方。如果您的受众在印度、巴西或东南亚,本地提供商可能会削减流量,CDN节点可能会过载,而DNS可能会解析到过时的IP。
另一个常见场景是CDN或WAF(Cloudflare、Akamai)级别的地理封锁。一些安全规则会阻止来自特定国家的整个IP范围,您的API在物理上对部分用户不可用,而从您的办公IP一切正常。如果仅从一个点进行测试,就无法诊断这些问题。
第三个场景是通过Anycast或区域CDN边缘进行负载均衡。来自德国的请求可能会到达一个节点,而来自新加坡的请求则会到达完全不同的节点,具有不同的缓存版本或配置。不同地区之间API行为的差异不是理论,而是全球用户分布的团队经常面临的现实。
5个只能通过外部IP看到的可用性指标
以下是五个指标,只有在请求来自物理位于目标国家或至少通过其网络路由的IP地址时,才能显示可用性的真实情况。
1. 响应时间(延迟/RTT)
往返时间(Round-Trip Time)是从发送请求到接收到第一个响应包的时间。从欧洲的一个服务器到您的API的延迟可能是20毫秒,而来自东南亚的用户由于地理距离和中间节点(hops)的数量将等待400-600毫秒。如果不从不同地区测量延迟,很容易错过服务对部分受众几乎不可用的时刻——这对于依赖实时操作的API尤其关键:广告竞标、聊天、金融交易。
2. TTFB(首次字节时间)
TTFB显示服务器处理请求到开始发送响应所需的时间。该指标不仅依赖于网络,还依赖于为特定区域服务的CDN或负载均衡器的节点。常常发生的是,一个国家的边缘服务器缓存响应并在50毫秒内返回,而在另一个国家,请求每次都到达源服务器并重新处理,耗时800毫秒或更多。不同地区之间的TTFB差异是CDN配置问题或边缘节点覆盖不足的可靠迹象。
3. DNS解析时间
DNS解析是延迟和错误的独立来源,完全依赖于用户的本地解析器。如果您设置了GeoDNS(根据请求区域的不同A记录),配置错误可能导致来自一个国家的用户解析到另一个大陆的数据中心——延迟巨大。只有在从目标国家的真实IP请求DNS解析时才能看到这个问题,本地测试总是会相对于您自己的地理位置“正确”解析。
4. 各地区成功请求的百分比(正常运行时间)
在从一个点发出的监控仪表板上显示的99.9%的正常运行时间,并不保证在另一个国家的用户也能达到99.9%。本地提供商可能在与您的托管提供商的对等连接上遇到问题,导致来自X国的部分请求超时,而其他地区则完全没有察觉到问题。要查看真实的正常运行时间,需要分别计算每个地区的成功和失败请求,而不是聚合。
5. 内容和状态码的差异(地理封锁和个性化)
第五个指标与速度无关,而是与响应内容本身有关。API可能会因WAF规则而返回403 Forbidden给特定国家,因许可证限制而返回缩减的数据集,或因与地理相关的A/B测试而显示不同版本的内容。如果仅从自己的IP测试API,这些差异将完全被忽视——而这些差异通常是特定地区用户投诉的主要原因。
重要理解
所有五个指标都需要从一个真实的IP发出请求,该IP确实通过目标国家的网络进行路由。只有一个国家的VPN或在同一地区的云服务器将提供近似的情况,但不会显示最终用户通过特定提供商及其到您API的路由所看到的内容。
如何设置来自不同国家的监控
设置逻辑很简单:您同时从多个点向您的API发送相同的HTTP请求,记录所有五个指标并比较结果。逐步如下:
- 列出优先国家——通常是流量或收入前5名的国家。
- 为每个国家准备一个具有该国真实IP的出口点(代理服务器或物理服务器)。
- 设置一个脚本或服务,通过每个点以指定的间隔(例如每5分钟)发送相同的请求。
- 将每个国家的所有5个指标单独记录到数据库或指标系统(Grafana、Prometheus、ClickHouse)中。
- 设置指标偏离基线水平的警报——例如,如果来自特定国家的延迟在一小时内增加了3倍。
关键点是第2点。没有真实的出口到目标国家,所有其他步骤都是无意义的,因为指标将测量的不是用户所看到的,而是您自己的监控服务器所看到的。
选择哪种类型的代理进行监控
对于构建地理分布的监控,通常使用代理服务器——这比在每个需要的国家租用物理服务器或VPS更便宜、更快。代理类型的选择取决于您想要测量的内容。
| 代理类型 | 何时使用 | 特点 |
|---|---|---|
| 数据中心代理 | 基本可用性和延迟检查,无需模拟真实用户 | 速度快,价格低,但IP容易被识别为数据中心——不适合根据提供商进行地理封锁测试 |
| 住宅代理 | 检查真实用户通过家庭提供商所看到的内容 | IP属于特定国家的真实提供商,更准确地反映路由和WAF规则 |
| 移动代理 | 测试移动应用程序和移动流量的API可用性 | 来自移动运营商网络的IP,显示特定于移动流量的延迟和阻塞 |
如果您的API主要服务于来自桌面和服务器的网络流量,构建基本监控只需数据中心代理——它们提供稳定的速度和可预测的延迟。但如果需要检查真实用户所面临的情况——包括根据提供商的ASN设置的地理封锁规则——则应使用住宅代理,因为它们通过该国的普通互联网提供商网络进行路由。对于移动应用程序和向API发出请求的SDK,合理地添加通过移动代理的检查,因为移动运营商通常使用NAT和自己的路由规则,这与家庭互联网不同。
用于收集指标的Python现成脚本
以下是一个简化的脚本示例,该脚本通过指定国家的代理发送请求并收集五个指标中的四个(内容差异需要单独比较响应)。该脚本使用requests库和socket模块来测量DNS解析时间。
import time
import socket
import requests
def measure_api(url, proxy, country_label):
hostname = url.split("//")[1].split("/")[0]
# 1. DNS解析时间
dns_start = time.time()
try:
socket.gethostbyname(hostname)
except socket.gaierror:
pass
dns_time = time.time() - dns_start
proxies = {
"http": proxy,
"https": proxy,
}
try:
start = time.time()
response = requests.get(
url,
proxies=proxies,
timeout=10,
stream=True
)
ttfb = time.time() - start # 近似TTFB
full_load_time = time.time() - start
status_code = response.status_code
success = status_code == 200
result = {
"country": country_label,
"dns_time_ms": round(dns_time * 1000, 2),
"ttfb_ms": round(ttfb * 1000, 2),
"total_time_ms": round(full_load_time * 1000, 2),
"status_code": status_code,
"success": success,
}
except requests.exceptions.RequestException as e:
result = {
"country": country_label,
"dns_time_ms": round(dns_time * 1000, 2),
"ttfb_ms": None,
"total_time_ms": None,
"status_code": None,
"success": False,
"error": str(e),
}
return result
# 使用来自不同国家的代理的示例
endpoints = [
{"label": "德国", "proxy": "http://user:[email protected]:port"},
{"label": "巴西", "proxy": "http://user:[email protected]:port"},
{"label": "新加坡", "proxy": "http://user:[email protected]:port"},
]
API_URL = "https://api.yourservice.com/health"
for ep in endpoints:
data = measure_api(API_URL, ep["proxy"], ep["label"])
print(data)
对于该脚本的生产版本,建议将结果记录到数据库(例如ClickHouse或InfluxDB),通过Grafana进行可视化,并在超过阈值时通过Telegram机器人或Slack webhook发送警报。最好通过cron或任务调度程序以每个国家5-15分钟的间隔运行脚本。
如果需要快速检查而不编写代码,可以通过cURL执行类似请求并测量时间:
curl -x http://user:[email protected]:port \
-o /dev/null -s -w "DNS: %{time_namelookup}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s | HTTP: %{http_code}\n" \
https://api.yourservice.com/health
如何解读结果
在收集了所有国家的数据至少一周后,每个地区会出现一个基线水平。接下来,您需要关注的不是绝对数字,而是与这个基线的偏差。如果来自巴西的延迟稳定在350毫秒——这在地理上是正常的,只有当值突然上升到1500毫秒时才应引起警报。正常运行时间也是如此:对于一个网络不稳定的复杂地区,99.5%可能是可以接受的,而降至95%则可能是提供商或CDN方面的问题的信号。
特别关注状态码403和451——它们几乎总是指向WAF或CDN的地理封锁,而不是API本身的问题。如果这些代码仅在特定国家出现,并且仅在使用特定类型的代理(例如数据中心代理)时出现,这可能意味着封锁是基于“IP看起来像数据中心”而不是基于真实地理位置——在这种情况下,使用住宅代理的测试将提供更真实的情况。
现成服务与自定义解决方案
如果不想维护自己的脚本,市场上有现成的合成监控服务,具有在不同国家的存在点:Pingdom、Uptrends、Site24x7、Checkly。它们免去了设置基础设施的必要,但通常限制在固定的地点集合,并且在选择特定测试的IP类型(住宅、移动、数据中心)时没有灵活性。
基于代理的自定义解决方案提供了更多控制:可以测试对您的业务重要的国家,在诊断特定问题(例如基于ASN的地理封锁)时在IP类型之间切换,并将指标直接集成到您的监控系统中,而无需多余的中介。两种方法的组合是合理的平衡:现成服务用于基本的SLA监控,自定义脚本与代理用于特定地区问题的精准诊断。
结论
从一个点进行的本地监控仅显示API可用性的部分真相。要看到真实情况,需要分别测量延迟、TTFB、DNS解析时间、正常运行时间和内容差异,并通过确实通过目标地区网络路由的IP进行测试。否则,您可能会错过阻碍部分用户使用服务的问题,而仪表板却显示“一切正常”。
对于构建这样的监控,住宅代理是最合适的选择,如果重要的是看到与特定国家的真实用户家庭互联网相同的内容。对于更便宜和快速的基本可用性检查,数据中心代理是合适的,而对于移动用户的问题诊断,则应添加通过移动代理的检查。这种组合方法提供了您API在世界任何地方的完整视图,而不仅仅是从其部署的服务器。