大規模サイトでのバックグラウンドタスクのサービス


49

StackOverflowの興味深い問題を扱っています。

私たちには、「すぐにやる必要がある」小さなタスクがたくさんあります。例は、「関連する質問」リストの更新です。過去に行ったことは、これらのタスクを一部のユーザーのページロードにピギーバックすることです。

これは決して理想的ではありませんでしたが、それほど目立ちませんでした。SOが1,000,000の疑問符を通過したので、それらの不運なユーザーはそれを感じ始めています。

自然な解決策は、これらのタスクを実際にバックグラウンドにプッシュすることです。私が検討しているこれを行うには2つの広い方法があります。

1. IISでカスタムスレッドプール/ワークキューとして

基本的に、IISに干渉しないようにいくつかのスレッド(非ThreadPool)をスピンアップし、Funcsを入れているコレクションにサービスを提供します。

ここでの大きな利点はシンプルです。マーシャリングについて心配する必要も、外部サービスが起動して応答することを確認する必要もありません。

また、すべての共通コードにアクセスできます。

欠点は、バックグラウンドスレッドを使用しないことです。私が知っている異議はすべて、IISの飢star(ThreadPoolを使用している場合)とスレッドのランダムな消滅(AppPoolのリサイクルのため)に集中しています。

ランダムスレッドデスを非問題にするための既存のインフラストラクチャがあり(基本的にタスクの検出は中止されています)、スレッド数の制限(および非スレッドプールスレッドの使用)も難しくありません。

IISプロセスのスレッドプーリング/ワークキューに他の異議がありませんか?

ここでは実際には対処されなかったため、StackOverflow移動しました。

2.サービスとして

サードパーティのソリューション、またはカスタムソリューションのいずれか。

基本的に、プロセスの境界を越えて何らかのサービスにタスクをマーシャリングし、それを忘れます。おそらく、生のSQL +接続文字列の一部のコードをリンクしている、または制限しているのでしょう。

プロは、これを行うための「正しい方法」であるということです。

短所は、できることが非常に制限されているか、このサービスをコードベースと同期させるために何らかのシステムを作成する必要があることです。また、監視とエラーログのすべてをなんらかの方法で接続する必要があります。これは、「IIS内」オプションで無料で取得できます。

サービスアプローチには他の利点や問題がありますか?

簡単に言えば、アプローチ#1を実行不可能にする予測不可能で克服できない問題がありますか。もしそうなら、アプローチ#2を検討する必要がある優れたサードパーティサービスはありますか。


正しい方法とは、他の方法に進むことにしたとき、振り返って正しい方法でやるべきだと言う方法です。賢明に選択してください。ただし、この特定の問題についてコメントできるほどIISの世界に精通していません。
クリス

2
私は似たようなシナリオを持っているので(はるかに小さいスケールで)興味があり、私もランダムなユーザーの不運な接続に便乗しているだけです。私は最善の解決策に精通していないので、ここで説明します。:-)
pc1oad1etter

7
これがStackOverflowにない理由はわかりません。これは工学的なトレードオフであり、主観的な評価ではありません。あなたはさまざまなアプローチの分析を求めています-それはすべて客観的です。分析によってトレードオフが正確に明確になった場合にのみ、それに対する主観性があり、あなたの質問を見る限りでは、「より重要なこと、私の時間とサーバーリソース、またはユーザーの時間を見つける必要がありますか? ' または類似のもの。
ジョレン

@ケビン・モントローズ-あなたのコメントから、あなたは「間もなく行われる必要がある」と「間隔を置いて予定される」を区別しているように見えます。これらは2つですなぜあなたは上の手の込んだ異なる異なるパターン/インフラストラクチャを必要とバックグラウンドタスクの種類は?
ポートマン

@Portman-基本的な違いは、「間もなく」タスクを投機的に実行できないことです。実行する必要があることがわかるまで待つ必要があります。エンベロープ計算の裏には、「関連する質問」クエリ(多くの1つだけ)を「ダム」cronタブに移動する場合、約1時間かかります。すべての質問に取り組むための1週間の確実な実行 通常、ユーザーエクスペリエンスに影響を与えることなく、できるだけ早く実行することも望まれますが、間隔タスクは5分に1回よりも頻繁に実行することはできません(通常ははるかに少ない頻度で実行できます)。
ケビンモントローズ

