<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                Crontab Linux/UNIX 系統上最常用 的計劃任務 理工具 PHP 開發者在實際項目中 會經常使用到該工具。不過受限于實際的項目部署應用環境, Crontab 置信息的編輯多 由專門的服務器維護人員操作,項目使用者想要自行添加和編輯,流程較為煩瑣。 本章將會基于內容管理框架,開發 個可視化的 Crontab 計劃任務管理模塊,極大地 方便了開發者和用戶的使用。 # 1 常見計劃任務實現萬法 在實際開發中,經常會遇見有計劃任務需求的場景,如創建但未支付的訂單,或失敗 需要退款的商品等,這些都需要定時執行某些操作。類似的場景還有許多。本節主要講解 常見的幾種計劃任務的實現方法。 ## 1.1 PHP 腳本實現計劃任務 因為 PHP 腳本是基于瀏覽器運行的,在關閉瀏覽器后程序會自動終止,同時程序執 行的最大時間默認為 秒,所以要讓 PHP 腳本實現計劃任務,就需要一個或多個腳本, 不依賴瀏覽器的動作而可以一直執行。下面給出常見方法。 - 腳本執行時間限制:使用 PHP 內置的 set_time_limit()方法可以實現讓腳本持續執行。 - 瀏覽器關閉,程序不終止:使用 PHP 內置的 ignore_user_ abort()方法,可以讓腳本在關閉瀏覽器的情況下可以繼續執行。 - 腳本定時執行 為了不讓 PHP 提前結束進程,使用語言內置的無限循環結構和 sleep()等待方法可以讓腳本定時執行,如 5秒執行1次。 這里給出一個簡單的腳本實例,演示 PHP 計劃任務的實現過程。新建 task.php 本文 件,實現代碼如下: ```php <?php ignore_user_abort(); //關閉瀏覽器 PHP 腳本也可以繼續執行 set_time_limit(0); //通過 set me limit (0 )可以讓程序無限制地執行下去 $interval = 3 ; //每隔3秒運行 $number = 0; //計數器 //無限循環 do{ ($number < 10) { //執行 次文件寫入操作 //定時寫入文件 file_put_contents( _DIR_.'/log/log'.date('Ymd_His').'.log',time()) ; $number =$number+1 ; sleep($interval); //延時執行 }while(true) ; ``` 在上述代碼中,實現了循環內的代碼每 秒執行 次, 共執行 10 次的計劃任務(新 log 文件) 。注意腳本頭文件中定義的兩個系統方法,代碼如下: ```php ignore_user_abort(); //關閉瀏覽器 PHP 腳本也可以繼續執行 set_time_limit(0); //通過 set me limit (0 )可以讓程序無限制地執行下去 ``` 在瀏覽器中訪問 task .php 腳本,可以發現在 lo 目錄下,會自動新增 10 log 文件, 不過使用這種方式,若更新了 PHP 文件內容,需要 重啟PHP進程才可以使計劃任務 生效。 此外, 若出現程序錯誤或者內存溢出, PHP 當前運行的進程也會被終止,故使用這 種方式具有極大的不穩定性,維護起來并不方便。 ## 1.2 使用系統級別的計劃任務工具 既然使用 PHP 腳本實現計劃任務,在一些方面不是很理想,那么借助外部的工具就 是更好的選擇。無論是windows 還是 Linux 操作系統,都有完 的計劃任務解決方案 如在 Windows 10 中, 在控制面板中,就可以直接找到任務計劃程序井管理計劃任務,使 用起來較為簡單, 不過基于 PHP 項目, 一般部署在windows 服務器上的較少,故 PHP 開發者最常用 的還是 Linux系統中的 Crontab 計劃任務命令工具 為了方便演示,這里使用 vagrant 工具, 在本地搭建 Ubun 的虛擬機系統,登錄成功后 執行以下命令查看 Crontab 幫助信息。 ```bash crontab -h ``` 結果如下 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20210320040711542.png) 也可以執行以下命令,查看管理員用戶( root )有哪些計 任務。 ```bash crontab -l ``` 執行結果如下 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20210320040803601.png) 其實無論使用哪個計劃任務工具,都是為了實現在特定的時間執行某項任務這樣的功 # 2.Crontab 入門 Linux 上的 Crontab 計劃任務工具 沒有可視化的交互界面 配置與使用該工具都需 要在 令行 作, 本節主要講解 Cron tab 工具的 些入 操作。 ## 2.1 Crontab 使用教程 在講之前之前, 需要先了解 Cron 和 Crontab 的區別。經常使用到的 Crontab 命令 是Cron和 Table 合體的簡寫 它其實是 Cron 配置文件,也可以 作業列 開發者可 以在 定義不同的時間表達式 實現不同的任務需求。 而 Cron是Linux 系統進程,Cron 搭配 Shell 腳本,就可以執行特定的計劃任務。 以ubun 16.04 為例 Cron tab 在系統中多個地方都有配置文件。 - /var/spool/cron/crontabs:該目錄下存放的是每個用戶的 Crontab ,配置文件的 與用戶名一 致。 - /etc/cron.d/: 存放需要執行的 Crontab 文件或腳本。 - /etc/cron.hourly、 /etc/cron.daily 、/etc/cron.weekly 、/etc/cron。monthly:這些目錄中的腳本,可以以每小時、每天、每星期和每月為單位執行1次。 常用的命 明如下: `crontab [- u username)` //省略用戶表表示操作當前用戶的 Cron tab - e 編輯任務列表) - 1 列出任務列表里的命令) - r 刪除任務列表) Crontab 的命令構成為 時間表達式+操作符+操作命令。時間表達式的構成有分、時、 日、月、周 5種, 操作符有以下幾種: *:取值范圍內的所有數字 /:每過多少個數字 -:從x到z .:散列數字 例如:每分鐘執行一次命令 `showtima` 實例如下: `* * * * * showtima` 每天 30 執行某個 PHP 腳本文件 示例如下 ```bash 30 23 * * * /usr/bin/php7.0 /var/www/task.php ``` 時間表達式的 義非常靈活 不過若不經常使用,極易導致配置 這里 推薦使用 在線的 Crontab 式生成器 ,根據需求進行定制。訪問地址為:http://www pppet.net 訪問后使用效果 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20210320042232621.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmd6aGFl,size_16,color_FFFFFF,t_70) ## 2.2 Crontab 實現 PHP 文件定時寫入 為了方便演示,這里實現1個每分鐘寫入文件日期的功能 首先在系統的/var/www (Ubun 虛擬機環境)目錄下,新增 log.php 文件 體代碼如下 ```php <?php file_put_contents(__DIR__.'/run.log',date("Y-m-d H:i:s")."\r\n",FILE_APPEND); ?> ``` 此腳本每次執行,都會生成 個帶有當前時間信息的文件,以便區分文件是何時創建 隨后執行以下命令,給當前用戶增加 Cronta 表達式,指定何時執行 log.php 腳本 ```bash crontab -e ``` 增加以下內容: ```bash * * * * * /use/bin/php7.0 /var/www/log.php ``` 保存后等待幾分鐘,發現在/var/www 目錄下,自動生成了 run.log 文件,使用 cat 令查看,內 容如下 root@scotchbox:/var/www# cat run.log 2018-01-03 16:01:01 2018-03-03 16:02:01 2018-03-03 16:03:02 根據 Crontab 中配置的時間任務表達式,log.php腳本每隔一分鐘都會被執行一次,而 此時修改腳本文件,則不需要重啟 PHP 進程,修改的代碼如下: ```php <?php file_put_contents(__DIR__.'/run.log',"time:".date("Y-m-d H:i:s")."\r\n",FILE_APPEND); ?> ``` 經過幾分鐘的等待,再次查看 ru log 文件,發現己經寫入了新的格式內容 2018-01-03 16:01:01 2018-03-03 16:02:01 2018-03-03 16:03:02 2018-01-03 16:04:01 time:2018 01-03 16 : 05 : 01 通過對日志列表細心觀 可以發現, Crontab 在執行的時候,默認最小單位為“分”, 并且會從第1 秒(根據配置文件編輯的時間,誤差在2秒內)開始執行。開發者還可以通 過使用 sleep 關鍵字定義在哪1秒執行,修改時間表達式如下: ```bash * * * * * sleep 20; /use/bin/php7.0 /var/www/log.php ``` sleep 后面的參數 20 指的就是延遲多少秒執行, 等待幾分鐘后,再次查看 run.log 文件, 發現文件寫入的時間發生了變化: 2018-03-03 16:03:02 2018-01-03 16:04:01 time:2018 01-03 16:05:01 time:2018 01-03 16:06:01 time:2018 01-03 16:07:01 time:2018 01-03 16:08: 01 time:2018 01-03 16:10: 21 time:2018 01-03 16:11: 21 # 奇奇怪怪的知識 完成計劃任務顯示列表管理的開發后,用戶就可以 自行定義需要的任務內容了,不過想 要自動運行,還需要 個自動執行任 的腳本,用來理這些任務。其實 步驟如下。 **1. 安裝第三方依賴類庫** 為了提升開發效率,這里主要安裝兩個依賴類庫,用來解析 Cro tab 表達式和發送 HTTP 請求。在項目的根目錄下,安裝 mtdowling/cron- expression 的命令如下: ```bash composer require mtdowling/cron- expression ``` 為了更好地獲取請求 URL 地址的 HTTP 回值 安裝使用 rmccue/requests 的命令 如下 ```bash composer require rmccue/requests ``` **2.開發核心任務腳本** 為了更好地管理代碼,在項目 application 目錄下,新增 crontab 應用模塊,在此模塊 下的 controller 目錄下,新增 Crontask.php 控制器文件,在此文件內開發任務執行腳本, 其步驟如下。 **(1)新增初始化方法。為了防止誤操作 ,此腳本只能在命令行下操作,在 Crontask 控制器文件中,增加以下代碼** ```php /* *初始化配置列表 @var array */ private $_config = [] ; /* *初始化方法 */ public function _initialize(} { parent::_initialize(); config('app_trace', false) ; //關閉app_trace //只可以以 cli 方式執行 if(!$this->request- >isCli()){ $this->error("計劃任務必須在命令行中執行"); } //初始化狀態 $this->_config=[ 'DELETE'=>-1,//己經刪除 'DISABLED'=>0,//禁用 'NORMAL'=>1,//正常 'COMPLETED'=>2,//完成 'EXPIRED'=>3,//過期 ] } ``` 為了腳本穩定地執行,代碼強制關閉了框架自帶的 Trace 輸出模式,并禁止在非命令 行模式下運行此腳本的任何方法。其代碼如下: ```php config('app_trace', false) ; //關閉app_trace if(!$this->request- >isCli()){ $this->error("計劃任務必須在命令行中執行"); } ``` **(2)實現任務管理核心方法。在控制器新增index()方法,增加以下代碼** ```php /** *定時任務執行方法 *@return bool **/ public function index(){ //查詢所有的任務列表 $map['status']= ['>', 0]; $crontab_list = Db::name("crontab ")->where ($map)->select(); if(!$crontab_list){ return false; } $now_time =time(); foreach($crontab_list as $key =>$cromtab){ $is_execute = false ; //是否執行 $update =[];//需要更新的數據 if($now_time<$cromtab["begin_time"]){ continue;//任務沒開始跳過 } if($cromtab["maximums"] &&$cromtab["executes"]>=$cromtab["maximums"]){ $update["status "]=$this->config["COMPLETED"];// 任務超過最大執行次數 任務完成 }elseif($cromtab["end_time"] >0 && $now_time> $cromtab["end_time"] ){ $update["status "]=$this->config["EXPIRED"];// 任務過期 }else{ //創建計劃任務對象并傳入時 表達式 $cron = CronExpression::factory($crontab[' schedule']); if($cron->isDue()){ //允許執行 $is_execute = true ; //允許執行的時候更新狀態 $update["execute_time"]= $now_time; $update["update_time"]= $now_time; $update["executes"]=$crontab["executes"]+ 1; $update["status "]= ($crontab["maximums "]>0 &&$update["executes"]>=$update["maximums "]?$this->config["COMPLETED"]:$this->config["NORMAL"]; )else{ //如果未到 行時間 跳過本任務去判斷下一個任務 continue; } } $map= [] ; $map["id"]= $crontab["id"]; Db::name("crontab")-> where($map)->update($update); //通過標志位來判斷是否滿足執行條件(任務是否開始、是否未達到規定次數等)最終決定執行任務還是只更新任務狀態 if(!$is_execute){ continue; }else{ //執行計劃任務操作 try{ //判斷任務類型 switch($crontab['type']){ //請求 URL case "url" if(substr($crontab["content"] ,0,1)=="/"){ //本地url $request = shell_exec("php".__ROOT_PATH__."index.php".$crontab["content"]."2>&1"); //修改日志 }else{ //遠程 URL使用curl請求 //修改日志 } break; case "shell" $request = shell_exec($crontab["content"]."2>&1"); //修改日志 break; } }catch(\Execeptionm $e){ ////記錄異常 } } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看