PHP速学视频免费教程(入门到精通)
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
当web应用和后端批处理应用运行在不同的服务器上,并且拥有各自独立的laravel项目时,直接通过web应用 dispatch() 一个任务,让后端批处理应用的队列工作器来处理,似乎是不可行的。最初的考量可能包括使用redis的pub/sub机制,结合laravel队列在后端处理。但这种方法引入了额外的复杂性,例如pub/sub订阅者在部署时可能丢失消息,并且需要额外的supervisor进程来管理订阅。更理想的方案是,能否直接利用laravel现有的队列机制,实现跨应用的无缝任务调度。
经过实践验证,一个简洁而有效的解决方案是:在发送任务的Web应用和处理任务的后端批处理应用中,定义结构完全一致的Job(任务)类。关键在于,Web应用中的Job类只需定义构造函数和属性,而handle()方法可以为空或仅作占位;而后端批处理应用中的Job类则需要包含实际的业务逻辑实现。
以下是具体的实现示例:
1. Web应用 (任务发送方)
在Web应用的 app/Jobs 目录下创建 SomeJob.php:
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class SomeJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $userId; private $someParam; /** * 创建一个新的任务实例。 * * @param int $userId * @param string $someParam * @return void */ public function __construct(int $userId, string $someParam) { $this->userId = $userId; $this->someParam = $someParam; } /** * 执行任务。(此处的handle方法通常为空或仅作占位) * 实际的业务逻辑将在批处理应用中实现。 * * @return void */ public function handle() { // 实际的业务逻辑将在批处理应用中实现 } }
在Web应用中调度任务:
<?php use App\Jobs\SomeJob; $userId = 123; $someParam = 'example_data'; SomeJob::dispatch($userId, $someParam);
当 SomeJob::dispatch() 被调用时,Laravel会将任务的类名(包括命名空间)、构造函数参数以及必要的元数据序列化,并将其存储到配置的队列驱动中(例如Redis)。
2. 后端批处理应用 (任务处理方)
在后端批处理应用的 app/Jobs 目录下创建 SomeJob.php,确保其命名空间、类名和构造函数与Web应用中的Job类完全一致:
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class SomeJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $userId; private $someParam; /** * 创建一个新的任务实例。 * * @param int $userId * @param string $someParam * @return void */ public function __construct(int $userId, string $someParam) { $this->userId = $userId; $this->someParam = $someParam; } /** * 执行任务。(此处包含实际的业务逻辑) * * @return void */ public function handle() { // 实际的业务逻辑实现 echo "Processing user ID: " . $this->userId . " with param: " . $this->someParam . "\n"; // 例如:更新数据库、调用外部API等 } }
在后端批处理应用中,启动队列工作器来监听并处理任务:
php artisan queue:work --sleep=3 --tries=1 --delay=1
当Web应用调度 SomeJob 时,Laravel会将任务的类名(例如 App\Jobs\SomeJob)、构造函数参数($userId, $someParam)以及其他必要的元数据序列化后存储到Redis队列中。
当后端批处理应用的队列工作器从Redis中取出这个任务时,它会根据存储的类名(App\Jobs\SomeJob)尝试实例化一个本地的 App\Jobs\SomeJob 对象。由于两个应用中的 SomeJob 类定义(包括命名空间、类名和构造函数)是相同的,Laravel能够成功地实例化该对象,并将队列中存储的参数注入到构造函数中。随后,工作器会调用这个本地实例的 handle() 方法,从而执行后端批处理应用中定义的实际业务逻辑。
注意事项:
通过在Web应用和后端批处理应用中同步Job类的结构(但只在后端实现 handle() 方法),并共享一个队列后端(如Redis),我们能够优雅地实现跨Laravel应用的异步任务调度。这种模式充分利用了Laravel队列的强大功能,简化了分布式系统中的任务管理,同时保持了各服务间的松散耦合,是构建可伸缩、可维护的分布式Laravel应用的推荐方法。
已抢7569个
抢已抢97331个
抢已抢15252个
抢已抢53946个
抢已抢198259个
抢已抢88323个
抢