国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

任務(wù)調(diào)度

任務(wù)調(diào)度


任務(wù)調(diào)度

簡(jiǎn)介

過(guò)去,你可能需要在服務(wù)器上為每一個(gè)調(diào)度任務(wù)去創(chuàng)建 Cron 入口。但是這種方式很快就會(huì)變得不友好,因?yàn)檫@些任務(wù)調(diào)度不在源代碼中,并且你每次都需要通過(guò) SSH 鏈接登錄到服務(wù)器中才能增加 Cron 入口。

Laravel 命令行調(diào)度器允許你在 Laravel 中對(duì)命令調(diào)度進(jìn)行清晰流暢的定義。且使用這個(gè)任務(wù)調(diào)度器時(shí),你只需要在你的服務(wù)器上創(chuàng)建單個(gè) Cron 入口接口。你的任務(wù)調(diào)度在 app/Console/Kernel.phpschedule 方法中進(jìn)行定義。為了幫助你更好的入門(mén),這個(gè)方法中有個(gè)簡(jiǎn)單的例子。

啟動(dòng)調(diào)度器

當(dāng)使用這個(gè)調(diào)度器時(shí),你只需要把下面的 Cron 入口添加到你的服務(wù)器中即可。如果你不知道怎么在服務(wù)器中添加 Cron 入口,可以考慮使用一些服務(wù)來(lái)管理 Cron 入口,比如 Laravel Forge

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

這個(gè) Cron 為每分鐘執(zhí)行一次 Laravel 的命令行調(diào)度器。當(dāng) schedule:run 命令被執(zhí)行的時(shí)候,Laravel 會(huì)根據(jù)你的調(diào)度執(zhí)行預(yù)定的程序。

定義調(diào)度

你可以在 App\Console\Kernel 類(lèi)的 schedule 方法中定義所有的調(diào)度任務(wù)。在開(kāi)始之前,讓我們來(lái)看一個(gè)例子。在這個(gè)例子中,我們計(jì)劃每天午夜調(diào)用一個(gè)閉包。在閉包中,我們執(zhí)行一個(gè)數(shù)據(jù)庫(kù)查詢來(lái)清空一張表:

<?php
    namespace App\Console;
    use Illuminate\Support\Facades\DB;
    use Illuminate\Console\Scheduling\Schedule;
    use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
    class Kernel extends ConsoleKernel{    
    /**
     * 應(yīng)用里的自定義 Artisan 命令
     *
     * @var array
     */   
     protected $commands = [    
         //   
       ];   
    /**
     * 定義計(jì)劃任務(wù)
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */  
    protected function schedule(Schedule $schedule) 
       {     
          $schedule->call(function () {       
          DB::table('recent_users')->delete();      
        })->daily();  
      }
   }

除了使用閉包來(lái)定義任務(wù)調(diào)度外,你也可以用 invokable objects

$schedule->call(new DeleteRecentUsers)->daily();

Artisan 命令調(diào)度

除了使用調(diào)用閉包這種方式來(lái)調(diào)度外,你還可以調(diào)用  Artisan 命令 和操作系統(tǒng)命令。比如,你可以給 command 方法傳遞命令名稱或者類(lèi)來(lái)調(diào)度一個(gè) Artisan 命令。

$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();

隊(duì)列任務(wù)調(diào)度

job 方法可以用來(lái)調(diào)度 隊(duì)列任務(wù)。此方法提供了一種快捷的方式來(lái)調(diào)度任務(wù),而無(wú)需使用 call 方法創(chuàng)建閉包來(lái)調(diào)度任務(wù)。

$schedule->job(new Heartbeat)->everyFiveMinutes();
// 分發(fā)任務(wù)到「heartbeats」隊(duì)列...
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();

Shell 命令調(diào)度

exec 方法可用于向操作系統(tǒng)發(fā)送命令:

$schedule->exec('node /home/forge/script.js')->daily();

調(diào)度頻率設(shè)置