回答:


17

数週間前に、SOで同様の質問をしました。簡単に言えば、しばらくの間、私のアプローチはWindowsサービスを開発することでした。NServiceBus(基本的にはカバーの下にあるMSMQ)を使用して、Webアプリからサービスへの要求をマーシャリングします。以前はWCFを使用していましたが、分散トランザクションをWCF上で正常に動作させることは、常に苦痛のように思えました。NServiceBusはトリックを行いました。データをコミットし、トランザクションでタスクを作成でき、その時点でサービスが稼働しているかどうかを心配する必要はありませんでした。簡単な例として、電子メール(登録電子メールなど)を送信する必要がある場合、トランザクションでユーザーアカウントを作成し、Windowsサービス(電子メールを送信するため)にシグナルを送信します。サービス側のメッセージハンドラはメッセージを取得し、それに応じて処理します。

ASP .NET 4.0およびAppFabricがリリースされて以来、上記のメカニズムに代わる多くの実行可能な代替手段があります。上記の質問に戻って、AppFabricのAppInitialize(net.pipe経由)と、ASP .NET 4.0のAuto-Start機能を使用して、WebサービスとしてのWindowsサービスの開発を実行可能な代替手段にしました。私はこれをいくつかの理由で始めました(展開されている最大のものはもはやお尻の痛みではありません):

  1. サービス上でWeb UIを開発できます(Webアプリとして実行されているため)。これは、実行時に何が起こっているかを確認するのに非常に役立ちます。
  2. Webアプリの展開モデルは、サービスアプリケーションで機能します。
  3. IISは、アプリケーションの障害を処理するためのいくつかの便利な機能を提供します(Windowsサービスといくつかの点で似ています)。
  4. Web開発者は(当然)Webアプリの開発に精通しており、ほとんどの人はWindowsサービスを開発する際のベストプラクティスについてあまり知りません。
  5. 他のアプリが使用するAPIを公開するための多くの代替手段を提供します。

このルートに行く場合(元の投稿からコピーして貼り付けてください)、別のWebアプリケーションでバックグラウンドロジックを実行することを絶対に検討します。これにはいくつかの理由があります。

  1. セキュリティ。実行中のバックグラウンドプロセスに関する情報を表示するUIには、別のセキュリティモデルがある場合があります。このUIをopsチーム以外に公開したくありません。また、Webアプリケーションは、高い権限セットを持つ別のユーザーとして実行される場合があります。
  2. メンテナンス。フロントエンドWebサイトを使用するユーザーに影響を与えずに、バックグラウンドプロセスをホストするアプリケーションに変更を展開できると便利です。
  3. パフォーマンス。ユーザーリクエストを処理するメインサイトからアプリケーションを分離することは、バックグラウンドスレッドが受信リクエストキューを処理するIISの機能を低下させないことを意味します。さらに、必要に応じて、バックグラウンドタスクを処理するアプリケーションを別のサーバーに展開できます。

これを行うと、マーシャリングの側面に戻ります。WCF、NServiceBus / RabbitMQ / ActiveMQなど、バニラMSMQ、RESTful API(MVCなど)はすべてオプションです。Windows Workflow 4.0を使用している場合、Webアプリが使用できるホストエンドポイントを公開できます。

サービスのWebホスティングアプローチはまだかなり新しいものであり、正しい選択であったかどうかは時間だけがわかります。これまでのところとても良い。ちなみに、AppFabricを使用したくない場合(何らかの奇妙な理由でWindows Server Web Editionがサポートされていないため、できませんでした)、Guの投稿で言及されているAuto-Start機能はうまく機能します。ただし、applicationhost.configファイルには近づかないでください。その投稿のすべては、IISコンソール(メインサーバーレベルの構成エディター)を介してセットアップできます。

