php /root/php/cron.php
问题:如果这脚本涌现非常,进程僵去世怎么办?
假设由于未知成分,cron.php 脚本一贯实行,没有退出。极度情形,进入一个去世循环。原来说好的一分钟实行一次,现在后面的脚本也不能跑了。
办理办法:利用timeout设置脚本实行超时时间
(图片来自网络侵删)
timeout 120 php /root/php/cron.php >> /root/php/logs.log 2>&1
上面定时任务脚本最大实行韶光120秒,超过120秒之后进程就会退出,这样就可以办理僵去世的情形。
定时任务进程互斥问题:由于设置的定时任务是每分钟启动一次,在未来的某个时候就会涌现多个脚本进程在实行相同任务,此刻可能就会造成数据的不一致性等问题。那么,该怎么避免呢?
办理办法:利用 flock 设置文件锁来进行互斥掌握。
用法:flock [选项] <文件|目录> <命令> [<参数>...]flock [选项] <文件|目录> -c <命令>flock [选项] <文件描述符号码>参数选项: -s, --shared 获取共享锁 -x, --exclusive 获取排他锁(默认) -u, --unlock 移除锁 -n, --nonblock 被其他做事锁住的时候返回失落败而非等待 -w, --timeout <秒> 等待限定的韶光 -E, --conflict-exit-code <数字> 冲突或超时后的退出代码 -o, --close 运行命令前关闭文件描述符 -c, --command <命令> 通过 shell 运行单个命令字符串 -F, --no-fork 实行命令时不 fork --verbose 增加详尽程度 -h, --help display this help -V, --version display version
文件锁互斥参数为 flock -xn, 同时设置互斥文件 /tmp/cron1.lock。
flock -xn /tmp/cron1.lock -c "timeout 120 php /root/php/cron.php"
为了方便排查,把输出数据追加到指定日志文件中。
flock -xn /tmp/cron1.lock -c "timeout 120 php /root/php/cron.php >> /root/php/logs.log 2>&1"
定时任务实行频率提升问题:以为一分钟启动一次频率太低,想10s启动一次怎么办?
办理办法:添加多个相同定时任务,每个定时任务sleep指定时间之后实行。
php /home/app/email.php >> /home/log/test.log 2>&1 ( sleep 10 ; php /root/php/cron.php >> /root/php/logs.log 2>&1 ) ( sleep 20 ; php /root/php/cron.php >> /root/php/logs.log 2>&1 ) ( sleep 30 ; php /root/php/cron.php >> /root/php/logs.log 2>&1 ) ( sleep 40 ; php /root/php/cron.php >> /root/php/logs.log 2>&1 ) ( sleep 50 ; php /root/php/cron.php >> /root/php/logs.log 2>&1 )
定时任务互斥及超时验证用于测试的php脚本
<?php$i = 10000;while ($i > 0) { echo --$i . \PHP_EOL; sleep(1);}
添加crontab定时任务
flock -xn /tmp/cron1.lock -c "timeout 120 php /root/php/cron.php >> /root/php/logs.log 2>&1"
查看日志文件/root/php/logs.log创造会有数值一直输出,120秒旁边之后数值停息输出。此时利用ps -aux | grep php查看没有创造定时任务干系的进程信息,解释timeout 120起到了浸染。然后,等待多少秒,等下一分钟的第一秒到达时,会创造数值又开始输出,也可以看到对应的定时任务进程信息,如此往来来往。
99999998999799969995....
定时任务实行期间,若再打开其余一个终端,手动在命令行实行:
flock -xn /tmp/cron1.lock -c "timeout 120 php /root/php/cron.php >> /root/php/logs.log 2>&1"
结果:① 命令行实行命令由于没有得到锁,直接退出(由于 flock 互斥)② 定时任务实行120 秒后自动由于超时退出进程(由于 timeout 120),此时再手动在命令行实行则可以成功