私はこの記事を読んだばかりで、混乱しています。
1つのwebappと1つの別個のアプリケーションが「ワーカー」として動作し、両方が同じデータベースを共有しているとしましょう。
ああ、私は「共有」と言いました。しかし、この記事は何について警告していますか?:
第4に、アプリケーション(またはサービス)間でデータベースを共有することは悪いことです。そこに無定形の共有状態を置くのはあまりにも魅力的であり、それを知る前に、巨大に結合したモンスターができます。
=>反対。別個のアプリケーションが依然として同じユニットの一部である場合があります。したがって、この場合、「カップリングの問題」という概念は意味がありません。
続けましょう:webappはクライアントHTTPリクエストを処理し、いつでもいくつかの集約(DDD用語)を更新して、対応するドメインイベントを生成します。
ワーカーの目標は、必要なジョブを処理することにより、これらのドメインイベントを処理することです。
ポイントは:
イベントデータをワーカーに渡す方法
読んだ記事が推進する最初の解決策は、優れたメッセージ指向ミドルウェアであるRabbitMQを使用することです。
ワークフローは簡単です:
Web dynoがイベントを生成するときはいつでも、RabbitMQを介してイベントを発行し、ワーカーにフィードします。
欠点は、潜在的な送信エラーやハードウェアの問題に対処せずに、集約更新のコミットとイベントの発行の間の即時の一貫性を保証するものがないことです。それは別の主な問題です。
例:集約の更新が成功せずにイベントが発行された可能性があり、その結果、ドメインモデルの誤った表現を表すイベントが発生しました。
グローバルXA(2フェーズコミット)が存在すると主張できますが、すべてのデータベースまたはミドルウェアに適合するソリューションではありません。
それでは、この即時の一貫性を確保するための優れたソリューションは何でしょうか?:
IMO、集計更新と同じローカルトランザクションでデータベースにイベントを保存します。
シンプルな非同期スケジューラが作成され、データベースから現在の未公開イベントをクエリし、それらをRabbitMQに送信します。RabbitMQはワーカーにデータを入力します。
しかし、なぜwebapp側で余分なスケジューラーが必要なのか、そしてところで:この場合RabbitMQが必要なのはなぜですか?
このソリューションでは、特にデータベースが共有されているため、RabbitMQは不要である可能性があります。
実際、どのような場合でも、即時一貫性にはデータベースからのポーリングが含まれることがわかりました。
したがって、なぜワーカーはこのポーリングに直接責任を負わないのでしょうか?
したがって、なぜWeb上の多くの記事が、データベース指向のキューイングを批判しているのに、メッセージ指向のミドルウェアを宣伝しているのか疑問に思います。
記事の抜粋:
シンプルで、仕事に適したツールを使用します。このシナリオは、メッセージングシステムを求めています。上記のすべての問題を解決します。これ以上のポーリング、効率的なメッセージ配信、完了したメッセージをキューからクリアする必要、共有状態はありません。
そして、即時の一貫性は無視されますか?
要約すると、データベースが共有されているかどうかにかかわらず、ケースが何であれ、データベースポーリングが必要なようです。
いくつかの重要な概念を見逃しましたか?
ありがとう