2017-07-08 4 views
2

紹介/システムアーキテクチャ

  • サーバA - Laravelのインストール、データベース
  • サーバーB - RabbitMQのサーバー
  • サーバーC - Laravelのインストール、データベースB

サーバーAはAPIエンドポイントであり、リモートソースからの呼び出しのみを受信します。コールに応じて、RabbitMQサーバ(サーバB)にジョブが追加されます。このジョブは、サーバCによって処理/聴取されます。Laravel - リモートシステム上で処理されるべき仕事のシリアライズ

サーバーサーバーCによって処理され、まったく同じジョブのローカルコピーが含まれています。ジョブハンドラのコードとコンストラクタを以下に示します(ジョブコード)。

問題: サーバーAがジョブをシリアル化し、それが唯一のデータベースB(サーバーC)に存在するモニターについての情報にアクセスしようとすると、キューに追加することはできません。 サーバAにはモデルのコピーが含まれていますが、実際のデータベーステーブルやレコードは使用されていないため、そのデータは含まれていません - ジョブをシリアル化して「これは何ですか」と言うだけですサーバC )しなければならない」

しかし、ジョブの発行時には、データベース情報を取得しようとしています(必要な正確なデータをシリアル化する可​​能性があります)。レコードが存在しないため、処理できません。

私はLaravelのSerializesModelsを理解していて、具体的にはモデル呼び出し自体をシリアライズするだけで、実際にはデータベース関連は何もしませんでした。これは機能しているようには見えないか、間違っていると誤解しています。

回避策:一つの可能​​な回避策は、単にサーバーCサーバーにデータベースへアクセス権を与えることであろう。この場合、高可用性を意図した設計(APIエンドポイントとキューは決して使用できないが、キュー・プロセッサがある場合がある)を破るため、オプションではありません。

TopDown View

コード

関連する求人コード

// Models 
use App\UptimeMonitor; 

// Notifications 
use App\Notifications\StatusQueue as StatusNotification; 

class StatusQueue implements ShouldQueue 
{ 
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; 

     protected $monitor_source; 
     protected $monitor_data; 
     protected $monitor_repository; 

     /** 
     * Create a new job instance. 
     * 
     * @param string[] monitor_source (Eg: HetrixTools) 
     * @param array[] monitor_data (All data passed from the source) 
     * 
     */ 
     public function __construct($monitor_source, array $monitor_data) 
     { 
      $this->monitor_source = $monitor_source; 
      $this->monitor_data = $monitor_data; 

      if($this->monitor_source === 'centric') 
        return $this->centric(); 

     } 

     /** 
     * Centric Uptime Monitoring 
     */ 
     public function centric() 
     { 
       $result = ($this->monitor_data['monitor_status'] == 'online') ? 'online' : 'timeout'; 

       try { 
         $monitor = UptimeMonitor::where('identifier', '=', $this->monitor_data['monitor_id'])->firstOrFail(); 
         $status = $monitor->status()->firstOrFail(); 
         $contacts = $monitor->contacts()->get(); 
       } catch (Exception $e) { 
         return Log::error('[JOBS::StatusQueue::centric] - ' . $e); 
       } 

       $status->state = $result; 

       if(!$contacts) 
         return true; 

       foreach($contacts as $contact) { 
         $contact->notify(new StatusNotification($monitor, $status)); 
       } 
     } 
} 

その他のコード

あなたが他のコードを必要とした場合は、私に知らせて!しかし、これはジョブクラス自体の全機能をカバーするはずです。それ以外に、起きているのは、その仕事を発行することだけです。それは、コンストラクタに基づいて明らかです。

質問

このすべてからの最後の質問:なぜ、この失敗は(?のように、なぜそれがデータベースの情報を必要とせずに、仕事をシリアル化することはできません)です - あなたは回避する方法を見ていますこの問題は、のサーバCからデータベースにアクセスする必要がない場所にジョブをキューに入れるサーバA、まだLaravelのキュー・メカニックを使用していますか?

いつものように義務付けられています。

答えて

0

最も簡単な解決法は、ほとんどの場合常に正しい方法です。

サーバAは、サーバBが処理するジョブの複製をにする必要はありません。同じクラスで完全に空のジョブを持つことができ、サーバBはそれを正しく処理します。その結果、これは今、サーバーA上の仕事である

class AlertQueue implements ShouldQueue 
{ 
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; 

    protected $job; 

    /** 
    * Create a new job instance. 
    * 
    */ 
    public function __construct() 
    { 

    } 

    /** 
    * Execute the job. 
    * 
    * @return void 
    */ 
    public function handle() 
    { 
     // 
    } 
} 

サーバーBながらも、実際に行われますロジックのすべてを持っているAlertQueue仕事を持っています。

関連する問題