3

私はこのシナリオを持っていますが、どこから始めればよいか本当にわかりません。サーバーでホストされている Web サービスのようなアプリ (API の可能性もあります) があるとします。そのアプリは、いくつかのデータを処理するリクエストを受け取ります (何らかのメソッドを介して、processData(data theData) を呼び出します)。

反対側には、データを処理するロボット (同じサーバーにインストールされている可能性があります) があります。そのため、Web サービスは共通のデータベース (両方のプログラムがアクセスできる) にリクエストを挿入し、その行が変更されて結果が返されるのを待つことになっています。

ロボットは定期的にデータベースをチェックして新しい行を探し、データを処理し、その行に何らかのフラグを設定して、データが処理されたことを示します。

ここでの主な問題は、メソッド proccessData(..) がデータ行の変更をチェックするために何をすべきかということです。

私はそれを行う 1 つの方法を知っています: x 秒ごとに行をチェックする反復ブロックを作成できます。しかし、私はそれをしたくありません。私がやりたいことは、行が変更されたときにトリガーされる、ある種のイベントリスナーを構築することです。非同期プログラミングが含まれる可能性があることは知っています

私は夢を見ているかもしれませんが、それは Web 環境でも可能ですか?

SqlDependency クラス、Async および AWait クラスなどについて読んでいます。

4

2 に答える 2

0

Message Queueについて言及していますか? .Net フレームワークは、この機能を既に提供しています。Web サービスにアプリケーション レベルのキューを管理させます。ロボットは、実行するために同じ Web サービスを要求します。ジョブに必要なデータが小さいと仮定すると、すべてをメモリに保持できます。まだデータベースを持っていない場合は、データベースを使用したくありません。

于 2013-10-16T22:55:58.010 に答える
0

この分散システムの設計をどの程度制御できるかにもよりますが、一歩下がって、これまで問題を絞り込んできたソリューションのドメインの外で考えてみると、そのアーキテクチャにとってより良い場合があります。「主な問題」は、分散サービスが共通データベースを介して相互に通信する方法を見つけることであることがわかりました。多分それはあなたが挑戦すべき考えです。

これらのコンポーネントが通信するための潜在的な方法は多数あります。設計目標が待ち時間を短縮してポーリングを回避することである場合、実際には、この作業項目の完了を通知する必要があるサービスに通知するのが正しい方法である可能性があります。それをすぐに。ただし、将来、このシステムのスループットを向上させる必要がある場合は、作業項目を一括で処理し、代わりに情報をポーリングすることが唯一の実行可能なオプションになる可能性があります。これが、私の回答をもう少し一般的に表現し、この分散システムの設計をより抽象的に議論することにした理由でもあります。

この検討の後も回答が変わらず、すぐに通知が必要な場合は、作業項目を処理するコンポーネントから、通知が必要なコンポーネントに通知することを検討してください。分散システムの一般的な設計原則として、特定のデータ セットに対して最も信頼できるコンポーネントを、そのデータに関する要求に応答するコンポーネントにすることが最善です。この場合、取得しているデータは作業項目の完了ステータスであるため、これに対応する最適なコンポーネントは、作業項目を完了しているコンポーネントです。そのコンポーネントが、呼び出し元のクライアントとコンポーネントにその完了を通知する方がよい場合があります。ここだ』

ただし、コンポーネント間の結合を減らしたり、他のコンポーネントと直接通信するためのアクセスがないなど、そのような呼び出しをしたくない正当な理由があると思います。Windows の MSMQ や Windows Azure のキューなど、このような通知を可能にする多くの通信プリミティブがあります。また、システム内の通信が 3 番目のコンポーネントに依存しているなどの理由もあり、システムの可用性が低下し、停止につながる可能性があります。ここで自問したい質問は次のとおりです。「信頼性と可用性の観点から、このシステムの設計上の優先事項は何ですか?」

したがって、最初に解決しようとする主な問題は、もう少し抽象的なものだと思います。この分散システムのコンポーネントが通信するためのインターフェースはどのように見えるべきか?

このすべての後、これらのコンポーネント間の通信インターフェイスを SQL データベースにすることに決めたままの場合は、SQL で INSERT および UPDATE トリガーを使用して調べることができます。これらのコマンドの構文を簡単に調べて、実行されるストアド プロシージャを指定できます。これらのストアド プロシージャでは、新しい行の完了フラグを確認し、場合によっては日付で確認する行数を制限するか、最後に処理された作業項目の ID を取得する必要があります。次に、他のコンポーネントに通知するには、組み込みのストアド プロシージャを使用して、XP_cmdshellWindows でコマンド ラインを実行することもできます。実行するコマンドは、タスクの完了のためにサービスに ping を送信する単純なツールである可能性があります。

SQL クエリ通知を使用するというあなたの提案を最初に見落としてしまい申し訳ありません。これも実行可能な方法であり、Service Broker コンポーネントを介して機能します。SqlCommand通常データベースにクエリを実行するかのようにを定義し、これを のインスタンスに渡しSqlDependency、 というイベントをサブスクライブしOnChangeます。を実行するとSqlCommand、 に追加したイベント ハンドラが呼び出されますOnChange

ただし、イベント ハンドラーに渡されるオブジェクトからデータベースへの正確な変更を取得する方法がわからないSqlNotificationEventArgsため、クエリは、アプリケーションが作業項目が完了したことをいつでも通知できるように十分に具体的である必要がある場合があります。または、正確に何が変更されたかを知ることができるように、通知を受けるたびに、アプリケーションからデータベースへの別のラウンドトリップを実行する必要がある場合があります。

于 2013-10-16T22:05:34.830 に答える