Linux定时任务_重庆幸运农场开到晚上几点

时间:2016-04-15 10:04来源:未知 作者:Linux先生 举报 点击:
PHP本身是没有定时功能的,PHP也不能多线程。PHP的定时任务功能必须通过和其他工具结合才能实现,例如WordPress内置了wp-cron的功能,很厉害。

本文地址:http://www.kooct.com/install/faq/20160412_how_linux_5230.html
文章摘要:Linux定时任务,周延有例可援授精,脑溢血减产天假之年。

PHP本身是没有定时功能的,PHP也不能多线程。PHP的定时任务功能必须通过和其他工具结合才能实现,例如WordPress内置了wp-cron的功能,很厉害。本文,我们就来深入的解析几种常见的php定时任务的思路。

Linux服务器上使用CronTab定时执行php

我们先从相对比较复杂的服务器执行php谈起。服务器上安装了php,就可以执行php文件,无论是否安装了nginx或Apache这样的服务器环境软件。而Linux中,使用命令行,用CronTab来定时任务,又是绝佳的选择,而且也是效率最高的选择。

首先,进入命令行模式。作为服务器的linux一般都默认进入命令行模式的,当然,我们管理服务器也一般通过putty等工具远程连接到服务器,为了方便,我们用root用户登录。在命令行中键入:

crontab -e 

之后就会打开一个文件,并且是非编辑状态,则是vi的编辑界面,通过敲键盘上的i,进入编辑模式,就可以编辑内容。这个文件中的每一行就是一个定时 任务,我们新建一行,就是新建一条定时任务(当然是指这一行内按照一定的格式进行书写)。我们现在来举个例子,增加一行,内容如下:

00 * * * * lynx -dump http://www.kooct.com/163/script.php 

这是什么意思呢?实际上上面这一行由两部分组成,前面一部分是时间,后面一部分是操作内容。例如上面这个,

00 * * * * 

就是指当当前时间的分钟数为00时,执行该定时任务。时间部分由5个时间参数组成,分别是:

分 时 日 月 周 
第1列表示分钟1~59 
每分钟用_或者 */1表示,_/n表示每n分钟,
例如*/8就是每8分钟的意思,
下面也是类推  
第2列表示小时1~23(0表示0点)  
第3列表示日期1~31  
第4列表示月份1~12  
第5列标识号星期0~6(0表示星期天)

整个句子的后面部分就是操作的具体内容。

lynx -dump http://www.kooct.com/682/script.php 

意思就是说通过lynx访问这个url。我们在使用中主要用到lynx、curl、wget来实现对url的远程访问,而如果要提高效率,直接用php去执行本地php文件是最佳选择,例如:

00 */2 * * * /usr/local/bin/php /home/www/script.php 

这条语句就可以在每2小时的0分钟,通过linux内部php环境执行script.php,注意,这里可不是通过url访问,通过服务器环境来执行哦,而是直接执行
,因为绕过了服务器环境,所以效率当然要高很多。

好了,已经添加了几条需要的定时任务了吧。点击键盘上的Esc键,输入“:wq”回车,这样就保存了设置的定时任务,屏幕上也能看到提示创建了新的定时任务。接下来就是好好写你的script.php了。

关于CronTab的更多用法这里就不介绍了,如果你想更灵活的使用这个定时任务功能,应该自己再去深入学习一下crontab。

Windows服务器上使用bat定时执行php

windows上和linux上有一个类似的cmd和bat文件,bat文件类似于shell文件,执行这个bat文件,就相当于依次执行里面的命 令(当然,还可以通过逻辑来实现编程),所以,我们可以利用bat命令文件在windows服务器上面实现PHP定时任务。实际上在windows上定时 任务,和linux上道理是一样的,只不过方法和途径不同。好了下面开始。

首先,在一个你觉得比较适当的位置创建一个cron.bat文件,然后用文本编辑器打开它(记事本都可以),在里面写上这样的内容:

D:\php\php.exe -q D:\website\test.php 

这句话的意思就是,使用php.exe去执行test.php这个php文件,和上面的contab一样,绕过了服务器环境,执行效率也比较高。写好之后,点击保存,
关闭编辑器。

接下来就是设置定时任务来运行cron.bat。依次打开:“开始–>控制面板–>任务计划–>添加任务计划”,在打开的界面中设置定时任务的时间、密码,通过选择,
把cron.bat挂载进去。确定,这样一个定时任务就建立好了,在这个定时任务上右键,运行,这个定时任务就开始执行了,到点时,就会运行cron.bat处理,c
ron.bat再去执行php。

非自有服务器(虚拟主机)上实现php定时任务

如果站长没有自己的服务器,而是租用虚拟主机,就无法进入服务器系统进行上述操作。这个时候应该如何进行php定时任务呢?其实方法又有多个。

使用ignore_user_abort(true)和sleep死循环

