
本文介绍使用php结合cron定时任务与状态锁机制,安全、稳定地分页拉取数十万级api数据(如300k+记录),兼顾jwt鉴权、速率限制(50次/3分钟)与内存可控性,避免服务过载。
本文介绍使用php结合cron定时任务与状态锁机制,安全、稳定地分页拉取数十万级api数据(如300k+记录),兼顾jwt鉴权、速率限制(50次/3分钟)与内存可控性,避免服务过载。
在处理大规模API数据(例如30万+条记录)时,直接循环请求所有分页极易触发限流、超时或内存溢出。尤其当API每页仅返回25条、且限制为50次请求/3分钟时,全量拉取需约12,000次请求——显然无法在单次脚本中完成。核心思路不是“更快地跑完”,而是“可持续、可恢复、不冲突地分片执行”。
✅ 推荐架构:Cron + 状态锁 + 持久化存储
避免使用前端JavaScript(JS)在浏览器中分页拉取:它受限于跨域、超时、内存崩溃及用户会话中断,完全不适用于后台批量任务。PHP后端配合系统级Cron才是可靠选择。
1. 状态锁防止并发冲突
必须确保同一时间仅有一个实例运行,否则多个进程叠加请求将迅速突破50次/3分钟限制,导致429错误甚至IP封禁。推荐用轻量级方式实现锁,例如:
<?php $lockFile = '/tmp/api_fetch_lock';
if (file_exists($lockFile) && (time() - filemtime($lockFile)) < 180) {
exit("Script is already running or stale lock exists.\n");
}
file_put_contents($lockFile, date('c'));
try {
// ✅ 此处执行单次分页请求(含JWT认证、curl配置、结果解析)
$page = (int)(file_get_contents('/tmp/api_next_page') ?: '1');
$token = getJwtToken(); // 你的JWT获取逻辑(可缓存+自动刷新)
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://api.example.com/data?page={$page}&per_page=25",
CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($data['data'])) {
throw new Exception("Invalid API response on page {$page}");
}
// ✅ 保存当前页数据(推荐追加写入文件或插入数据库)
file_put_contents('/var/data/api_export.json', json_encode($data['data']) . "\n", FILE_APPEND | LOCK_EX);
// ✅ 更新下一页序号(关键:原子更新)
file_put_contents('/tmp/api_next_page', (string)($page + 1));
// ✅ 可选:记录日志
error_log("[INFO] Fetched page {$page}, ".count($data['data'])." records.");
} catch (Exception $e) {
error_log("[ERROR] Page {$page}: " . $e->getMessage());
} finally {
unlink($lockFile); // 释放锁
}
?>
2. Cron调度策略(关键!)
在服务器添加定时任务,严格控制频率:
# 每3分钟最多执行1次(匹配API配额) */3 * * * * /usr/bin/php /path/to/fetch_api_page.php >> /var/log/api_fetch.log 2>&1
⚠️ 注意:不要设为
* * * * *(每分钟执行),否则3分钟内可能堆积3个进程,直接触发限流。
3. 增强健壮性的建议
-
JWT Token自动续期:检查
exp字段,提前5分钟刷新token并持久化; - 失败重试机制:对HTTP非2xx响应增加指数退避(如sleep(1, 2, 4, 8秒)后重试1次);
-
断点续传保障:每次成功后才更新
/tmp/api_next_page,崩溃时从最后成功页继续; - 数据去重与校验:若API不保证分页绝对有序,入库前按唯一ID去重;
-
监控与告警:当连续5次失败或
/tmp/api_next_page长时间未更新时,触发邮件通知。
总结
分页拉取海量API数据的本质是工程化任务编排问题,而非单纯编码技巧。放弃“一次性跑完”的幻想,转而构建:
? 有状态的分步执行器(通过文件锁+页码文件实现)
? 受控的调度节奏(Cron精准匹配API速率窗口)
? 持久化的中间存储(文件追加或数据库批量插入,避免内存爆炸)
这样既能稳定应对300k+数据,也为后续增量同步、错误排查和横向扩展打下基础。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