當(dāng)然了,你可以給你的任務(wù)分配多種調(diào)度計(jì)劃:

方法描述
->cron('* * * * *');自定義 Cron 時(shí)間表執(zhí)行任務(wù)
->everyMinute();每分鐘執(zhí)行一次任務(wù)
->everyFiveMinutes();每五分鐘執(zhí)行一次任務(wù)
->everyTenMinutes();每十分鐘執(zhí)行一次任務(wù)
->everyFifteenMinutes();每十五分鐘執(zhí)行一次任務(wù)
->everyThirtyMinutes();每三十分鐘執(zhí)行一次任務(wù)
->hourly();每小時(shí)執(zhí)行一次任務(wù)
->hourlyAt(17);每小時(shí)第 17 分鐘執(zhí)行一次任務(wù)
->daily();每天午夜執(zhí)行一次任務(wù)(譯者注:每天零點(diǎn))
->dailyAt('13:00');每天 13 點(diǎn)執(zhí)行一次任務(wù)
->twiceDaily(1, 13);每天 1 點(diǎn) 和 13 點(diǎn)分別執(zhí)行一次任務(wù)
->weekly();每周執(zhí)行一次任務(wù)
->weeklyOn(1, '8:00');每周一的 8 點(diǎn)執(zhí)行一次任務(wù)
->monthly();每月執(zhí)行一次任務(wù)
->monthlyOn(4, '15:00');每月 4 號(hào)的 15 點(diǎn)執(zhí)行一次任務(wù)
->quarterly();每季度執(zhí)行一次任務(wù)
->yearly();每年執(zhí)行一次任務(wù)
->timezone('America/New_York');設(shè)定時(shí)區(qū)

結(jié)合其他一些特定條件,我們可以生成在一周中特定時(shí)間運(yùn)行的任務(wù)。舉個(gè)例子,在每周一執(zhí)行命令:

// 每周一 13:00 執(zhí)行...
$schedule->call(function () { 
   //
   })->weekly()->mondays()->at('13:00');
 // 工作日(周一至周五) 8點(diǎn) 至 17 點(diǎn)每小時(shí)執(zhí)行一次...
$schedule->command('foo')        
  ->weekdays()          
  ->hourly()          
  ->timezone('America/Chicago')          
  ->between('8:00', '17:00');

額外的限制條件列表如下:

方法描述
->weekdays();限制任務(wù)在工作日?qǐng)?zhí)行
->weekends();限制任務(wù)在周末執(zhí)行
->sundays();限制任務(wù)在周日?qǐng)?zhí)行
->mondays();限制任務(wù)在周一執(zhí)行
->tuesdays();限制任務(wù)在周二執(zhí)行
->wednesdays();限制任務(wù)在周三執(zhí)行
->thursdays();限制任務(wù)在周四執(zhí)行
->fridays();限制任務(wù)在周五執(zhí)行
->saturdays();限制任務(wù)在周六執(zhí)行
->between($start, $end);限制任務(wù)在 $start$end 之間執(zhí)行
->when(Closure);當(dāng)閉包返回為真時(shí)執(zhí)行
->environments($env);限制任務(wù)在特定環(huán)境中執(zhí)行

時(shí)間范圍限制

使用 between 來(lái)限制任務(wù)在一天中的某個(gè)時(shí)間段來(lái)執(zhí)行:

$schedule->command('reminders:send')     
               ->hourly()                    
               ->between('7:00', '22:00');

或者使用 unlessBetween 方法來(lái)為任務(wù)排除一個(gè)時(shí)間段:

$schedule->command('reminders:send')              
      ->hourly()                    
      ->unlessBetween('23:00', '4:00');

閉包測(cè)試限制

使用 when 方法來(lái)根據(jù)測(cè)試結(jié)果來(lái)執(zhí)行任務(wù)。也就是說(shuō),如果給定的閉包返回結(jié)果為 true,只要沒(méi)有其他約束條件阻止任務(wù)運(yùn)行,任務(wù)就會(huì)一直執(zhí)行下去:

