我有一个产品数据库,可以在早上与产品数据同步.
这个过程非常清楚:
如果我查询少量的项目,但将其限制为500个随机产品,一切都很顺利.但是当我查询所有产品时,我的脚本SOMETIMES继续使用fritz并开始多次循环.几个小时后,我仍然看到我的日志文件在增长,产品正在增加.
我查看了我能想到的一切,例如:
使其特别奇怪的原因是它有时是正确的,有时它不会.这可能是一些记忆问题吗?
编辑
wget -q -O /dev/null http://example.eu/xxxxx/cron.php?operation=sync它在webmin中调用特定的小时和分钟
代码长达数百行......
谢谢
你有:
完成500条记录没有问题.这表明脚本在下一次cronjob迭代之前完成其过程.例如,如果您的cron每小时运行一次,则会在不到一小时的时间内处理500条记录.
如果您有一个将要处理大量记录的cronjob,那么请考虑向该进程添加锁定机制.仅允许脚本运行一次,并在上一个过程完成时重新启动.
在执行php脚本之前,您可以将脚本锁创建为shell脚本的一部分.或者,如果您无法访问服务器,则可以在php脚本中使用数据库锁定,如下所示.
class ProductCronJob
{
protected $lockValue;
public function run()
{
// Obtain a lock
if ($this->obtainLock()) {
// Run your script if you have valid lock
$this->syncProducts();
// Release the lock on complete
$this->releaseLock();
}
}
protected function syncProducts()
{
// your long running script
}
protected function obtainLock()
{
$time = new \DateTime;
$timestamp = $time->getTimestamp();
$this->lockValue = $timestamp . '_syncProducts';
$db = JFactory::getDbo();
$lock = [
'lock' => $this->lockValue,
'timemodified' => $timestamp
];
// lock = '0' indicate that the cronjob is not active.
// Update #__cronlock set lock = '', timemodified = '' where name = 'syncProducts' and lock = '0'
// $result = $db->updateObject('#__cronlock', $lock, 'id');
// $lock = SELECT * FROM #__cronlock where name = 'syncProducts';
if ($lock !== false && (string)$lock !== (string)$this->lockValue) {
// Currently there is an active process - can't start a new one
return false;
// You can return false as above or add extra logic as below
// Check the current lock age - how long its been running for
// $diff = $timestamp - $lock['timemodified'];
// if ($diff >= 25200) {
// // The current script is active for 7 hours.
// // You can change 25200 to any number of seconds you want.
// // Here you can send notification email to site administrator.
// // ...
// }
}
return true;
}
protected function releaseLock()
{
// Update #__cronlock set lock = '0' where name = 'syncProducts'
}
}
Run Code Online (Sandbox Code Playgroud)
你的脚本运行了相当长的时间(约45米)并且因为你没有返回任何数据而认为它是"超时".默认情况下,wget将具有900s的超时值和20的重试次数.因此,首先您应该更改wget命令以防止这种情况:
wget --tries = 0 --timeout = 0 -q -O/dev/null http://example.eu/xxxxx/cron.php?operation=sync
现在删除超时可能会导致其他问题,因此您可以发送(并刷新以强制Web服务器发送它)来自脚本的数据,以确保wget不认为脚本"超时",每1000个循环或某事像那样.把它想象成一个进度条......
请记住,当运行时间接近您的时间段时,您将遇到问题,因为2个crons将并行运行.你应该优化你的过程和/或有锁机制吗?
我自己解决了这个问题。感谢所有的答复!
我的 MySQL 超时,这就是问题所在。我一添加:
ini_set('mysql.connect_timeout', 14400);
ini_set('default_socket_timeout', 14400);
Run Code Online (Sandbox Code Playgroud)
对于我的脚本,问题停止了。我真的希望这对某人有帮助。我会投票支持所有锁定答案,因为这些答案非常有帮助!
| 归档时间: |
|
| 查看次数: |
1699 次 |
| 最近记录: |