注:私はもともとこのメッセージにさらにいくつかのリンクを投稿しましたが、残念ながら、これはこの交換への最初の投稿であり、1つのリンクのみがサポートされています!Googleに「Windowsサービスへの死... Long Live AppFabric!」を得るために、基本的に他に2つありました。および「auto-start-asp-net-applications」。ごめんなさい


サービスとして独立したウェブサイトを使用しての基本的な考え方は...私は考えられていなかった興味深いものです
ケビン・モントローズ

ローランド、私はここで何かを見逃しているかもしれませんが、あなたはあなたのNServiceBusハンドラー内からWindowsサービスと対話していると言っているようです。私が正しいなら、なぜあなたはNServiceBusメッセージハンドラからメールを送信しないのか尋ねることができますか?これは開発、テスト、展開が非常に簡単です?
ショーンカーロン

WebサイトはWindowsサービスにメッセージを送信します。WindowsサービスのNServiceBusメッセージハンドラーは、メッセージを取得して送信します。本質的に、それはあなたが記述しているプロセスと同じです。
ローランド

22

実際には、Windowsにはバックグラウンドサービスを実行する3番目の方法があり、UNIXの世界では非常に一般的です。3番目の方法は、CRONインフラストラクチャの一部を実行するジョブです。Windowsでは、これはとして知られてtask schedulerおり、定期的にコードを実行するために非常に一般的です。これを使用するには、事前定義されたスケジュールで実行されるコマンドラインアプリを作成します。この利点は、プロセスがサービスのように稼働し続けているかどうかを心配する必要がないことです。何らかの理由で失敗した場合、次回起動するだけです。

特定のタスクのマーシャリングに関しては、これらのタスクを永続的なバイナリストレージに保存するだけです。コマンドラインアプリがストレージからそれらを選択して実行するまで。これは、過去にCassandraデータベースを特定のユーザーのバックグラウンドタスクに詰め込むためのセッション状態プロバイダーとしてCassandraデータベースを使用し、コマンドラインにそれらを選択させてユーザーに実行させることで行いました。

これは典型的なマーシャリングソリューションではなかったかもしれませんが、スケジュールされたタスクがシャットダウン、ネットワークの問題、および中央にあるために任意のマシンがタスクを実行できるため、非常にうまく機能し、非常にエレガントなソリューションであることが判明しました格納されます。

恥知らずなプロモーションですが、これが私のプロジェクトであり、簡単に説明した解決策がプロジェクトを作成した理由です:http : //github.com/managedfusion/fluentcassandra/


2
シェルアクセスがないため、共有ホスティングサービスでこれを行います。重要なことを行うPHPページを作成してから、定期的にwgetまたはlynxを使用してページをロードするcronジョブを作成します。これは、まさにこの場合に機能し、非常にシンプルで、現在の方法を変更する必要のないタイプのように聞こえます。
リケット

なんて簡単なソリューション。それは、私自身のプロジェクトのアイディアを引き起こし、私はまだ検討していませんでした。さらに、既存のコードベースに完全にアクセスできます。ソリューションにコンソールプロジェクトを追加し、既存のプロジェクトを参照するだけです。
ティムマーフィー

10

Cron + Webアプリ

これは、Webファームに合わせて水平方向スケーリングし、すでに知っているWebテクノロジースタックを使用していることを確認する、戦闘テスト済みの設計です。

仕組みは次のとおりです。

  1. Webアプリケーションでコントローラー/アクションを作成して、スケジュールされたバックグラウンドタスクを処理します。慣例により、私は通常私のものを呼び出しますhttp://mydomain.com/system/cron
  2. セキュリティのため、このアクションはローカルネットワーク上の認証済みIPアドレスのみにロックダウンする必要があります。
  3. 別のマシンにWgetをインストールし、wgetがステップ1からリソースをフェッチするようにスケジュールされたタスクをセットアップします。タスクを必要な頻度で実行できます(通常は30秒を選択します)。適切なcookie引数をWgetに渡すことを忘れないでください。これにより、Webアプリが認証されます。
  4. 冗長性のために、2番目のマシンに2番目のスケジュールされたwgetをインストールすることもできます。

やった!これで、30秒ごとに呼び出されるルートができました。また、リクエストの処理に5分かかる場合、ユーザーのページリクエストの一部ではないため、誰も気にしません。

