美文网首页
php中curl未设置超时导致的睡眠进程问题

php中curl未设置超时导致的睡眠进程问题

作者: 叛逆的机器人 | 来源:发表于2020-04-21 22:00 被阅读0次

在我们的业务中,需要定时任务去执行php脚本,对苹果自动续费用户进行续约。某次发现有大量的定时任务在执行,有些开始时间是半年前,所有进程都处于睡眠中。

root     31625  0.0  0.0 108124  1304 ?        Ss   Mar22   0:00 /bin/sh -c /usr/local/php7/bin/php -r 'Crontab::debug("/data/erge_api", "Cron_Apple_Pay_Subscribe");' >> /tmp/cronapplepaysubscribe.log 2>&1
root     31634  0.0  0.0 233520 10064 ?        S    Mar22   0:49 /usr/local/php7/bin/php -r Crontab::debug("/data/erge_api", "Cron_Apple_Pay_Subscribe");

通过lsof命令可以发现,该进程打开了两个socket,一个是连接数据库的,一个是请求苹果服务器的。

php     31634 root    3u  IPv4 3973134538      0t0        TCP localhost:63880->localhost:27017 (ESTABLISHED)
php     31634 root    4u  IPv4 3973134589      0t0        TCP 192.168.10.100:17462->17.154.66.159:https (ESTABLISHED)

再通过strace命令,可以发现进程一直在进行如下调用,而且文件描述符就是4,也就是说,进程一直轮询地获取从苹果服务器那边的数据。

restart_syscall(<... resuming interrupted call ...>) = 0
poll([{fd=4, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
clock_gettime(CLOCK_MONOTONIC, {41212631, 418739828}) = 0
clock_gettime(CLOCK_MONOTONIC, {41212631, 418821856}) = 0
clock_gettime(CLOCK_MONOTONIC, {41212631, 418887370}) = 0

为了确认这个现象,可以在应用程序中加上日志。Logger打印日志的时候还会加上进程ID。

        Logger::crontab($value, 'start', __CLASS__);
        $ch = curl_init($endpoint);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);   

        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $errmsg = curl_error($ch);
        curl_close($ch);
        Logger::crontab($response, "applepay|notify|receiptdata", __CLASS__);

通过日志发现,只有start,没有notify的记录,那么问题基本可以确定出现在curl上。curl做了一次http请求,那么有请求就有超时时间,查看curl_setopt选项,发现提供了两个请求超时选项的设置。如果设置为0,则无限等待,默认值没说。两个选项的优先级也没说。不过这里可以通过设置CURLOPT_TIMEOUT来限制curl最长执行时间,最后解决问题。

CURLOPT_CONNECTTIMEOUT  在尝试连接时等待的秒数。设置为0,则无限等待
CURLOPT_TIMEOUT 允许 cURL 函数执行的最长秒数。

相关文章

网友评论

      本文标题:php中curl未设置超时导致的睡眠进程问题

      本文链接:https://www.haomeiwen.com/subject/maumihtx.html