在一个php文档的开头直接来一句:

ignore_user_abort(true); 

这时,通过url访问这个php的时候,即使用户把浏览器关掉(断开连接),php也会在服务器上继续执行。利用这个特性,我们可以实现非常牛的功能,也就是通过它来
实现定时任务的激活,激活之后就随便它自己怎么办了,实际上就有点类似于后台任务。

而sleep(n)则是指当程序执行到这里时,暂时不往下执行,而是休息n秒钟。如果你访问这个php,就会发现页面起码要加载n秒钟。实际上,这种长时间等待的行为
是比较消耗资源的,不能大量使用。

那么定时任务到底怎么实现呢?使用下面的代码即可实现:

<?php
ignore_user_abort(true);
set_time_limit(0);
date_default_timezone_set('PRC'); 
// 切换到中国的时间
  $run_time = strtotime('+1 day');
 // 定时任务第一次执行的时间是明天的这个时候
 $interval = 3600*12;
 // 每12个小时执行一次
  if(!file_exists(dirname(__FILE__).'/cron-run')) exit();
 // 在目录下存放一个cron-run文件,如果这个文件不存在,说明已经在执行过程中了,该任务就不能再激活,执行第二次,否则这个文件被多次访问的话,服务器就要崩溃掉了
  do {   if(!file_exists(dirname(__FILE__).'/cron-switch')) break;
 // 如果不存在cron-switch这个文件,就停止执行,这是一个开关的作用
   $gmt_time = microtime(true);
// 当前的运行时间,精确到0.0001秒
   $loop = isset($loop) && $loop ? $loop : $run_time - $gmt_time;
 // 这里处理是为了确定还要等多久才开始第一次执行任务,$loop就是要等多久才执行的时间间隔
   $loop = $loop > 0 ? $loop : 0;   if(!$loop) break;
// 如果循环的间隔为零,则停止
   sleep($loop);    // ...
   // 执行某些代码
   @unlink(dirname(__FILE__).'/cron-run');
 // 这里就是通过删除cron-run来告诉程序,这个定时任务已经在执行过程中,不能再执行一个新的同样的任务
   $loop = $interval; 
} while(true); 

通过执行上面这段php代码,即可实现定时任务,直到你删除cron-switch文件,这个任务才会停止。

但是有一个问题,也就是如果用户直接访问这个php,实际上没有任何作用,页面也会停在这个地方,一直处于加载状态,有没有一种办法可以消除这种影响呢?fsocko
pen帮我们解决了这个问题。

fsockopen可以实现在请求访问某个文件时,不必获得返回结果就继续往下执行程序,这是和curl通常用法不一样的地方,我们在使用curl访问网页时,一定要
等curl加载完网页后,才会执行curl后面的代码,虽然实际上curl也可以实现“非阻塞式”的请求,但是比fsockopen复杂的多,所以我们优先选择fso
ckopen,fsockopen可以在规定的时间内,比如1秒钟以内,完成对访问路径发出请求,完成之后就不管这个路径是否返回内容了,它的任务就到这里结束,可以
继续往下执行程序了。利用这个特性,我们在正常的程序流中加入fsockopen,对上面我们创建的这个定时任务php的地址发出请求,即可让定时任务在后台执行。如
果上面这个php的url地址是www.yourdomain.com/script.php,那么我们在编程中,可以这样:

    // ... // 正常的php执行程序 // ..  // 远程请求(不获取内容)函数,下面可以反复使用 
function _sock($url)
{
    $host = parse_url($url, PHP_URL_HOST);
    $port = parse_url($url, PHP_URL_PORT);
    $port = $port ? $port : 80;
    $scheme = parse_url($url, PHP_URL_SCHEME);
    $path = parse_url($url, PHP_URL_PATH);
    $query = parse_url($url, PHP_URL_QUERY);
    if ( $query ) $path .= '?' . $query;
    if ( $scheme == 'http' ) {
        $host = 'ssl://' . $host;
    }
    $fp = fsockopen($host, $port, $error_code, $error_msg, 1);
    if ( !$fp ) {
        return array('error_code' => $error_code, 'error_msg' => $error_msg);
    } else {
        stream_set_blocking($fp, true);//开启了手册上说的非阻塞模式
        stream_set_timeout($fp,1);
        //设置超时
        $header = "GET $path HTTP/1.1\r\n";     
        $header.="Host: $host\r\n";     
        $header.="Connection: close\r\n\r\n";
        //长连接关闭
        fwrite($fp, $header);     
        usleep(1000); 
        // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
        fclose($fp);
        return array('error_code' => 0);   
    } }  
    _sock('www.yourdomain.com/script.php'); 
     // ... // 继续执行其他动作 // .. 

把这段代码加入到某个定时任务提交结果程序中,在设置好时间后,提交,然后执行上面这个代码,就可以激活该定时任务,而且对于提交的这个用户而言,没有任何页面上的堵
塞感。

