好多系统中会用到邮件系统,咱们假设有一个 PHP 脚本用来发送邮件。使用 Linux cron 每分钟执行一次php
咱们暂时不引入队列系统,其实使用队列处理此方式更优。shell
咱们获得下面的基本配置bash
* * * * * php /home/app/email.php
复制代码
假设因为未知因素, email.php
脚本一直执行,没有退出。极端的状况,进入一个 while 死循环。app
这下倒好,原来讲好的一分钟执行一次,如今一直死这边了,后面的脚本也不能跑了测试
解决办法:ui
使用 timeout,假设咱们设定每一个脚本最多执行时间位 200秒,超过 200秒 就自动死掉。this
* * * * * timeout 200 php /home/app/email.php
复制代码
php email.php
,若是避免重复执行?这样会出现,有两个进程同时在执行 php email.php
,那会不会出现同一个任务被执行了两次?spa
解决办法:日志
使用 flock 进行互斥控制code
用法:
flock [选项] <文件|目录> <命令> [<参数>...]
flock [选项] <文件|目录> -c <命令>
flock [选项] <文件描述符号码>
经过 shell 脚本管理文件锁。
选项:
-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/test.lock -c "timeout 200 php /home/app/email.php"
复制代码
定时任务可能要记录日志呀,否则后期怎么排查
* * * * * flock -xn /tmp/test.lock -c "timeout 200 php /home/app/email.php >> /home/log/test.log 2>&1"
复制代码
* * * * * flock -xn /tmp/test.lock -c "timeout 200 php /home/app/email.php >> /home/log/test.log 2>&1"
复制代码
我以为一分钟一次频率过低,想 10s 执行一次怎么办?
* * * * * php /home/app/email.php >> /home/log/test.log 2>&1
* * * * * ( sleep 10 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 20 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 30 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 40 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 50 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
复制代码
准备一个 php 脚本 /home/rovast/Code/flock/test.php
<?php
$i = 10000;
while ($i > 0) {
echo --$i . \PHP_EOL;
sleep(1);
}
复制代码
执行
flock -xn /tmp/mytest.lock -c "timeout 30 php /home/rovast/Code/flock/test.php"
复制代码
咱们看到终端不停输出数值
9999
9998
9997
9996
9995
9994
9993
9992
9991
9990
复制代码
咱们再打开另一个终端,执行
flock -xn /tmp/mytest.lock -c "timeout 30 php /home/rovast/Code/flock/test.php"
复制代码
咱们发现: