本文的示例代码参考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 定时任务