cronアクションは非常に単純な探して終わる:彼は、特定の周波数で実行するためのメソッドのリストを持っています。要求が届くと、実行する必要があるメソッドがあるかどうかを確認し、適切なメソッドを呼び出します。これは、データベースのスケジュールを制御できることを意味します。おそらく、サイトの他の重要な構成データがすでにたくさんある可能性があります。

さらに重要なことは(あなたにとって)、これはあなたの仕事が決まったスケジュールで呼ばれる必要がないことを意味します。メソッドをいつ実行するかを決定するための任意のロジックを作成できます。

長所と短所

長所
  • ASP.NET MVCコードの記述は既に非常に得意であるため、これにより、他のソリューションを記述するプラットフォーム同じプラットフォームでバックグラウンドタスクを記述できます。
  • タスクはWebアプリと同じコンテキストで実行されるため、キャッシュ共有し、既存のヘルパーメソッドを利用できます
  • wgetが負荷分散された URIをフェッチしている場合、バックグラウンドタスクも負荷分散されています。
  • 同時展開 -Webアプリがバックグラウンドタスクロジックと同期することを心配する必要はありません。すべて同じ展開にあるためです。
短所
  • 何年もの間、このデザインは「高度に結合されている」と私に言っていた人もいますが、押されたとき、彼らはなぜそれが悪いのかを明確にできませんでした。

注:質問や懸念がある場合は、コメントを追加してください。詳しく説明させていただきます。


7

私は現在のアプリケーションでこれを行うためのあらゆる可能な方法を試して使用しました。私はあなたが現在やっていることと同じことを始め、ユーザーのリクエストに便乗してデータを入力し、その後キャッシュしていきます。これも悪い考えだと気付きました(特に、複数のWebサーバーに拡張するにつれて、より多くのユーザーがヒットします)。

また、ASP.NETアプリのURLにヒットするスケジュールジョブもあります。これは適切なソリューションですが、1つのWebサーバーを超えてスケ​​ーリングする分を分解し始めます。

現在、2つの異なる方法を使用しています。どちらもすばらしい小さなライブラリであるQuartz.NETを使用しています。1つ目は、ASP.NETとインプロセスで実行されるQuartz.NETです。global.asaxでセットアップされ、数分ごとに実行されます。これを使用してASP.NETキャッシュを帯域外で更新します。これがASP.NETの一部として実行される唯一の理由です。

2つ目は、DaemonMasterと呼ばれるQuartz.NETをラップするライブラリを作成したことです。これにより、DLLをディレクトリにドロップして、Windowsサービスで実行できるようになります。Windowsサービスでの作業の面倒な部分を避けるのに役立ち、またQuartz.NET APIをクリーンアップすることがわかりました。DaemonMasterを介して実行されるサービスには2つの異なる種類があります。1つ目は、毎晩またはX分ごとに実行する必要があるジョブです。他のジョブは、ASP.NETアプリケーションからのデータに基づいてキューから処理されます。ASP.NETアプリはRabbitMQにJSONオブジェクトをドロップし、サービスはRabbitMQをポーリングしてからデータを処理します。

これに基づいて、Windowsサービスにアクセスし(DaemonMasterをチェックアウト)、必要に応じてRabbitMQなどのキューを使用して、ASP.NETアプリからサービスにデータを渡すことをお勧めします。 。キャッシュを読み込んでいる場合は、ASP.NETで実行するのが理にかなっています。


6

私はそれを正しい方法で行い、「キュー」を監視するWindowsサービスを実行します。「キュー」と言うのは、MSMQを使用したプログラミングがホットポーカーを眼球に刺すようなものだからです。

RailsのDelayed :: Jobのシンプルさに夢中になり、.NETでも同様のことが簡単にできるようになりました。

基本的には、あらゆる種類SomethingOperationPerform()メソッドを持つもの)を追加します。次に、関連するパラメーターをシリアル化し、優先順位、何らかの既定の再試行動作を与え、データベースに挿入します。

サービスはこれを監視し、キュー内のジョブを処理します。


