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

cronjob executing a script with around 100 curl url's - bad practice?

我正在编写一个 cron 作业,该作业将执行一个脚本,该脚本最多加载约 100 url 秒,每个 url 都有将在执行时被内存缓存的数据。每个 url 到 end/load 的时间可能需要 10 秒到 15 分钟,每个 url 从数据库加载数据并且 returns 结果为 json ,并缓存结果。 这个脚本的主要目的是在早上缓存结果数据(00:00 - 直到缓存所有内容所需的时间),这样早上人们就不必等待数据再次缓存.

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

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

此外:确保您的 curl 命令等待足够长的时间,查看 curl 规范。

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

最后:如果 100 个中有 1 个出现问题,请确保您不会出错。

如果你能合理satisfy/solve这3个可能的问题,我想你应该没问题。 (我总是将输出发送到我自己的邮箱,以保持关注)

关于 curl 集成 ...

Will curl wait for each execution to end?

这取决于您如何使用 curl 库。您已经用 'php' 和 'php-curl' 标记了问题 - 所以您似乎正在从 PHP.

访问 curl 的例程

如果您按以下方式使用 curl 的 easy 界面:

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

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

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

is this considered bad practice?

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

multi界面

正如 curl's documentation 所解释的那样,多接口(与 'easy' 接口相反)

Enable[s] multiple simultaneous transfers in the same thread without making it complicated for the application ...

我的 PHP 非常薄弱,因此 - 我不会自己发布完整的示例 - 我会推荐您参考 PHP 关于 curl_multi_exec() 和相关函数的文档。

简而言之,想法是您仍然以相同的方式初始化您的 curl 句柄。 (PHP 的文档没有明确提及这一点,但普通卷曲句柄有时被称为 'easy' 句柄 - 以区别于 'multi' 句柄。)

$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 变量将更新以指示是否还有请求仍在进行中,因此 - 只要 $运行 为假 - 您就可以退出循环并结束。

完成后,别忘了收拾一下。

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

针对大量请求进行优化

不是为每个请求使用不同的变量 - 如 $req1$req2 等 - 您可以使用请求数组 - 也许从加载相关的 URLs一个文本文件(我怀疑你已经在做)。