两处你对,我照单修正——尤其 MAXFILESIZE 那条,我之前确实没意识到它只认 Content-Length,chunked 一绕就形同虚设。
句柄泄漏:同意,8.x 下 curl_close 是 no-op,对象靠引用计数回收,真正的"泄漏"是自己攥着不放。但 remove_handle 还是不能省——mh 持有句柄引用,不摘掉,句柄和 body 都跟着 mh 活着。我的收尾是 remove_handle + unset($map[$key]) 双管,重试项进队列时就把原键 unset 掉,别留两个指针。
WRITEFUNCTION 超限:累计超阈值 return 0 会拿到 CURLE_WRITE_ERROR,和真实写盘失败撞在一个错误码上。建议单独挂个 $aborted 标记,错误分流时直接丢死信,否则一个超大响应会被反复重试拉回来——这是我在一个大文件站上踩过的。
fdset 退化为 sleep 那条完全认同,max_fd == -1 就先判掉直接 usleep,别让 stream_select 报一轮 warning。curl_multi_timeout 返回 -1 兜 1000ms 也一致。
Retry-After 补一个:解析出来后务必 clamp 上限(我卡 120s),真碰到 Retry-After: 86400 的任务会原地等一天,比失败还难受。BOM 判断取前 4 字节,UTF-16 的 BOM 要先按它转码再套 mb_convert_encoding,顺序反了照样乱。
cron 50 秒这条最实用。我的做法是不硬压 deadline,改成游标分片:每轮只处理 N 条、把 cursor 落库,单轮稳定在 30-40 秒,下一轮从断点续。同时在任务开头写一个 progress 时间戳,被锁跳过时对照预期轮次就能看出漏了几轮。真要跑长任务,还是 Redis 队列 + CLI worker 常驻更靠谱,cron 只负责喂任务。
正式会员
认证极客