関連するパラメーターのシリアル化は、実際には「単なる」ではなく、ほとんど「すべて」です。別のプロセスアプローチについての私の大きな留保のその1 ...
ケビン・モントローズ

ええ、それは私が使用したのと同じ種類のソリューションですが、オブジェクト全体をバイナリとしてデータベースにシリアル化し、実行するためにそれらを引き出しました。私は永続ストレージとしてCassandraを使用し、タスクを実行および実行するコマンドラインアプリのCRONスケジューラーとしてタスクスケジューラーを使用しました。
ニックベラディ

メッセージに単純なデータを含めることから始め、オブジェクト全体をスローしました。それでもうまくいきました。他の利点もあるため、分離を検討します。
ネイサンパーマー

@Kevin -のみ我々は....シリアライズの歴史の多くが付いている一部の人々があった場合
マルクGravell

4

サービスバス/メッセージキュー/サービスのアプローチには非常に満足しています。基本的なアーキテクチャはこれです。

Webサイトはメッセージをキューに送信します

bus.Send(new ProjectApproved()); // returns immediately

Windowsサービスは、独自の時間にメッセージを受信して​​処理します

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Do something "offline"
   }
}

利点は、ユーザーも接続されているフロントエンドサービスに遅延がないことです。メインサイトを中断せずに、Windowsサービスをシャットダウンしてアップグレードできます。さらに、それは非常に高速です。

メッセージ内のすべてのデータを保存できない場合は、いつでも保存して後で取得できます。RavenDBMongoDBなどのドキュメントストレージメカニズムを使用することをお勧めします。ここでは、クラスを変更せずに保存することが非常に簡単です。

Webサイトはメッセージをキューに送信します

// Save your object
store.Save(completeProject);

// Send a message indicating its ready to be processed
bus.Send(new ProjectApproved() { ProjectId = completeProject.Id });

Windowsサービスは、独自の時間にメッセージを受信して​​処理します

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Retrieve your object back
      var completeProject = store.Get(Message.ProjectId);
   }
}

物事を簡単にするために、Rhino ESBTopshelfを使用します。構成は非常に簡単で、これを既存のアプリケーションの所定の場所に配置するのにかかる時間はごくわずかです。


とにかく、CQRSとサービス・バスを使用すると、常にあなたのスケーラビリティを向上させるための良い方法です
thinkbeforecoding

3

なぜこの2つの組み合わせが実行可能なオプションではないのか興味があります。今、あなたはページビューでジョブをトリガーします。いくつかの不幸な樹液がページが現れるまで10秒待って立ち往生しています。少なくともそれはあなたの現在の方法の私の理解です。

ただし、これらのジョブはサイトの拡大に​​伴い実行に時間がかかり、サイトでのユーザーエクスペリエンスを狂わせたくありません。数人(または多分)の不運なユーザーでさえ、一日を通してではないので、バックグラウンドでジョブをスケジュールすることを考えています。

バックグラウンドジョブを定期的に実行すると、訪問者を真似できない理由がわかりません。今、私はWindowsプログラマーではありませんが、Linuxの世界では、定期的な間隔で実行されるcronジョブをセットアップし、2行のコードを作成します。

#!/bin/bash
wget -O /dev/null http://stackoverflow.com/specially_crafted_url

両方のシステムの長所を組み合わせています。バックグラウンドで行われます。ユーザーには影響しません。引き続きページビューを使用してジョブを開始します。このアプローチが以前に使用されたことを見ました。昔の単純な道と、より複雑な道が道をたどる中間点になりがちです。

更新

Webサーバー自体でジョブランナーを実行すると、負荷分散の問題を回避できると思います。ジョブランナーはジョブキューからURLを取り出し、次のように実行します。

wget -O /dev/null http://localhost/specially_crafted_url

ジョブ/メッセージングキューの性質により、ジョブはジョブランナー間で均等に分散されます。つまり、specially_crafted_urlは最終的にWebサーバー間で分散されます。


