紹介/システムアーキテクチャ
- サーバA - Laravelのインストール、データベース
- サーバーB - RabbitMQのサーバー
- サーバーC - Laravelのインストール、データベースB
サーバーAはAPIエンドポイントであり、リモートソースからの呼び出しのみを受信します。コールに応じて、RabbitMQサーバ(サーバB)にジョブが追加されます。このジョブは、サーバCによって処理/聴取されます。Laravel - リモートシステム上で処理されるべき仕事のシリアライズ
サーバーはサーバーCによって処理され、まったく同じジョブのローカルコピーが含まれています。ジョブハンドラのコードとコンストラクタを以下に示します(ジョブコード)。
問題: サーバーAがジョブをシリアル化し、それが唯一のデータベースB(サーバーC)に存在するモニターについての情報にアクセスしようとすると、キューに追加することはできません。 サーバAにはモデルのコピーが含まれていますが、実際のデータベーステーブルやレコードは使用されていないため、そのデータは含まれていません - ジョブをシリアル化して「これは何ですか」と言うだけです(サーバC )しなければならない」
しかし、ジョブの発行時には、データベース情報を取得しようとしています(必要な正確なデータをシリアル化する可能性があります)。レコードが存在しないため、処理できません。
私はLaravelのSerializesModels
を理解していて、具体的にはモデル呼び出し自体をシリアライズするだけで、実際にはデータベース関連は何もしませんでした。これは機能しているようには見えないか、間違っていると誤解しています。
回避策:一つの可能な回避策は、単にサーバーCにサーバーにデータベースへアクセス権を与えることであろう。この場合、高可用性を意図した設計(APIエンドポイントとキューは決して使用できないが、キュー・プロセッサがある場合がある)を破るため、オプションではありません。
コード
関連する求人コード
// 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のキュー・メカニックを使用していますか?
いつものように義務付けられています。