$schedule->command('emails:send')->daily()->when(function () { 
   return true;
 });

skip 方法可以看做是 when 方法的逆過(guò)程。如果 skip 方法返回 true,任務(wù)就不會(huì)執(zhí)行:

$schedule->command('emails:send')->daily()->skip(function () {
    return true;
 });

使用鏈?zhǔn)秸{(diào)用 when 方法時(shí),只有所有的 when 都返回 true 時(shí),任務(wù)才會(huì)執(zhí)行。

環(huán)境約束

environments 方法可用于僅在給定環(huán)境中執(zhí)行任務(wù):

$schedule->command('emails:send')         
   ->daily()            
   ->environments(['staging', 'production']);

時(shí)區(qū)

使用 timezone 方法,你可以指定任務(wù)在給定的時(shí)區(qū)內(nèi)執(zhí)行:

$schedule->command('report:generate')      
   ->timezone('America/New_York')        
   ->at('02:00')

如果要為所有計(jì)劃任務(wù)分配相同的時(shí)區(qū),則可能希望在 app/Console/Kernel.php 文件中定義 scheduleTimezone 方法。 此方法應(yīng)返回應(yīng)分配給所有計(jì)劃任務(wù)的默認(rèn)時(shí)區(qū):

/**
 * 獲取默認(rèn)情況下應(yīng)為預(yù)定事件使用的時(shí)區(qū)。
 *
 * @return \DateTimeZone|string|null
 */
 protected function scheduleTimezone(){  
   return 'America/Chicago';
 }

{note} 請(qǐng)記住,有些時(shí)區(qū)會(huì)使用夏令時(shí)。當(dāng)夏時(shí)制時(shí)間發(fā)生更改時(shí),你的任務(wù)可能會(huì)執(zhí)行兩次,甚至根本不會(huì)執(zhí)行。所以我們建議盡可能避免使用時(shí)區(qū)來(lái)安排計(jì)劃任務(wù)。

避免任務(wù)重復(fù)

默認(rèn)情況下,即使之前的任務(wù)還在執(zhí)行,調(diào)度內(nèi)任務(wù)也會(huì)執(zhí)行。你可以使用 withoutOverlapping 方法來(lái)避免這種情況:

$schedule->command('emails:send')->withoutOverlapping();

在這個(gè)例子中,如果 emails:send Artisan 命令 沒(méi)有正在運(yùn)行,它將會(huì)每分鐘執(zhí)行一次。如果你的任務(wù)執(zhí)行時(shí)間不確定,且你又不能準(zhǔn)確預(yù)估出任務(wù)的執(zhí)行時(shí)間,那么  withoutOverlapping 方法會(huì)顯得特別有用。

如果有需要,你可以指定「without overlapping」鎖指定的時(shí)間范圍。默認(rèn)情況下,鎖將在 24 小時(shí)后過(guò)期。

$schedule->command('emails:send')->withoutOverlapping(10);

任務(wù)只運(yùn)行在一臺(tái)服務(wù)器上

{note} 要使用這個(gè)特性,你的應(yīng)用默認(rèn)緩存驅(qū)動(dòng)必須是 memcached 或者 redis。除此之外,所有的服務(wù)器必須使用同一個(gè)中央緩存服務(wù)器通信。

如果你的應(yīng)用在多個(gè)服務(wù)器上運(yùn)行,你可能需要限制你的調(diào)度任務(wù)只在單個(gè)服務(wù)器上運(yùn)行。假設(shè)你有一個(gè)調(diào)度任務(wù):每周五晚生成一份新報(bào)告。如果這個(gè)任務(wù)調(diào)度器在三個(gè)服務(wù)器上運(yùn)行,那么這個(gè)任務(wù)會(huì)在三臺(tái)服務(wù)器上運(yùn)行且生成三份報(bào)告。這樣不好!

為了說(shuō)明任務(wù)應(yīng)該在單個(gè)服務(wù)器上運(yùn)行,在定義調(diào)度任務(wù)時(shí)使用 onOneServer 方法。第一個(gè)獲取到任務(wù)的服務(wù)器會(huì)生成一個(gè)原子鎖,用來(lái)防止其他服務(wù)器在同一時(shí)刻執(zhí)行相同任務(wù)。

$schedule->command('report:generate')             
   ->fridays()                
   ->at('17:00')                
   ->onOneServer();

后臺(tái)任務(wù)

默認(rèn)情況下,同時(shí)調(diào)度的多個(gè)命令將按順序執(zhí)行。如果你有長(zhǎng)時(shí)間運(yùn)行的命令,這可能會(huì)導(dǎo)致后續(xù)命令的啟動(dòng)時(shí)間比預(yù)期的要晚。因此,你想在后臺(tái)同時(shí)運(yùn)行命令,可以使用 runInBackground 方法:

$schedule->command('analytics:report')      
   ->daily()         
   ->runInBackground();

維護(hù)模式

Laravel 的隊(duì)列任務(wù)在 維護(hù)模式 下不會(huì)運(yùn)行。因?yàn)槲覀儾幌肽愕恼{(diào)度任務(wù)干擾到你服務(wù)器上可能還未完成的項(xiàng)目。不過(guò),如果你確實(shí)是想在維護(hù)模式下強(qiáng)制調(diào)度任務(wù)執(zhí)行,你可以使用 evenInMaintenanceMode 方法:

$schedule->command('emails:send')->evenInMaintenanceMode();

任務(wù)輸出

Laravel 調(diào)度器提供了一些方便的方法來(lái)處理調(diào)度任務(wù)輸出。首先,你可以使用 sendOutputTo 方法來(lái)輸出到文件以便于后續(xù)檢查:

$schedule->command('emails:send')    
     ->daily()         
     ->sendOutputTo($filePath);

如果希望將輸出 附加 到給定文件,可以使用 appendOutputTo 方法

$schedule->command('emails:send')     
    ->daily()         
    ->appendOutputTo($filePath);

使用 emailOutputTo 方法,你可以將輸出發(fā)送到指定郵箱。在使用郵件發(fā)送之前,你需要配置 Laravel 的 郵件服務(wù):

$schedule->command('foo')   
      ->daily()         
      ->sendOutputTo($filePath)        
      ->emailOutputTo('foo@example.com');

{note} emailOutputTo,sendOutputToappendOutputTo 方法是  commandexec 獨(dú)有的。

任務(wù)鉤子

使用 beforeafter 方法,你可以在調(diào)度任務(wù)執(zhí)行前或者執(zhí)行后來(lái)執(zhí)行特定代碼:

$schedule->command('emails:send')   
      ->daily()         
      ->before(function () {         
          // Task is about to start...      
            })      
      ->after(function () {       
           // Task is complete...      
         });

Ping 網(wǎng)址

使用 pingBeforethenPing 方法,你可以在任務(wù)執(zhí)行前或者執(zhí)行后來(lái) ping 指定的 URL。這個(gè)方法在通知外部服務(wù)(比如 Laravel Envoyer)時(shí)將會(huì)特別有用:

$schedule->command('emails:send')      
   ->daily()         
   ->pingBefore($url)         
   ->thenPing($url);

只有在給定條件為 true 時(shí),才能使用 pingBeforeIfthenPingIf 方法 ping 指定的 URL:

$schedule->command('emails:send')      
   ->daily()         
   ->pingBeforeIf($condition, $url)         
   ->thenPingIf($condition, $url);

所有 ping 方法都需要 Guzzle HTTP 庫(kù)。你可以使用 Composer 來(lái)添加 Guzzle 到你的項(xiàng)目中:

composer require guzzlehttp/guzzle
本文章首發(fā)在 LearnKu.com 網(wǎng)站上。