予測可能な間隔で実行されるすべてのことについて、すでにそれを行っています。残されているのは、あまりにも前もって予測できないものです。たとえば、「関連する質問ブロック」は、最近表示された質問でのみ更新されます。タグ付き質問リストも同様に、誰かがそれらのタグをチェックしたい場合にのみキャッシュされます。100万を超える質問があり、25kのタグに近づいているため、「万が一に備えて」関連するすべてのタスクを実行することはできません(2つの例にすぎません)。
ケビンモントローズ

SOは複数のサーバーに分割されるため、負荷分散の問題もあります。基本的に、stackoverflow.comにアクセスすると、常に同じサーバーにアクセスします。wgetアプローチでは、すべてのタスクを1つのサーバーにマーシャリングする(または負荷分散の設定を実際にやり直す)ことを余儀なくされ、これは非常に苦痛です。
ケビンモントローズ

物事が定期的に実行された場合でも、いいですね?私はあなたの言っていることを理解していますが、上で概説した方法論(および他の数人の人たちが言及したと思います)は変わりません。ページビューに「このジョブを実行する時間です」と表示されたら、ジョブをメッセージキューに保持します。長時間実行されているバックグラウンドジョブは、検出したジョブを実行します。この場合、ジョブはリクエストする必要があるURLにすぎません。heheコードベースを実行する必要がないので、おそらく月20ドルの共有サーバーでこれを設定できます。使いやすいメッセージングサービスについては、Amazon SQSをご覧ください。
mellowsoon

負荷バランスの問題について。意志があるところには、方法があります!stackoverflow.comにリクエストを送信する代わりに、IPアドレスを使用してサーバーをランダムにヒットさせることができます。ロードバランサーがCookieをチェックしてリクエストをパイプする場合、Cookieを偽造できます。IPアドレスをチェックする場合は、おそらくそれを偽造することもできます(サーバーからの応答を気にしないため)。
mellowsoon

ロードバランシングは、これを行わない理由ではないことに同意しました。のリクエストspecially_crafted_urlは既知のIPからのものであるため、ロードバランサーにルールを追加して、そのIPからのリクエストに対してのみラウンドロビンを実行できます。
ポートマン

2

純粋なサービスアプローチの欠点は、コードがサービスに分散し、コアアプリから離れていることだと思います。

これは、コードをまとめてサービスを簡素化する、バックグラウンドで時間に依存しない大きなバックグラウンドジョブで行ったことです。

  1. ジョブキュー(メモリ内またはDB、ジョブの種類に必要な永続性)を作成します。
  2. キューに入れられたジョブを実行するWebサービスを作成します
  3. 指定された間隔でWebサービスを呼び出すデッドシンプルサービスアプリは、すべての複雑なもの(ジョブの取得と実行)をコアコードベースのWebサービスに残します。

さらに簡単に、コンソールアプリで呼び出しを行い、タスクスケジューラまたはVisualCronを使用して「サービス」に変換します。


1
仕事中の重要なアプリケーションで、これを正確に持っています-定期的にWebアプリをトリガーするWindowsサービス。Webアプリはステートレスのままで、必要に応じてデータベースから状態を取得します。御Works走。
ベヴァン

1

私はTopShelfが好きでした。シンプルさを保ちながら、Windowsサービスとして適切な方法で実行します。基本的に、コンソールアプリを作成し、約15〜20行のコードを追加してから、サービスとしてインストールします。

http://code.google.com/p/topshelf/


1

Webサーバー上で実行され、さまざまなタスクを実行するメンテナンスURLに定期的にアクセスする非常に単純なWindowsサービスを用意してください。特定のリクエストで行う作業量を調整します。


1

ここでは明らかな傾向に逆らい、IIS内モデルに進むことを提案します。私は自分でそれを使用し、それは本当にうまく機能します。まともなスレッドプールクラスを実装することは、それほど難しくありません(長年にわたって、スレッドプールクラスを拡張して、スレッドの動的な作成と破棄、ジョブの再試行などをサポートしています)。利点は次のとおりです。

  • 監視する外部サービスはありません
  • 実装の単純さ:クロスプロセスマーシャリングなし、高度なジョブ監視なし
  • まだIISプロセス内にいるので、通常のログ記録などをすべて実行できます(複数のログファイルは必要ありません)
  • 非常に単純化された展開(サービスを更新する場合、サービスを停止し、ファイルをコピーし、サービスを開始する必要があります-これは、Webサイトコードに対する通常の更新に追加されます)

