调用量统计

场景

用户认证系统上线后,业务继续增长。

新需求

运营团队找到我:

Ops Chat
周一 10:20

我们需要了解:

  1. 每个用户用了多少次 API?
  2. 哪些时间段的调用最多?
  3. 哪些 API 接口最热门?
  4. 谁是我们的重度用户? 这些数据对后续推出付费套餐很重要。

我意识到:需要建立完善的统计系统。

当前问题

我查看了一下当前的日志系统:

问题 1:查询太慢

设计流程
当前问题:数据模型
  1. 步骤 1:按业务维度聚合统计结果
  2. 步骤 2:确认「当前问题:数据模型」涉及的请求、数据对象和责任边界
  3. 步骤 3:根据输入、状态和失败情况选择后续路径
  4. 步骤 4:写入处理结果,并返回可观测的业务状态
关注点:输入边界、状态变化、失败处理和验证方式。

这个查询需要扫描几十万条记录,耗时 2-5 秒

问题 2:统计维度不够

当前只能按用户统计,但运营需要:

  • 按时间统计(每小时、每天)
  • 按接口统计(哪个接口最热门)
  • 按响应时间统计(性能分析)

问题 3:数据量太大

日志表每个月增加 600 万条记录:

  • 3 个月:1800 万条
  • 查询越来越慢
  • 数据库压力越来越大

解决思路

我决定采用预聚合的方式:

核心思想

不实时统计原始日志,而是:

  1. 实时更新统计数据
  2. 定期聚合原始日志
  3. 查询时直接读取统计数据

优势

  • 查询速度极快(直接读取统计结果)
  • 原始日志可以定期清理
  • 支持多种统计维度

设计统计表

修改 API 调用逻辑

API 调用统计流程
API 请求到达
用户发起 API 调用请求
执行业务逻辑
处理请求并获取结果,记录响应时间
记录原始日志
将调用详情写入 api_logs 表
更新统计数据
实时更新 api_stats_hourly 小时统计
返回响应
将业务结果返回给客户端
定时聚合任务
小时统计
实时更新
每条 API 请求时实时更新
表:api_stats_hourly
日统计
每天凌晨 1 点
聚合小时数据,按用户 + 接口分组
表:api_stats_daily
月统计
每月 1 号凌晨 2 点
聚合日数据,统计月度趋势和最常用接口
表:user_stats_monthly

数据清理

有了统计表后,原始日志可以定期清理:

数据清理任务
crontab 0 3 * * 0 /usr/bin/python3 /path/to/clean_logs.py
确定清理时间点
每周日凌晨 3 点执行
计算截止日期
当前时间往前推 90 天
归档旧日志
将过期数据导出为 CSV 文件保存
删除旧日志
从 api_logs 表中删除 90 天前的记录
完成
提交事务并输出清理统计信息

练习

练习 1

如果运营说“昨天的调用量和用户后台看到的不一致”,你会优先检查哪些地方?

参考答案 (3 个标签)
调用量统计 数据口径 排查思路

先不要急着改代码,要先确认是不是统计口径不同

排查顺序可以是:

  1. 确认时间范围:运营看的“昨天”是自然日、UTC 时间,还是北京时间。
  2. 确认统计对象:是否只统计成功请求,还是失败、限流、超时请求也算。
  3. 确认聚合延迟:预聚合任务是否延迟,昨天的数据是否已经跑完。
  4. 抽样对账:选一个用户,把原始日志、统计表、用户后台三边对一下。

如果三边对不上,再检查写日志是否漏记、聚合任务是否重复跑、清理任务是否提前删除了原始日志。

当前架构