多迈知识库
第二套高阶模板 · 更大气的阅读体验

服务端如何做数据统计

发布时间:2025-12-09 03:37:30 阅读:327 次

服务数据统计的常见场景

你在刷短视频时,每点一次“点赞”,背后就是一次服务端的数据记录。用户行为、访问量、订单金额、在线人数——这些数字不会自己跑进报表里,得靠服务端有条不紊地收集和处理。

比如一个电商后台要统计今天卖了多少单,不能等到晚上再翻日志一条条数,而是实时或准实时地把订单生成事件上报到统计系统。

数据采集:从请求中捞信息

每次客户端发请求,服务端都能拿到不少可用信息:IP、User-Agent、请求路径、耗时、状态码。把这些打个标记存下来,就是原始数据。

以 Node.js 为例,可以在中间件里记录访问日志:

app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
console.log(JSON.stringify({
method: req.method,
url: req.url,
status: res.statusCode,
ip: req.ip,
ua: req.get('User-Agent'),
duration_ms: duration
}));
});
next();
});

这些日志可以写入文件,也可以直接发到消息队列。

异步上报避免拖慢主流程

如果每来一个请求就同步写一次数据库,服务器很容易被拖垮。更常见的做法是把数据先丢进 Kafka 或 RabbitMQ 这类消息队列,由后台消费者慢慢处理。

比如用户完成支付后,服务端不直接更新统计表,而是发一条消息:

{
"event": "order_paid",
"amount": 299.5,
"user_id": 10086,
"timestamp": 1717023456
}

另一个进程监听这个消息,负责累加今日销售额、更新用户消费等级等操作。

聚合存储:从明细到汇总

原始数据太多,直接查很慢。通常会用定时任务做聚合,比如每小时算一次 PV、UV,结果存进 Redis 或 MySQL。

Redis 的 HyperLogLog 适合算 UV:

await redis.pfadd('pv:2024-05-30', req.ip);
await redis.incr('uv:2024-05-30');

MySQL 里可以用时间分表,每天一张表存访问记录,方便归档和查询。

监控与报警:让数据说话

光统计没用,得能发现问题。比如 5 分钟内 5xx 错误暴涨,系统就得立刻告警。可以用 Prometheus 抓取接口错误率,配合 Grafana 做可视化面板。

一个简单的指标暴露接口:

app.get('/metrics', (req, res) => {
res.set('Content-Type', 'text/plain');
res.send(`http_requests_total{status="5xx"} ${errorCount}’n`);
});

Prometheus 定时抓取这个接口,就能画出趋势图,设置阈值触发钉钉或邮件通知。

隐私与合规别忽视

统计时容易顺手记下用户手机号、身份证号,这是大忌。敏感字段要脱敏,比如只记录 user_id 而非真实姓名。国内还得遵守《个人信息保护法》,日志保存不能无限期,用户注销后数据也得清理。

实际操作中,很多团队会在日志写入前加一层过滤:

function safeLog(data) {
const clean = { ...data };
delete clean.phone;
delete clean.id_card;
return console.log(JSON.stringify(clean));
}