如何使此PHP cURL执行得更好?

时间:2019-05-08 11:53:27

标签: php curl

以下与我正在开发的开发站点有关。它在Ionos(1and1)上的云服务器上运行,该服务器在CentOS Linux 7.6.1810(Core)和PHP 7.2.18上运行。

我有一个php cronjob,它是一个父进程。该脚本检查数据库中是否需要处理的记录,对于每个需要处理的记录,父级会生成一个通过php cURL调用的子进程。我正在使用multi_curl功能。

我目前正在用25条虚拟记录进行测试,并且在生产时将需要能够处理多达5000条记录。当前,子进程仅将结果写入日志文件。

所有25个子进程都需要几乎同时启动;但是,少于10个(通常少于5个)同时启动,然后其余的随着以前的请求结束而启动。这是不可接受的,并且我需要知道要更改我的设置(php / mysql / etc)中的哪些内容才能解决此问题,并尽可能同时启动所有子进程。

父进程从数据库中选择要处理的记录,然后通过以下方式生成子进程:

    $ch = array();
    $mh = curl_multi_init();
    $URLs = array();

    while ($row = mysqli_fetch_assoc($sql_list)) { // process each reservation
    extract($row);

        $url = '/cronjobs/reservation.child.php?jid=' . $j_id;
        array_push($URLs, $url);
}

   foreach ($URLs as $url) {
    $ch[$i] = curl_init();
    curl_setopt($ch[$i], CURLOPT_URL, $url);
    curl_setopt($ch[$i], CURLOPT_HEADER, 0);

    curl_multi_add_handle($mh, $ch[$i]);
    $i++;
}

$active = null;
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($active);


$i = 0;
foreach ($ch AS $i => $c) {
    curl_multi_remove_handle($mh, $c);
}

curl_multi_close($mh);

,并且产生的子进程当前正在写入日志文件。就是这样。

以下是最近的日志条目:

2019-05-07 13:32:01:开始处理请求

2019-05-07 13:32:01:请求ID 1:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 2:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 3:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 4:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 5:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 6:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 7:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 8:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 9:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 10:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 11:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 12:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 13:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 14:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 15:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 16:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 17:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 18:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 19:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 20:输入的处理队列,状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 21:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 22:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 23:输入的处理队列和状态已更新为“正在处理”

2019-05-07 13:32:01:请求ID 24:输入的处理队列,状态更新为“正在处理”

2019-05-07 13:32:01:请求ID 25:输入的处理队列,状态更新为“正在处理”

到目前为止,父php脚本已经通过php cURL产生了25个子代……到目前为止还算不错。但是,所有25个都应该几乎同时开始,但这是结果:

2019-05-07 13:32:01:请求ID 7:在13:32:01.97731400提交,状态更新为“已处理”

2019-05-07 13:32:01:请求ID 4:在13:32:01.98214300提交,状态更新为“已处理”

2019-05-07 13:32:02:请求ID 3:在13:32:02.99112000提交,状态更新为“已处理”

2019-05-07 13:32:02:请求ID 11:在13:32:02.99643700提交,状态更新为“已处理”

2019-05-07 13:32:02:请求ID 1:在13:32:02.99687200提交,状态更新为“已处理”

2019-05-07 13:32:02:请求ID 13:在13:32:02.99788200提交,状态更新为“已处理”

2019-05-07 13:32:03:请求ID 5:在13:32:03.00521700提交,状态更新为“已处理”

2019-05-07 13:32:03:请求ID 10:在13:32:03.00567200提交,状态更新为“已处理”

2019-05-07 13:32:33:请求ID 14:在13:32:33.97885900提交,状态更新为“已处理”

2019-05-07 13:32:34:请求ID 25:在13:32:34.98112300提交,状态更新为“已处理”

2019-05-07 13:32:38:请求ID 12:在13:32:38.98721700提交,状态更新为“已处理”

2019-05-07 13:32:38:请求ID 6:在13:32:38.98854100提交,状态更新为“已处理”

2019-05-07 13:32:43:请求ID 21:在13:32:43.00379900提交,状态更新为“已处理”

2019-05-07 13:32:45:请求ID 2:在13:32:45.00574600提交,状态更新为“已处理”

2019-05-07 13:32:53:请求ID 15:在13:32:53.05596300提交,状态更新为“已处理”

2019-05-07 13:32:53:请求ID 20:在13:32:53.05604100提交,状态更新为“已处理”

在产生的25个孩子中,只有15个实际得到处理,并且不是所有的孩子都是从13:32:01开始,而是花了将近一分钟的时间来产生。

我在处理过程中监控了顶部,并且CPU使用率从未超过2.x%。

在该网站的plesk日志中,某些子级出现以下错误:

504 GET /cronjobs/reservation.child.php?jid=8&jeid=027093&starttime=1557250321.6883&timeToStartProcess=1557250380&timeToSleep=58307153 HTTP / 1.0

以及

mod_fcgid:45秒内读取数据超时

在标头之前的脚本输出结尾:jumpseat.reservation.child.php

* 152510上游从上游读取响应头时超时(110:连接超时)

我正在运行php 7.2.18,已经尝试过FastCGI和两种FPM。我还尝试了各种PHP-FPM设置组合。

我需要做什么/更改/配置才能几乎同时启动数千个处理过的东西。

谢谢。

1 个答案:

答案 0 :(得分:0)

如果您只是点击URL,请查看以下替代实现:

https://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/

就服务器资源而言,您可以根据自己的喜好设置$rolling_window(并行线程数)。