借用用户的访问行为来执行某些延迟任务

但是上面使用sleep来实现定时任务,是效率很低的一种方案。我们希望不要使用这种方式来执行,这样的话就可以解决效率问题。我们借用用户访问行为来执行任务。用户
对网站的访问其实是一个非常丰富的行为资源,包括搜索引擎蜘蛛对网站的访问,都可以算作这个类型。在用户访问网站时,内部加一个动作,去检查任务列表中是否存在没有被
执行的任务,如果存在,就将这个任务执行。对于用户而言,利用上面所说的fsockopen,根本感觉不到自己的访问竟然还做出了这样的贡献。但是这种访问的缺点就是
访问很不规律,比如你希望在凌晨2点执行某项任务,但是这个时间段非常倒霉,没有用户或任何行为到达你的网站,直到早上6点才有一个新访问。这就导致你原本打算2点执
行的任务,到6点才被执行。

这里涉及到一个定时任务列表,也就是说你需要有一个列表来记录所有任务的时间、执行什么内容。一般来说,很多系统会采用数据库来记录这些任务列表,比如wordpress就是这样做的。我则利用文件读写特性,提供了托管在github上的开源项目php-cron,你可以去看看。总之,如果你想要管理多个定时任务,靠上面的单个php是无法合理布局的,必须想办法构建一个schedules列表。由于这里面的逻辑比较复杂,就不再详细阐述,我们仅停留在思路层面上。

借用第三方定时任务跳板

很好玩的是,一些服务商提供了各种类型的定时任务,例如阿里云的ACE提供了单独的定时任务,你可以填写自己应用下的某个uri。百度云BCE提供 了服务器监测功能,每天会按照一定的时间规律访问应用下的固定uri。类似的第三方平台上还有很多定时任务可以用。你完全可以用这些第三方定时任务作为跳 板,为你的网站定时任务服务。比如说,你可以在阿里云ACE上建立一个每天凌晨2点的定时任务,执行的uri是/cron.php。

然后你创建cron.php,里面则采用fsockopen去访问你真正要执行某些任务的网站的url,例如上面的 www.yourdomain.com/script.php,而且在cron.php中还可以访问多个url。然后把cron.php上传到你的ACE 上面去,让ACE的定时任务去访问/cron.php,然后让cron.php去远程请求目标网站的定时任务脚本。

循环利用include包含文件(待验证)

php面向过程的特性使得其程序是从上往下执行的,利用这个特性,在我们使用include某个文件时,就会执行被引入的文件,知道include的文件内程序执行完
之后,再往下执行。如果我们创建一个循环,再利用sleep,不断的include某个文件,使循环执行某段程序,则可以达到定时执行的目的。我们再进一步,并不是利
用while(true)来实现循环,而是利用被include文件本身再include自身来实现循环,比如我们创建一个do.php,它的内容如下:

if(...) exit(); 
// 通过某个开关来关闭执行  // ...  // 执行某些程序 // ...  
sleep($loop); // 这个$loop在include('do.php');之前赋值  
include(dirname(__FILE__).'/do.php'); 

其实通过这种方法执行和while的思路也像。而且同样用到sleep,效率低。

PHP定时任务是一个非常有意思的东西,虽然说实话,用系统的php.exe去直接执行php文件的效率更高,但是对于很多普通站长而言,虚拟主机是无法做到直接ph
p执行原生程序的。本文仅提供一些解决的思路,我也仅仅是在学习中,有很多问题或表述都不正确,希望你指出来;你可以通过本文的思路,开发出自己的一种解决方案,希望你能将方案发布,并与我一起探讨。

推荐内容
幸运农场历史走势图 晚上打农场 幸运农场开奖结果走势 重庆时时彩 重庆幸运农场时间
重庆幸运农场总和 双色球胆拖计算器 幸运农场夜场好久开始 重庆幸运农场走势图一览 幸运农场万能4码
重庆机场大巴最晚几点 幸运飞艇杀码技巧 重庆幸运旅场开奖 x幸运农场 重庆幸运农场开奖走势
重庆幸运农场20选8 幸运农场包稳赚方法 幸运农场3全中多少钱 幸运农场20选8如何选号 幸运28计算公式
五张牌棋牌斗牛怎么玩 可怕人为控制的时时彩 重庆幸运农场官方网站 山西快乐10分开奖号码 棋牌10人斗牛游戏
天津快乐10分玩法 下载宁夏十一选五 河北快三开奖号码 重庆时时彩官方开奖 双色球开奖
新加坡快乐8 广西十一选五一定牛 21点游戏程序设计 高频11选5走势图河南 秒速时时彩开奖记录APP
双色球玩法介绍 幸运农场手机投注 新疆时时彩三星和值图 王中王铁算盘开奖结果 湖南幸运赛车奖金查询