脚本怎样统计接口调用频次

wen 实用脚本 27

从零搭建日志分析与监控体系

📚 目录导读

  1. 统计接口调用频次的核心价值
  2. 常见实现方案对比
  3. 实战:Python脚本统计API频次
  4. Shell脚本快速统计方案
  5. 实时监控与告警集成
  6. FAQ:常见问题与解决方案

统计接口调用频次的核心价值

你是否遇到过:线上服务突然变慢,却不知道哪个接口被疯狂调用?老板问“这个API每天有多少请求”,你只能靠瞎猜?

脚本怎样统计接口调用频次

接口频次统计是运维和开发人员的必备技能,它能帮助:

  • 性能调优:识别高频调用接口,提前优化瓶颈
  • 故障定位:发现异常突增(如爬虫攻击、死循环请求)
  • 容量规划:根据调用量合理分配服务器资源

常见实现方案对比

方案 适用场景 优点 缺点
访问日志分析 所有Web服务 无侵入,生效快 依赖日志采集
应用代码埋点 自研系统 数据精确 需修改代码
中间件拦截 API网关、Nginx 统一管理 需部署组件
数据库计数器 低频场景 简单粗暴 高并发有瓶颈

推荐组合:日志分析 + 预聚合(如Redis计数)是最实用的“黄金搭档”。


实战:Python脚本统计API频次

假设你有Nginx访问日志(如:/var/log/nginx/access.log),每行格式:

168.1.1 - - [10/Feb/2025:12:00:01 +0800] "POST /api/order HTTP/1.1" 200 1234

1 基础统计脚本

import re
from collections import Counter
def parse_log(file_path):
    """提取API路径并统计频次"""
    pattern = r'"\w+ (/[/\w-]+) HTTP'  # 匹配请求路径
    api_counter = Counter()
    with open(file_path, 'r') as f:
        for line in f:
            match = re.search(pattern, line)
            if match:
                api = match.group(1)
                api_counter[api] += 1
    return api_counter
if __name__ == "__main__":
    result = parse_log("access.log")
    for api, count in result.most_common(20):
        print(f"{api}: {count} 次")

输出示例

/api/order: 15832 次
/api/user/info: 10921 次
/api/payment/callback: 234 次

2 带时间窗口的统计

from datetime import datetime, timedelta
import re
def count_by_hour(log_file, target_date):
    """统计某天每小时的调用量"""
    hourly_count = {i:0 for i in range(24)}
    date_pattern = target_date.strftime("%d/%b/%Y")
    with open(log_file, 'r') as f:
        for line in f:
            if date_pattern not in line:
                continue
            # 提取小时信息
            hour_match = re.search(r':(\d{2}):', line)
            if hour_match:
                hour = int(hour_match.group(1))
                hourly_count[hour] += 1
    return hourly_count
# 使用示例
from datetime import date
today = date.today()
result = count_by_hour("access.log", today)
for hour, count in result.items():
    print(f"{hour}:00 - {count}")

Shell脚本快速统计方案

无需编程环境?一行Shell搞定:

# 统计Top 10接口
grep -oP '"\w+ /\K[^"]+' access.log | sort | uniq -c | sort -rn | head -10
# 按分钟统计请求量
awk '{print $4}' access.log | cut -d: -f1-2 | sort | uniq -c | sort -rn

关键参数解析:

  • -oP:使用Perl兼容正则,仅输出匹配部分
  • \K:重置匹配起点,只保留API路径
  • uniq -c:去重并计数

实时监控与告警集成

1 对接Prometheus

# prometheus_client 示例
from prometheus_client import Counter, start_http_server
import time
REQUEST_COUNT = Counter('api_requests_total', 'Total API requests', ['method', 'endpoint'])
def process_request(method, endpoint):
    REQUEST_COUNT.labels(method=method, endpoint=endpoint).inc()
# 启动指标暴露端
start_http_server(8000)
while True:
    time.sleep(1)

2 阈值告警(基于Python)

ALERT_THRESHOLD = 1000  # 每分钟超过1000次触发
def check_alert(api, current_count):
    if current_count > ALERT_THRESHOLD:
        send_alert(f"API {api} 调用频次异常:{current_count}/min")
        # 可联动:调用限流API、触发自动扩容

FAQ:常见问题与解决方案

❓ Q1:日志文件太大(10GB+),脚本处理太慢怎么办?

A:推荐以下策略:

  • 行级处理:使用awksed替代Python(纯C实现,快10倍)
  • 分片读取for i in split -l 500000 access.log; do python count.py $i ; done
  • 流式处理:使用tail -F配合缓冲,实时消费新日志

❓ Q2:如何区分正常流量和爬虫攻击?

A:在统计中加入IP维度:

# 统计每个IP的调用频次
ip_counter = Counter()
ip_api_pair = {}  # 记录IP调用的API列表
# 如果同一IP每秒请求超过50次→标记为异常

❓ Q3:统计结果和实际流量有差异?

A:常见原因:

  • 日志轮转导致重复统计 → 使用inotify监控日志新建事件
  • 负载均衡器日志和业务日志混杂 → 增加服务标识字段(如X-Request-ID

❓ Q4:需要统计第三方API的调用频次?

A:可通过代理拦截(如Nginx反向代理)或DNS劫持统一记录:

http {
    log_format extended '$remote_addr - $upstream_response_time "$request"';
    server {
        location / {
            proxy_pass http://third_party_service;
            access_log /var/log/third_api.log extended;
        }
    }
}

📌 总结与最佳实践

通过脚本统计接口调用频次,无需昂贵APM工具,也能实现精准监控,建议遵循:

  1. 日志先行:确保Nginx/应用日志包含完整请求信息
  2. 分级统计:秒级用Redis,小时级用日志分析,天级用离线任务
  3. 自动化:将脚本做成crontab任务,结果写入时序数据库

立即行动:复制上面的Python脚本,在测试环境运行5分钟,你就能看到线上最真实的接口调用图谱。

(本文技术验证环境:Python 3.9 + Ubuntu 20.04 + Nginx 1.18)

抱歉,评论功能暂时关闭!