商会系统上线后,会员反馈"列表偶尔卡好几秒""导出报表半天"。这类"慢"本地复现不了,只能上线上看真实日志,我们之前靠文本日志 grep 半天,效率很低。
后来把日志接进 SLS,再用函数计算 FC 跑定时排查,慢接口一目了然。
一、先说边界
我们的诉求三点:查任意窗口的接口耗时分布、慢接口自动告警、排查任务按需跑不养服务器。
基于这三条,我们排除了两套:自己搭 ELK 运维太重,只打点又没法聚合查询。
最终方案:日志统一采集到 SLS,用其查询分析做耗时统计,用 FC 定时跑慢接口巡检并告警。
二、日志采集:Logtail 统一打点
后端每个接口在入口出口记录耗时,按统一 JSON 输出,Logtail 自动采集进 SLS。
{
"level": "info",
"trace_id": "a1b2c3",
"method": "GET",
"path": "/api/members",
"status": 200,
"cost_ms": 1820,
"org_id": 1024,
"ts": "2026-09-07T10:22:01Z"
}
关键是 cost_ms 和 path 两个字段,Logtail 设成索引 SLS 才能统计。
三、SLS 查询:耗时分布
查某个接口在过去一小时的 P95 耗时,用 SLS 的 SQL 分析:
* and path: "/api/members" and status: 200
| select
date_trunc('minute', ts) as minute,
avg(cost_ms) as avg_ms,
approx_percentile(cost_ms, 0.95) as p95_ms,
count(*) as qps
group by minute
order by minute
这条查询画出每分钟平均耗时和 P95 曲线,哪个分钟突然抬高一眼可见。
还加了一条"慢请求明细"查询,专门捞耗时超一秒的:
* and cost_ms > 1000
| select path, cost_ms, org_id, ts
order by cost_ms desc
limit 100
这根查询排在前面的,就是当天响应慢的接口,排查就从这里入手。
四、函数计算:定时巡检 + 告警
SLS 查询要手动跑,我们希望每天自动跑、超阈值告警,于是用 FC 定时触发器跑巡检函数。
const {
Client } = require('@alicloud/sls20201230');
exports.handler = async (event) => {
const client = new Client({
accessKeyId: process.env.AK, accessKeySecret: process.env.SK, endpoint: process.env.SLS_EP });
const query = `* and cost_ms > 1000 | select path, approx_percentile(cost_ms,0.95) as p95, count(*) as cnt group by path having cnt > 20`;
const res = await client.ExecuteQuery({
projectName: process.env.SLS_PROJECT,
logStoreName: 'app-access',
query,
from: Date.now() - 3600 * 1000,
to: Date.now()
});
const slow = (res.body.results || []).filter((r) => r.p95 > 800);
if (slow.length) {
// 推到钉钉/短信,这里只示意
await notify({
title: '慢接口告警', detail: slow.map((s) => `${
s.path} p95=${
s.p95}ms 次数=${
s.cnt}`) });
}
return {
slowCount: slow.length };
};
FC 按调用计费,巡检每天跑几次费用可忽略。
五、实战:一次导出接口变慢
上个月排查"导出报表卡半天",按上面流程先捞慢请求明细,发现 /api/reports/export 的 P95 到八秒,且卡在一个 org_id 上。
顺着 org_id 查发现导出时后台在跑全量会员聚合查询,重查询和定时任务撞车。
解决办法:导出任务改异步扔进消息队列,后端限流控制同时只跑两个导出。改完再跑巡检,P95 回到一秒以内。
走 SLS 加 FC,从告警到定位不到一小时。
六、几个细节
一是索引字段别太多。SLS 按索引字段计费,只把 path、status、cost_ms、org_id、ts 设索引,其余当原文存,省钱。
二是采样,高峰全量采集量大,对 info 级采样、error 级全采,存储成本降六成。
三是告警阈值:P95 超八百毫秒且持续十分钟才告警,避免偶发抖动误报。
四是 trace_id 串联,慢请求顺 trace_id 看完整调用链,前端到数据库都能追。
我们这边在跑的商会管理系统叫未来漫城·商会互联平台,线上可观测就是这套 SLS 加 FC 的组合,会员反馈"卡"时秘书处不用等我们远程,告警已先到,慢接口在哪个商会、哪个接口、卡多久,打开 SLS 一看就清楚。