美文网首页
Laravel框架 之 队列与任务调度

Laravel框架 之 队列与任务调度

作者: 诺之林 | 来源:发表于2018-09-20 14:29 被阅读8次

    本文的示例代码参考queue-and-schedule

    目录

    Startup

    Composer

    composer create-project laravel/laravel queue-and-schedule --prefer-dist "5.5.*"
    
    cd queue-and-schedule
    

    Controller

    php artisan make:controller FenceAlarmsController
    
    vim app/Http/Controllers/FenceAlarmsController.php
    
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class FenceAlarmsController extends Controller
    {
        public function create(Request $request)
        {
            $type = $request->input('type');
            $alarms = $request->input('content');
    
            // 校验请求
            // 详细参考 http://lbsyun.baidu.com/index.php?title=yingyan/api/v3/geofencealarm#service-page-anchor8
            if ($type === 1) {
                return [
                    'code' => 0,
                ];
            }
    
            // 报警推送
            return [
                'code' => 0,
                'alarms' => count($alarms)
            ];
        }
    }
    

    Route

    vim routes/web.php
    
    <?php
    
    Route::get('/', function () {
        return view('welcome');
    });
    
    Route::post('/fences/alarms', 'FenceAlarmsController@create');
    
    vim app/Http/Middleware/VerifyCsrfToken.php
    
    <?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
    
    class VerifyCsrfToken extends Middleware
    {
        protected $except = [
            '/fences/*'
        ];
    }
    
    • 测试
    php artisan serve
    
    curl -X POST \
        -H 'content-type: application/json' \
        -d '{ "type": 1 }' \
        http://localhost:8000/fences/alarms \
        | json
    
    {
      "code": 0
    }
    
    curl -X POST \
        -H 'content-type: application/json' \
        -d '{ "type": 2, "content": [ { "fence_id": 1 } ] }' \
        http://localhost:8000/fences/alarms \
        | json
    
    {
      "code": 0,
      "alarms": 1
    }
    

    Queue

    Job

    php artisan make:job HandleFenceAlarms
    
    vim app/Jobs/HandleFenceAlarms.php
    
    <?php
    
    namespace App\Jobs;
    
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Illuminate\Support\Facades\Log;
    
    class HandleFenceAlarms implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        private $alarm;
    
        public function __construct($alarm)
        {
            $this->alarm = $alarm;
        }
    
        public function handle()
        {
            Log::info('handle alarm: ' . $this->alarm['fence_id']);
        }
    }
    

    Dispatch

    vim app/Http/Controllers/FenceAlarmsController.php
    
    <?php
    
    namespace App\Http\Controllers;
    
    use App\Jobs\HandleFenceAlarms;
    use Illuminate\Http\Request;
    
    class FenceAlarmsController extends Controller
    {
        public function create(Request $request)
        {
            $type = $request->input('type');
            $alarms = $request->json()->all()['content'];
    
            // 校验请求
            // 详细参考 http://lbsyun.baidu.com/index.php?title=yingyan/api/v3/geofencealarm#service-page-anchor8
            if ($type === 1) {
                return [
                    'code' => 0,
                ];
            }
    
            foreach ($alarms as $alarm) {
                $job = (new HandleFenceAlarms($alarm))->onQueue('fence-alarms');
                $this->dispatch($job);
            }
    
            // 报警推送
            return [
                'code' => 0,
                'alarms' => count($alarms)
            ];
        }
    }
    

    Async

    sed -i "" 's/QUEUE_DRIVER=sync/QUEUE_DRIVER=redis/g' .env
    
    composer require predis/predis
    
    docker run --name laravel-redis -p 6379:6379 -d redis
    

    Daemon

    Supervisor

    brew install supervisor
    
    sed -i "" 's/;\[inet_http_server/\[inet_http_server/g' /usr/local/etc/supervisord.ini
    
    sed -i "" 's/;port=127.0.0.1:9001/port=127.0.0.1:9001/g' /usr/local/etc/supervisord.ini
    

    Program

    mkdir -p /usr/local/etc/supervisor.d/
    
    vim fence-alarms.ini
    
    [program:fence-alarms]
    process_name=%(program_name)s_%(process_num)02d
    command=php /Users/kevin/Workspace/laravel-tutorial/queue-and-schedule/artisan queue:work redis --queue=fence-alarms --tries=3
    autostart = true     ; 在 supervisord 启动的时候也自动启动
    startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了
    autorestart = true   ; 程序异常退出后自动重启
    startretries = 3     ; 启动失败自动重试次数,默认是 3
    user = kevin         ; 用哪个用户启动
    numprocs = 4
    redirect_stderr = true  ; 把 stderr 重定向到 stdout,默认 false
    stdout_logfile=/Users/kevin/Workspace/laravel-tutorial/queue-and-schedule/storage/logs/fence-alarms.log
    

    Process

    supervisord -c /usr/local/etc/supervisord.ini
    
    supervisorctl status
    
    supervisorctl reload
    

    此方法重启系统后需要手动启动supervisord

    • 测试
    php artisan serve
    
    rm storage/logs/laravel.log
    
    curl -X POST \
        -H 'content-type: application/json' \
        -d '{ "type": 2, "content": [ { "fence_id": 1001 } ] }' \
        http://localhost:8000/fences/alarms \
        | json
    
    {
      "code": 0,
      "alarms": 1
    }
    
    cat storage/logs/laravel.log
    
    [2018-09-14 06:41:33] local.INFO: handle alarm: 1001
    
    cat storage/logs/fence-alarms.log
    
    [2018-09-14 06:41:32] Processing: App\Jobs\HandleFenceAlarms
    [2018-09-14 06:41:33] Processed:  App\Jobs\HandleFenceAlarms
    

    Schedule

    Command

    php artisan make:command CurrentTime
    
    vim app/Console/Commands/CurrentTime.php
    
    <?php
    
    namespace App\Console\Commands;
    
    use Carbon\Carbon;
    use Illuminate\Console\Command;
    use Illuminate\Support\Facades\Log;
    
    class CurrentTime extends Command
    {
        protected $signature = 'CurrentTime';
    
        protected $description = '显示当前时间';
    
        public function __construct()
        {
            parent::__construct();
        }
    
        public function handle()
        {
            Log::info('current time: ' . Carbon::now()->toDateTimeString());
        }
    }
    

    Kernel

    vim app/Console/Kernel.php
    
    <?php
    
    namespace App\Console;
    
    use App\Console\Commands\CurrentTime;
    use Illuminate\Console\Scheduling\Schedule;
    use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
    
    class Kernel extends ConsoleKernel
    {
        protected $commands = [
            CurrentTime::class,
        ];
    
        protected function schedule(Schedule $schedule)
        {
            $schedule->command('CurrentTime')->everyMinute();
        }
    
        protected function commands()
        {
            $this->load(__DIR__ . '/Commands');
    
            require base_path('routes/console.php');
        }
    }
    

    Cron

    echo "* * * * * php /Users/kevin/Workspace/laravel-tutorial/queue-and-schedule/artisan schedule:run >> /dev/null 2>&1" >> cron.txt
    
    crontab cron.txt
    
    crontab -l # crontab -r
    

    关于crontab更多介绍 可以参考19. crontab 定时任务

    参考

    相关文章

      网友评论

          本文标题:Laravel框架 之 队列与任务调度

          本文链接:https://www.haomeiwen.com/subject/ommngftx.html