cronjob 执行具有大约 100 个 curl URL 的脚本 - 不好的做法?



我正在编写一个 cron 作业,它将执行一个脚本,该脚本将加载多达 ~ 100 个 url,每个 url 都有在执行时将被内存缓存的数据。每个 url 的结束/加载时间可能需要 10 秒到 15 分钟,每个 url 从数据库加载数据并将结果作为 json 返回,并缓存结果。 此脚本的要点是在早上(00:00 - 直到缓存所有内容所需的时间(缓存结果数据,因此在早上人们不必等待数据再次缓存。

这些网址是 API 网址。curl 会等待每次执行结束吗?这算不算不好的做法?到目前为止,还没有缓存,所以我正在尝试实现它,将最常用的 url 数据缓存 24 小时或类似时间。

关于curl集成...

curl 会等待每次执行结束吗?

这取决于您如何使用 curl 库。您已经用"php"和"php-curl"标记了问题 - 所以看起来您正在从PHP访问curl的例程。

如果您以类似于以下方式使用 curl 的easy接口:

  • 使用$req = curl_init()初始化简单句柄
  • 使用curl_setopt()设置 URL 和其他参数
  • 使用curl_exec($req)执行(单个(请求
  • 使用curl_close($req)curl_reset($req)关闭或重置请求

然后,自然地,您必须等到每个请求完成才能开始下一个请求。

另一种方法是使用multi接口(见下文( - 它允许多个请求同时运行。

这算不算不好的做法?

如果您要发送如此大量的网络请求 - 并且每个请求可能需要很长时间 - 我认为这肯定远非理想。如果可能的话,最好使用 curl 的接口。

multi界面

正如curl的文档所解释的那样,多接口(与"简单"接口相反(

在同一线程中启用多个同时传输,而不会使应用程序变得复杂...

我的PHP非常弱,所以 - 我不会自己发布一个完整的示例 - 而是向您推荐PHP关于curl_multi_exec()和相关函数的文档。

简而言之,这个想法是你仍然以相同的方式初始化你的卷曲句柄。(PHP 的文档没有明确提到这一点,但普通卷曲句柄有时被称为"简单"句柄 - 以区别于"多"句柄。

$req1 = curl_init();
$req2 = curl_init();
// Set URL and other options using `curl_setopt(...)`

(为了简洁起见,我在这里省略了所有错误检查。 但是,您不是调用curl_exec(...),而是创建一个multi实例,

$mh = curl_multi_init();

easy句柄添加到新创建的multi实例,

curl_multi_add_handle($mh, $req1);
curl_multi_add_handle($mh, $req2);

然后(而不是为单个easy句柄调用curl_exec()(在循环中定期调用curl_multi_exec(...)

curl_multi_exec($mh, $running);

$running变量将被更新以指示是否有请求仍在进行中,因此 - 一旦$running为 false,您就可以退出循环并结束。

完成后,不要忘记整理。

curl_multi_remove_handle($mh, $req1);
curl_multi_remove_handle($mh, $req2);
curl_multi_cleanup($mh);

针对大量请求进行优化

与其为每个请求使用不同的变量 - 如$req1$req2等 - 您可以使用请求数组 - 也许从文本文件加载相关URL(我怀疑您已经在这样做了(。

确保你的脚本不会超时,所以从 BASH 或其他东西运行它,而不是通过服务器(Apache、NGINX 等(。

另外:确保您的 curl 命令等待足够长的时间,查找 curl 规格。

https://unix.stackexchange.com/questions/94604/does-curl-have-a-timeout/94612

最后:确保如果 100 个中有 1 个坏了,请不要出错。

如果你能合理地满足/解决这3个可能的问题,我想你应该没问题。(我总是将输出发送到我自己的邮件中,以密切关注它(

最新更新