必须监控ttfb的p99而非平均值或状态码,超1.2s即告警,因composer update卡在packages.json拉取阶段;需用带composer user-agent和-w "%{time_starttransfer}"的curl实测,禁用缓存并绕过sni,同时关联同步新鲜度指标定位真因。

必须监控 TTFB 的 P99,不是平均值,也不是 HTTP 状态码——P99 超 1.2s 就该告警,否则 composer update 会在拉取 packages.json 阶段卡住,用户感知就是“卡死”。
为什么不能用 composer diag 或 curl -I 做告警探测
前者只验证连通性,不发真实元数据请求;后者可能命中 CDN 缓存页或返回 403(缺 User-Agent)。镜像站对非 Composer 请求常直接拒收。真实延迟必须用带正确标识的短连接实测。
- 必须加
-H "User-Agent: Composer/2.9.6",否则阿里云、腾讯云等镜像返回 403 - 必须用
-w "%{time_starttransfer}"提取服务端开始吐数据的时间,%{time_total}包含 DNS/TLS,干扰太大 - 避免缓存干扰:加
-H "Cache-Control: no-cache"或用随机查询参数(如?t=123)
如何用 curl 实测真实 TTFB 并接入 Prometheus
告警依据是服务端首字节响应时间(TTFB),不是整个下载耗时。以下命令可直接用于 exporter 或 probe:
curl -s -o /dev/null -f \
-H "User-Agent: Composer/2.9.6" \
-H "Accept: application/json" \
-H "Cache-Control: no-cache" \
-w "TTFB: %{time_starttransfer}s\n" \
https://mirrors.aliyun.com/composer/packages.json
- 若遇 SSL 错误或超时,先用
--resolve mirrors.aliyun.com:443:223.6.6.6绕过本地 DNS/SNI 问题 - Prometheus 中采集指标应为
probe_http_duration_seconds{phase="starttransfer", url=~".*/packages.json"} - 计算 P99 的 PromQL:
histogram_quantile(0.99, sum(rate(probe_http_duration_seconds_bucket[5m])) by (le, url))
告警阈值设为 1.2s 的实际依据和干扰排除
这个数字不是拍脑袋定的:阿里云镜像正常 P99 在 0.8–1.1s,腾讯云高峰可达 1.3–1.5s;一旦持续 > 1.2s,composer install 平均耗时增加 3–7 秒。但需过滤伪故障。
- 上游
packagist.org返回 503 时,镜像站会重试上游,导致 TTFB 突增——用 PromQL 加unless on() (probe_http_status_code{job="upstream-packagist"} == 503)过滤 - 单看 TTFB 没意义:如果镜像元数据已滞后 5 分钟,即使 TTFB 是 0.3s,用户照样遇到
Could not find package xx——必须关联同步新鲜度指标(如mirror_last_sync_age_seconds) - 告警触发后,第一反应不是重启服务,而是查
curl -I https://mirrors.aliyun.com/composer/p2/laravel/framework/10.0.0.json是否返回 200,确认是否真卡在 provider 同步环节
真正关键的不是“有没有告警”,而是告警时能否立刻区分:是网络抖动、镜像站过载,还是上游同步中断?TTFB + 同步滞后 + 上游状态三者缺一不可,漏掉任一维度,就会把“镜像没同步”误判成“服务挂了”。