私の意見では、IIS内のソリューションは、ランダムなページビューに作業を便乗させることからの「次のステップアップ」にすぎません。


1

Resqueはいいです。または、完了後に結果の値を通知する必要がある場合は、Kthxbyeでさえもです。

Redis / Rubyベースのtho。

正直なところ、サービスベースのアプローチを行っている場合、現在のプラットフォームにスーパーインテグレーションする必要はありません。これはプラスに思えます。(何らかの監視を使用して)実行され、ジョブを完了するセットアンドフォーゲットシステムになることを願っています。データベース情報を更新/変更するだけなので、同じプラットフォームで実行する必要があるかどうかはわかりません。

特にスレッド化の問題に対処しているように見えるため、この種のワークアウトを別のエンティティにファーム化すると、はるかに多くのことをはるかに少なく逃げることができます。ResqueKthxbyeは両方とも、処理を別々のプロセスに移動して、OSが並行性を処理できるようにします。

レスク

クスクスバイ


偉大な名前のためだけにKthxbyeを試してみなければなりません!
ネイサンパーマー

かなり素晴らしい。次はORLYですか?図書館。おそらく何らかの種類の統計監視のために...;)
ルカス

0

MSMQキューをリッスンするWASホストWCFサービスを使用します。

プロの

  • Webアプリからの一方通行のメッセージを送信して忘れる

  • MSMQ / WCFスロットリングと再試行

  • 配達保証; D

  • デッドレター管理

  • 分散処理

  • WAS / MSMQアクティベーション

コンの

  • MSMQ(死んでいない...まだ)

WCFのMSMQ機能により、MSMQの使用は非常に便利です。はい、構成で出血しますが、犠牲よりも利点が大きくなります。


0

Webアプリケーションを開発するときに、これに何度か遭遇しました。タスクを実行するWindowsコンソールアプリケーションを作成し、実際にタスクを実行するために頻繁に実行されるスケジュールされたタスクを作成することで、この問題を解決しています。


0

Rxと次のようなものを使用して、バックグラウンドスレッド(または多くのバックグラウンドスレッド)に作業を振り分けることができます。

var scheduler = new EventLoopScheduler( SchedulerThreadName );
_workToDo = new Subject<Action>();
var queueSubscription = _workToDo.ObserveOn( scheduler ).Subscribe( work => work() );
_cleanup = new CompositeDisposable( queueSubscription, scheduler );

使用するには:

var work = () => { ... };
_workToDo.OnNext( work ); // Can also put on error / on complete in here

1つしか存在しないクラス内ですべてをホストします(別名シングルトンですが、適切に実行します-IoCコンテナーを使用してライフスタイルを決定します)。

EventLoopScheduler(単一のスレッドを実行する)を使用する代わりにカスタムスケジューラを記述することにより、スレッドプールなどのサイズを制御できます。


0

私はこのようなことを数回実装しました。Windowsでは、さまざまなタイミングで何かを実行するpythonコマンドラインプログラムを設定します。このプログラムは、ポート上のxmlrpcインターフェイスも公開します。次に、スケジュールされたタスクジョブが1分ごとに実行され、xmlrpcインターフェイスを照会します。起動していない場合は、起動しようとします。それができない場合、私にメールします。

利点は、実行するジョブがcronまたはスケジュールにバインドされていないことです。秒単位で実行されるプロセスジョブがありますが、新しいジョブを開始するまでの間に待機する時間が長くなります。また、結果に基づいてインテリジェントに動作するために使用できます。500エラーが発生しましたか?本当に長い遅延がありましたか?他のことをしてください。別のサービスに通知してください。等。

そして、同じシステムがunixで動作しますが、わずかな修正が必要です。


0

あなた自身には答えはありませんが、問題は鐘を鳴らします- ポッドキャストで一度議論したランダムな人を覚えています。

