Laravel调度作业不会运行异步,阻碍执行

时间:2016-09-08 13:57:51

标签: php laravel asynchronous queue

所以在laravel中我有一个函数发布一些内容并将作业推送到队列并从函数(而不是队列)返回一些数据。

现在我认为laravel队列应该是某种异步函数,即使有很多数据需要处理,你也可以确保你的代码保持快速。但是我注意到我的代码仍然需要等到作业完成才能将数据返回给用户。这是一个名为2次的脚本日志,但其中一个在作业中几乎没有数据,另一个有很多:

[2016-09-08 13:26:50] production.INFO: New alert with Image  
[2016-09-08 13:26:50] production.INFO: Push is send.  
[2016-09-08 13:26:50] production.INFO: Alert data is send back.  
[2016-09-08 13:26:50] production.INFO: New image is valid  
[2016-09-08 13:26:50] production.INFO: Move file for upload  
[2016-09-08 13:26:50] production.INFO: Made it to upload  

[2016-09-08 13:28:50] production.INFO: New alert with Image  
[2016-09-08 13:31:19] production.INFO: Push is send.  
[2016-09-08 13:31:19] production.INFO: Alert data is send back.  
[2016-09-08 13:31:20] production.INFO: New image is valid  
[2016-09-08 13:31:20] production.INFO: Move file for upload  
[2016-09-08 13:31:20] production.INFO: Made it to upload  

正如您所看到的,在应用程序收到更多数据之前,第二个需要4分钟。这是一个交易破坏者,你不能让用户等待这么久。那么如何让作业运行异步并且函数不必等待它完成。

这是我调用代码的行:

if($isValid === true) {
  $this->dispatch(new SendPushNotificationAlert($alert));

  Log::info('Push is send.');
}

这是我的工作:

<?php

namespace App\Jobs;

use DB;
use Log;
use App\Alerts;
use App\Users;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Http\Controllers\PushNotificationsController as PushNotificationsController;

class SendPushNotificationAlert extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    Protected $alert;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Alerts $alert)
    {
        //
        $this->alert = $alert;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $alert = $this->alert;
        $radius = 10000;
        $earthRadius = 6371000;  // earth's mean radius, m
        // first-cut bounding box (in degrees)
        $maxLat = $alert->lat + rad2deg($radius/$earthRadius);
        $minLat = $alert->lat - rad2deg($radius/$earthRadius);
        // compensate for degrees longitude getting smaller with increasing latitude
        $maxLon = $alert->lon + rad2deg($radius/$earthRadius/cos(deg2rad($alert->lat)));
        $minLon = $alert->lon - rad2deg($radius/$earthRadius/cos(deg2rad($alert->lat)));
        $locations = DB::select("
        SELECT id, lat, lon, user_id, name, radius,
          acos(
            sin(?)*
            sin(radians(lat))+
            cos(?)*
            cos(radians(lat))*
            cos(radians(lon) - ?)
          ) * ? AS distance
              FROM (
                  SELECT id, lat, lon, user_id, name, radius
                  FROM user__locations
                  WHERE lat BETWEEN ? AND ?
                    AND lon BETWEEN ? AND ? AND hide = 0
        ) AS FirstCut
        WHERE acos(
            sin(?)*
            sin(radians(lat))+
            cos(?)*
            cos(radians(lat)
          )*
          cos(radians(lon) - ?)
        ) * ? < ?
        ORDER BY distance", [
          deg2rad($alert->lat),
          deg2rad($alert->lat),
                deg2rad($alert->lon),
          $earthRadius,
                $minLat,
          $maxLat,
          $minLon,
          $maxLon,
          deg2rad($alert->lat),
          deg2rad($alert->lat),
          deg2rad($alert->lon),
          $earthRadius,
          $radius
        ]);

        if(count($locations > 0)) {
          foreach ($locations as $location) {
            if($location->distance < $location->radius) {
              if($alert->anoniem == 0) {
                $user = Users::find($alert->user_id);
                $pushuser = Users::find($location->user_id);
                $pushuser->type = 'location';
                $pushuser->locationname = $location->name;
                $pushusers[] = $pushuser;
              }
                    }
          }
        }
        if(isset($pushusers)) {
          PushNotificationsController::sendPushnotificationsAlert($pushusers, $user);
        }
    }
}

任何人都知道为什么作业不会异步运行以及我可以做些什么来修复它?

2 个答案:

答案 0 :(得分:1)

你使用什么队列驱动程序?

如此处所述:https://laravel.com/docs/5.2/queues#introduction您有多种选择,但如果您使用synchronous(仅适用于本地环境),则不会运行异步。

您的工作是否实施了Illuminate\Contracts\Queue\ShouldQueue

如上所述:https://laravel.com/docs/5.2/queues#writing-job-classes您会看到如果您不实施该作业,则该作业将同步运行。

希望它能帮助你!

修改

看到你已经实现了Illuminate\Contracts\Queue\ShouldQueue,所以这不是问题。

答案 1 :(得分:0)

我在Laravel 5.7中遇到了同样的问题。默认情况下,Laravel队列配置为同步运行。打开config/queue.php,切换到sync以外的其他地方

例如:

'default' => env('QUEUE_CONNECTION', 'redis'),

或者,您也可以将其添加到.env文件中。

QUEUE_CONNECTION=redis