CRON定时任务
在linux下执行定期任务可以使用crontab,目前mac os也可以使用它,不过已不推荐使用。推荐做法是采用plist脚本,plist脚本可以设置执行的动作,时间间隔等其他一些信息。另外crontab的最小时间间隔是一分钟,使用plist脚本原则上时间间隔可以为一秒。定时任务每月一号跑10万条数据。如果按照每5分钟跑一次配置任务,数据跑完了后空跑脚本,造成性能的浪费。最好的方法每月1号跑一..
在linux下执行定期任务可以使用crontab,目前mac os也可以使用它,不过已不推荐使用。推荐做法是采用plist脚本,plist脚本可以设置执行的动作,时间间隔等其他一些信息。另外crontab的最小时间间隔是一分钟,使用plist脚本原则上时间间隔可以为一秒。
定时任务拉取数据原则:拉取当前系统时间之前5分中之前的数据
定时任务每月一号跑10万条数据。如果按照每5分钟跑一次配置任务,数据跑完了后空跑脚本,造成性能的浪费。最好的方法每月1号跑一次,因为定时任务机制不会超时php-cli,每次操作300条数据,可以在任务内部循环do..while实现
public function myCronJob() {
$page = 1;
do {
$workParking = $listParkingTmp['data']['list'];
$page++;
} while ($workParking);
}
PHP版的定时任务
<?php
$a = time();
ignore_user_abort(); //关掉浏览器,PHP脚本也可以继续执行.
set_time_limit(3000); // 通过set_time_limit(0)可以让程序无限制的执行下去
$interval = 5; // 每隔5s运行
do {
sleep($interval);
//查询订单接口
echo $i . "---" . (time() - $a) . "<br/>";
$paid_list = $order_logic->getCallBackList($order_id);
} while (empty($paid_list));
?>
Mac PLIST
plist脚本存放路径为/Library/LaunchDaemons或/Library/LaunchAgents,其区别是后一个路径的脚本当用户登陆系统后才会被执行,前一个只要系统启动了,哪怕用户不登陆系统也会被执行。
可以通过两种方式来设置脚本的执行时间。一个是使用StartInterval,它指定脚本每间隔多长时间(单位:秒)执行一次;另外一个使用 StartCalendarInterval,它可以指定脚本在多少分钟、小时、天、星期几、月时间上执行,类似如crontab的中的设置。
一个简单例子如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.yangyz.cron.test.plist</string>
<key>ProgramArguments</key>
<array>
<string>/Users/yangyz/plist-test.sh</string>
</array>
<key>KeepAlive</key>
<false/>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>
其中key是plist脚本定义的属性,紧跟着的下一行是该属性对应的值。上述脚本是每间隔60秒执行一次/Users/yangyz/plist- test.sh这个shell脚本,也可以使用StartCalendarInterval来替换StartInterval达到同样的效果,例如:
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>0</integer>
</dict>
上述设置的意思为每天的每个小时的第0分钟执行,也即使每60秒执行一次。plist脚本中定义的属性以及具体的含义,可以参看苹果官方网站的说明
launchctl命令可以控制plist脚本停止或重新加载。例如:
#停止脚本com.yangyz.cron.test.plist运行
launchctl unload /Library/LaunchDaemons/com.yangyz.cron.test.plist
#启动脚本com.yangyz.cron.test.plist运行
launchctl load /Library/LaunchDaemons/com.yangyz.cron.test.plist
如果执行上面命令看到launchctl: Dubious ownership on file (skipping): /Library/LaunchDaemons/com.yangyz.cron.test.plist这样的错误,其原因是该脚本的owner和当前执 行操作用户不一致。使用chown修改一下即可
Linux crontab
Linux crontab定时执行任务 命令格式与详细例子,大家可以参考下
# Example of job definition:
# .---------------- 分钟 (0 - 59)
# | .------------- 小时 (0 - 23)
# | | .---------- 一个月中的第几天 (1 - 31)
# | | | .------- 月份 (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- 星期中星期几 (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
基本格式 :
* * * * * command
分 时 日 月 周 命令
- 第1列表示分钟1~59 每分钟用*或者 */1表示
- 第2列表示小时1~23(0表示0点)
- 第3列表示日期1~31
- 第4列表示月份1~12
- 第5列标识号星期0~6(0表示星期天)
- 第6列要运行的命令
crontab例子
* * * * * /bin/ls
每一分钟执行一次 /bin/ls:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
#上面的例子表示每月1、10、22日的4 : 45重启apache。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
#晚上11点到早上7点之间,每隔一小时重启apache
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache
比如说root查看自己的cron设置:crontab -u root -l
再例如,root想删除fred的cron设置:crontab -u fred -r
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e
修改/etc/crontab这种方法只有root用户能用,这种方法更加方便与直接直接给其他用户设置计划任务,而且还可以指定执行shell等等, crontab -e这种所有用户都可以使用,普通用户也只能为自己设置计划任务。然后自动写入/var/spool/cron/usename
在使用之前首先通过which php命令找到自己的php安装到了哪里,西面能用到,我的打印出来是/usr/local/php/bin/php
为了知道自己写的php到底有没有被调用,在php写了一个简单的文件写入函数,我将当前的时间写入到一个test.txt中,只要查看test.txt, 我就知道php是有没有调用,什么时候调用,这样就可以大致看出来,自己设置的调用时间是不是被正确执行了。
<?php
$fp = fopen("test.txt","a+");
fwrite($fp, date('Y-m-d H:i:s')."****"."\r\n");
fclose($fp);
?>
配置crontab:
* * * * * root php /var/www/html/iu-deployer/current/artisan schedule:run >> /var/logs/cron.log 2>&1
* * * * * root /bin/bash /var/www/html/a.sh >> /var/logs/sh.log 2>&1
然后保存退出
同步linux服务器系统时间
Linux服务器运行久时,系统时间就会存在一定的误差,一般情况下可以使用date命令进行时间设置,但在做数据库集群分片等操作时对多台机器的时间差是有要求的,此时就需要使用ntpdate进行时间同步
#同步linux服务器系统时间
*/5 * * * * ntpdate ntp1.aliyun.com >/dev/null 2>&1
关于定时任务的思考:每天统计1天的对账单定时脚本,当天的对账单不能做到及时数据,如果将定时任务做成每3分跑一次服务器压力又很大。解决方法:当有查询报表功能时,触发统计当天的统计业务逻辑即可
定时任务执行失败可能原因
在linux下用crontab启动定时sh脚本,放到crontab中死活没反应,这是可能的原因:
- 检查 crontab服务是否正常service crond status
- 看日志:cat /var/log/cron 或 /var/log/messages。
- 看日志完全没反应,没有脚本执行记录,crontab也是运行状态,这时可能的原因是编辑定时任务时带了中文空格。
- 要赋予执行权限,如 chmod +x xxx.sh 就是给xxx.sh这个脚本赋予执行权限。
- 还有一个原因可能脚本开头 #!/bin/bash 写错了或者少写了。
- crontab定时任务要写全路径,全路径!
- 检查脚本是否需要用到的变量
近期某服务器的crontab,每天未正常执行,检查日志发现大量报错,如下:
1.chage -l ${username}查看用户密码期限相关信息
chage -l root
-----------------------------------------
Last password change : Jun 29, 2016
Password expires : Sep 27, 2016
Password inactive : never
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 90
Number of days of warning before password expires : 7
2.修改Maximum number of days between password change期限至永久
chage -M 99999 root;
-----------------------------------------
Last password change : Aug 04, 2018
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : 7
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)