Spolsky:ブログで尋ねた質問の1つが、一般的なメンテナンスの繰り返しタスクをどのように処理すべきかということに気付きましたか?

アトウッド:はい。

Spolsky:それは公正な特徴ですか?すべてのWebサイトには、Webページの読み込み時に実行したくないタスクがいくつかありますが、何らかの繰り返しを実行して実行する必要があります。

Atwood:ええ、バックグラウンドタスクのようなものです。

スポルスキー:ええ、それで、あなたは何を理解しましたか?

アトウッド:さて、私はもともとツイッターで質問しました。なぜなら、私は単に軽いものが欲しかったからです。私は本当にWindowsサービスを書くのが好きではありませんでした。それは帯域外コードのように感じました。加えて、実際に作業を行うコードは実際にはWebページです。なぜなら、私にとってそれはWebサイトでの作業の論理単位であり、Webページだからです。ですから、実際にウェブサイトにコールバックしているようなものです。ウェブサイトでの別のリクエストのようなものです。そのため、私はそれをインラインのままにしておくべきものと考えました。本質的には、有効期限が固定されたアプリケーションキャッシュに何かを追加することでした。その後、コールバックがあるため、その有効期限が切れると、作業を行う特定の関数を呼び出し、同じ有効期限でキャッシュに追加し直します。


1
ええ、それはStackOverflowがなっているよりもはるかに小さいサイトで動作します。残念ながら、スケールは大きな問題です(または幸いなことに、見方によっては)。
ケビンモントローズ

@ケビン・モントローズ、私はここで完全な無知を嘆願します。秘密のWebページで作業を実行し(おそらく小さな単位で)、他のどこかでページ/ cronジョブを更新することでスケーラブルでない理由を説明してください。私はあなたが正しいことを疑いませんが、私は学びたいです。
奇妙な思考

特定の提案(キャッシュの有効期限)は、すべてのキャッシュの有効期限(ASP.NET)が単一のスレッドを実行するため、スケールしません(SOなどの小規模なサイトの巧妙なハックです)。単一のサーバーが大きくなりすぎて(SOは3であり、まだ成長している)、cronタスクは単一のサーバーにヒットするため、cronタスクはスケーリングしません(少なくとも、不変式を変更すると、負荷が非常に大きくなります。バランス設定)。これらのタスクは数分で繰り返されるため、cronタスクも非常に頻繁に実行する必要があります。
ケビンモントローズ

頻度の低い実行、一定の間隔、タスク、バッジの付与や毎日の電子メール通知などに「cronスタイル」のスケジューリングを使用していることに注意してください。
ケビンモントローズ

0

タスクキューJava APIの概要

タスクの概念
App Engineバックグラウンド処理では、タスクは小さな作業単位の完全な説明です。この説明は2つの部分で構成されています。

  • タスクをパラメーター化するデータペイロード。
  • タスクを実装するコード。

オフラインWebフックとしてのタスク
幸いなことに、インターネットは、HTTP要求とその応答という形で、そのようなソリューションを既に提供しています。データペイロードは、Webフォーム変数、XML、JSON、またはエンコードされたバイナリデータなどのHTTPリクエストのコンテンツです。コード参照はURL自体です。実際のコードは、応答を準備する際にサーバーが実行するロジックです。


GAEタスクキューAPIを使用することはお勧めしませんが、モデルに従います。彼らはしばらくの間それを熟考し、その実装を書きました。
antony.trupe

0

両方をする

現在ユーザーのリクエストに便乗している作業を行う質問パスにオプションのパラメーターを追加します。

大規模サイトでのバックグラウンドタスクのサービス

各サーバーで実行されるコンソールアプリを作成し、IISログ共有バイナリを開き、ファイルの現在の最後まで読み取ります。IISがログをフラッシュしたときに更新を収集するために、filesystemwatcherまたは時間間隔を使用して先読みします。

この情報を使用して、現在表示されているページを判別します。

解析されたログのページURLを使用して、webclientオブジェクトを使用してlocalhostの「extrastuff」バージョンのURLを呼び出します。

各ログ期間の終わりにファイルを切り替えるためのコードを追加するか、各ログ期間のプロセスを再起動します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.