ThinkPHP6自定義命令行指令結合crontab實現定時任務

這是我參與8月更文挑戰的第5天,活動詳情查看:8月更文挑戰php

前言

定時任務在實際業務中常常用到,例如未支付訂單超時取消,定時清理日誌等。上一個項目是一個自動售貨機,須要調用物聯網設備,偶爾會有信號很差致使設備啓動信號發出以後,接收不到設備啓動信息,須要主動查詢設備啓動狀況,啓動成功將訂單標記成功,失敗的須要給用戶退款。shell

初期是作了一個http接口,經過crontab定時調用觸發,按期處理異常訂單,可是當訂單體量增大,任務執行時間增加,有時候會阻塞業務。後來改爲了php命令行執行,知足了業務需求。數組

1、crontab

crontab 是用來讓使用者在固定時間或固定間隔執行程序之用,也就是相似使用者的時程表。markdown

定義格式以下:app

minute hour day month week command
複製代碼
  • minute 分鐘,範圍0-59。
  • hour 小時,範圍0-23。
  • day 每個月幾號,範圍1-31。
  • month 月份,範圍1-12。
  • week 一週的第幾天,範圍0-7,0和7都是週日。
  • command 執行的命令。

minute5 表示每五分鐘執行一次 command;當值爲 * 表示每一個時間單位都執行一次;能夠用, 隔開多個值,例如2,5,10 表示設定時間內的2分,5分,10分執行命令;能夠用- 隔開兩個值,例如10-20 設定時間內的第10分開始到20分結束每分鐘執行一次命令;*/15表示每15分鐘執行一次命令。其他單位設置方式相同。composer

舉例:post

  • 天天上午10點-12點,每半個小時執行一次命令測試

    */30 10-12 * * *
    複製代碼
  • 每一年的5月1日和10月1日凌晨2點執行一次命令ui

    0 2 1 5,10 *
    複製代碼

2、ThinkPHP命令行指令

1. 建立項目

composer create-project topthink/think command-demo
複製代碼

cd command-demo 進入項目目錄,接着執行 php think ,若是沒有配置php環境變量可使用絕對路徑,例如/usr/local/php/bin/php think。若是打印出相似以下內容說明項目安裝成功。this

2. 建立自定義命令

php think make:command OrderCheckCommand ordercheck
複製代碼

上面命令的意思是在app/command/目錄下 建立一個OrderCheckCommand.php php類文件,命令名稱叫作ordercheck

3. 註冊指令

找到config/console.php 文件,添加以下代碼:

<?php
return [
    // 指令定義
    'commands' => [
        'ordercheck' => 'app\command\OrderCheckCommand'
    ],
];
複製代碼

試着執行命令 php think ordercheck 若是看到以下輸出,則命令建立成功。

image-20210807235956230

4. 指令說明

打開app/command/OrderCheckCommand.php

image-20210808000337925

  • 其中configure 方法是對指令的配置

    setName 設置指令名稱;

    setDescription 設置指令描述內容;

    addArgument 設置指令參數;

    addOption 設置指令選項。

  • execute 當執行命令時會執行execute 中邏輯。

5. 編寫業務指令

建立一個僞需求:指令接收一個訂單狀態參數,其中1是異常訂單,需校驗訂單實際狀態,2只查詢失敗訂單,給用戶退款;接收一個省份選項,若是輸入省份則只處理某個省份的訂單。

修改代碼以下:

class OrderCheckCommand extends Command {
    protected function configure() {
        // 指令配置
        $this->setName('ordercheck')
            // Argument::OPTIONAL->可選參數 Argument::REQUIRED->必填參數 Argument::IS_ARRAY->數組參數
            ->addArgument('status', Argument::OPTIONAL, '訂單狀態', 1)
            ->addOption('province', 'p', Option::VALUE_REQUIRED, '訂單所屬省份', 'beijing')
            ->setDescription('the ordercheck command');
    }

    protected function execute(Input $input, Output $output) {
        $status = intval($input->getArgument('status'));
        $statusText = $status == 1 ? '訂單狀態爲異常訂單,進行訂單實際狀態校驗' : '訂單狀態失敗訂單,退款給用戶';
        if ($input->hasOption('province')) {
            $pre = '處理' . $input->getOption('province') . '訂單;';
        } else {
            $pre = '處理全國訂單;';
        }
      	// 記錄執行日誌
      	Log::info($pre . $statusText);
        // 指令輸出
        $output->writeln($pre . $statusText);
    }
}
複製代碼

addArgument 接收四個參數,分別是名稱、類型、描述、默認值;類型可選值分別爲 Argument::OPTIONAL(可選參數)Argument::REQUIRED(必填參數)Argument::IS_ARRAY(數組參數)

addOption 接收五個參數,分別是選項名稱、別名(簡寫選項名)、類型、描述、默認值,其中類型可選值分別是Option::VALUE_NONE(無需傳值)Option::VALUE_REQUIRED(必須傳值)Option::VALUE_OPTIONAL(可選傳值)Option::VALUE_IS_ARRAY(傳數組值)

6. 測試指令

image-20210808004518523

3、結合crontab部署定時任務

假設須要一個定時任務,每2分鐘查詢省份爲beijing 的失敗訂單給用戶退款,咱們須要執行的命令就是:

php think ordercheck 2 -p beijing
複製代碼

當命令寫到crontab中須要寫項目的絕對路徑,最終crontab寫入內容以下:

*/2 * * * * php /home/www/command-demo/think ordercheck 2 -p beijing
複製代碼

首先執行crontab -e,添加上面內容,保存。

image-20210808010826094

接着執行systemctl restart crond.service ,重啓crontab。

image-20210808011007654

等待幾分鐘以後查看日誌,看命令是否執行。

image-20210808011404367

相關文章
相關標籤/搜索