質問

今は興味深い問題StackOverflow.

今日はこのままビバップからハードバップちょっとした"きぐっぽ"事ができます。例えば"アップデートに関する質問"のリストが表示されます。しました過去にはピギーバックタはもユーザーページ。

したことのない理想的なかったしますのでご連絡くださいこの経過は、1,000,000マーク、ヤンのユーザーを感じ始めます。

自然の値段が高くなりますが、実際に押しこれらの課題の背景のもの。り幅広い方ってこい。

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

基本的には、スピンの拡大にともない、最近、よく非ThreadPool, うとともに、これに干渉しませんIIS)スレッドとしてサービスのアイテムがコレクションの一部まshoving Funcs ます。

大proはシンプルさが人気です。いても安心の総力を結集し、何にでもいくかの外部サービスでの回答を得ました。

またアジアの共通コードです。

のシャトルバスが出来ないものとなっており使ってスレッド)。つかのすべてを中心としたお腹IISを使用している場合はThreadPoolのスレッドdieingランダムによAppPoolリサイクル)されます。

私たちの既存インフラのランダムスレッドの死は非課題(その検出が可能なタスクを放棄し、基本的には、制限の数のスレッド(非ThreadPoolックしなく。

私欠損その他の異議を唱えるIISプスレッドプール/ワークキュー?

移StackOverflow, がんに対す。

2.サービスとして

いずれも第三者溶液、またはカスタムします。

基本的には、私たちの整理作業の過程の境界に一部のサービスで忘れています。ここからはいつものコード、または制限される原SQL+接続文字列になります。

のプロであること、正しいやり方"ではないかと思います。

の連結実績はまだ非常に限に何ができるのか、またはいかができるシステムを本サービスを同社のドラインをサポートしています。今もフックのモニタリング、エラーログまで、なんとかした無料の"とIISの"オプションです。

その他の特典の問題のサービスのアプローチを考えていますか。

一言ではありまunforseen、乗り越問題とアプローチ#1机上の空論の場であるのに良い第三者サービスを拡大する見通しとなっていたアプローチ#2?

役に立ちましたか?

解決

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

ASP .NET 4.0とAppFabricがリリースされているため、上記のメカニズムには多くの実行可能な代替手段があります。上記の質問を参照して、AppFabricのAppinitialize(net.pipe経由)と、WebアプリとしてWindows Servicesを実行できるようにするASP .NET 4.0のオートスタート機能があります。私は今、これを多くの理由で始めました(展開であることはもはやお尻の痛みではありません):

  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エディションがサポートされていないため)、GUの投稿で言及されている自動スタート機能はうまく機能します。ただし、ApplicationHost.configファイルには近づかないでください。その投稿のすべては、IISコンソール(メインサーバーレベルの構成エディター)を介してセットアップすることができます。

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

他のヒント

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

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

これは典型的なマーシャリングソリューションではなかったかもしれませんが、スケジュールされたタスクがシャットダウン、ネットワークの問題、あらゆるマシンが中央にあるためタスクを実行できるため、非常にエレガントなソリューションであることが判明しました。保存されています。

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

Cron+Webアプリケーション

このバトルをデザイン 水平スケール とweb農場およびご利用中の web技術スタック ます。

この作品:

  1. コントローラを作成-アクションにウェブアプリケーションを扱う予定の背景事ができます。規則にしたがって、通常の通話鉱山 http://mydomain.com/system/cron.
  2. セキュリティのため、このディスカッションをロックしかいなくなったからで認証されたIPアドレスにすることをおすすめしています。
  3. は、別の機、インストール Wget および設定 予定のタスク いwgetターネット資源からのステップ1です。しないように注意してください課題として実行していまたは、オプト30秒)。忘れずに適切なクッキーの引数Wgetで認証が行われるwebアプリです。
  4. 冗長できるインストールも第二の予定wget次の機です。

イエーイ!しかし、これらのルートが呼び出される毎30秒です。およびご請求になる場合には、歩5分程でいますので、注意が必要のないユーザーのページです。

cron 動作終了までは非常にシンプルです:彼は、リストの方法を実行する周波数です。る請求があったときは、その手はそのままに、彼がある方法であればそのニーズに実行されると、適切な方法です。 これをコントロールすることが出来まューデータベース, おそらくすでに多くのその他の重要なコンフィギュレーションデータに対するものとします。

このように、このお仕事をなしと呼ばれるように固定します。まず論理する場合に実行メソッドになっています。

是非

プロ
  • だけで文章を書くASP.NET MVCコードで、こで書き方を背景に業務の ットフォーム 書いてます他のソリューションです。
  • の作業実行、同じコンテキストとしてwebアプリケーションです 共有のキャッシュ の利用 ヘルパーの方法 ることはすでに存在しています。
  • まwgetを取得する 負荷バランス URIのその背景に業務は負荷バランスしています。
  • 同時展開 -いの心配を同期でお客様のwebアプリバックグラウンドタスクの論理は、それらはすべて同じ展開。
連結実績
  • 長年に渡り、少数の人々が聞こえてくるこのデザインは"高い結合"が押しきれていない自然をなぜることは悪いことであると考えていた。

注意:がある場合は疑問やお悩みなど、 追記してくださいコメント.嬉しいとされる。

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

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

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

2つ目は、Daemonmasterと呼ばれるQuartz.netをラップするライブラリを書いたことです。これにより、DLLをディレクトリに簡単にドロップしてWindowsサービスで実行できます。 Windowsサービスで作業する際の迷惑な部分のいくつかを避け、Quartz.net APIをクリーンアップするのに役立つことがわかりました。 Daemonmasterを介して実行されるサービスは2つの異なるフレーバーのものです。最初のサービスは、毎晩またはXの1分間を実行する必要があるジョブです。他のジョブは、ASP.NETアプリケーションから入ってくるデータに基づいてキューから動作します。 ASP.NETアプリは、RabbitMQにJSONオブジェクトをドロップし、サービスポールRabbitMQでデータを処理します。

これに基づいて、Windowsサービス(およびDaemonmasterをチェックしてください)を使用することをお勧めします。必要に応じて、rabbitmqのようなキューを使用してASP.NETアプリからサービスにデータを渡すことをお勧めします。 。キャッシュをロードしている場合、ASP.NETで実行することは理にかなっています。そうでなければ、そうではないと思います。

私はそれを正しい方法で行い、「キュー」を監視するWindowsサービスを実行しています。 MSMQのプログラミングはあなたの眼球に熱い人々を貼り付けることに似ているので、私は「キュー」と言います。

私はのシンプルさに恋をしました 遅延::ジョブ Railsで、同様のことを.netで簡単に実行できます。

基本的に、あらゆる種類を追加します SomethingOperation (あるものがあります Perform() 方法)。次に、関連するパラメーターをシリアル化し、優先順位を与え、ある種のデフォルトの再試行動作を示し、データベースに詰めます。

サービスはこれを監視し、キューでジョブを機能させるだけです。

してきましたか嬉しいサービスバス/メッセージキュー/サービスです。の基本アーキテクチャがあります。

サイトから配信されるメッセージキュー

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

Windowsサービスを受けやプロセスのメッセージを独自の時間

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

のではありませんの遅延のためのフロントエンドサービスのユーザーが接続されます。Windowsのサービスの停止およびグレードアップして止めずに、本サイトです。スペシャル"ホットスポットの 非常に高速.

できない場合は店舗のすべてのデータ内のメッセージつきの店舗で取得ておくことが出来ます。であることを文書保管機構など RavenDB または Pythonの でも真っ直ぐにお客様の授業なしに変わります。

サイトから配信されるメッセージキュー

// 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);
   }
}

もの簡単な使用してい: サイESBTopshelf.の構成は非常にシンプルなものなんです、このため、既存のアプリであることが確認されがあります。

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

ただし、これらのジョブは、サイトが成長するにつれて実行に長くかかり、長くかかり、サイトでのユーザーエクスペリエンスを脱線させたくありません。少数の(または多分)不運なユーザーが1日を通してさえないため、バックグラウンドでジョブをスケジュールすることを考えています。

バックグラウンドジョブが定期的に実行される理由は、訪問者を模倣できない理由がわかりません。今、私は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

ジョブ/メッセージングキューの性質により、ジョブはジョブランナーに均等に配布されます。つまり、特別な_crafted_urlは最終的にWebサーバーに配布されます。

純粋なサービスアプローチを備えたCONは、コードがサービスに散らばっていて、コアアプリから離れていることだと思います。

これは、コードを一緒に保ち、サービスを簡素化する大きなバックグラウンドではないジョブで行ったことです。

  1. ジョブキューを作成します(インメモリまたはDBのいずれか、ジョブの種類に必要な持続性が何であれ)
  2. キューのジョブを実行するWebサービスを作成する
  3. 指定されたインターバルでWebサービスを呼び出すDead Simple Serviceアプリは、すべての複雑なもの(ジョブ検索と実行)をコアコードベースのWebサービスに残します。

さらに簡単に、コンソールアプリで電話をかけ、タスクスケジューラまたはVisualCronを使用して「サービス」に変えるだけです。

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

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

Webサーバーで実行され、その他のタスクを行うメンテナンスURLに定期的にヒットする非常にシンプルなWindowsサービスがあるのはどうですか。特定のリクエストでどれだけの作業を行うかをスロットルにしてください。

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

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

私の意見では、IISのソリューションは、単に作業をランダムなページビューにピギーバックすることからの「次のステップアップ」です。

リク いいです。あるいは kthxbye 結果の値が完了したら、結果の値を通知する必要がある場合。

両方のRedis/RubyベースのTho。

正直なところ、サービスベースのアプローチを行っている場合、現在のプラットフォームで非常に統合する必要はありません。それが(ある種の監視で)実行され、完全な仕事を実行するセットアンドフォーゲットシステムになることを願っています。データベース情報を更新/変更するだけなので、同じプラットフォームで実行する必要があるかどうかはわかりません。

特にスレッドの問題に対処しているように見えるので、このような作業を別のエンティティに耕作した場合、あなたはもっと少なく、より少ないほど逃げることができると確信しています。両方 リクkthxbye 処理を分離してプロセスを分離して、OSが並行性を処理できるようにします。

リク

kthxbye

MSMQキューを聞いてホストされたWCFサービスを使用します。

プロの

  • Webアプリからの片道メッセージを発射して忘れる

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

  • 配達保証; d

  • 死んだ手紙管理

  • 分散処理

  • / MSMQの活性化でした

詐欺

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

WCFのMSMQ機能により、MSMQを使用することが非常に優れています。はい、構成に出血しますが、利点は犠牲を上回ります。

Webアプリケーションを開発するときに、これに数回遭遇しました。タスクを実行するWindowsコンソールアプリケーションを作成し、実際にタスクを実行するために頻繁に実行されるスケジュールされたタスクを作成することにより、それを解決してきました。

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

クラス内にはすべてが存在するすべてのものをホストします(別名シングルトンですが、適切に行います - ライフスタイルを決定するためにIOCコンテナを使用してください)。

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

私はこのタイプのものを数回実装しました。 Windowsでは、さまざまな時期に何かを行うPythonコマンドラインプログラムを設定します。このプログラムは、ポートにXMLRPCインターフェイスも公開します。次に、スケジュールされたタスクジョブが毎分実行され、XMLRPCインターフェイスを照会します。彼らが起きていない場合、それはそれらを起動しようとします。できない場合は、私に電子メールを送ります。

利点は、実行されるジョブがCronまたはスケジュールバインドされていないことです。私は毎月実行されるプロセスジョブを持っていますが、それがやるべきかどうかに応じて、新しい仕事を始める間に長く何度も待ちます。また、結果に基づいてインテリジェントに作用するために使用できます。 500エラーがありますか?本当に長い遅延がありましたか?何か他のことをしてください。別のサービスに通知します。等。

また、同じシステムがUNIXで動作し、マイナーな変更を加えています。

私はあなた自身のために答えを持っていませんが、問題は鐘を鳴らします - 私はいくつかのランダムな人を覚えています ポッドキャストで一度話し合います.

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

アトウッド:はい。

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

アトウッド:YA、バックグラウンドタスクのようなもの。

Spolsky:YA、それであなたは何を理解しましたか?

Atwood:まあ、私はもともとTwitterで尋ねました。私は本当にWindowsサービスを書くのが好きではありませんでした。それはバンドコードが外れていると感じました。さらに、実際に作業を行うコードは実際にはWebページです。なぜなら、私にとっては、Webサイト上の論理的な作業単位であるため、Webページです。だから、それは本当に私たちがウェブサイトに電話をかけているようなものであり、それはウェブサイトの別のリクエストのようなものなので、私はそれをインラインを維持するべきものと見なしました、そして私たちが出てきた小さなアプローチはTwitterで私に推奨されました基本的に、固定有効期限が切れてアプリケーションキャッシュに何かを追加することでした。その後、コールバックがあります。そのため、それが有効期限が切れたときに、作業を行う特定の関数を呼び出して、同じ有効期限でキャッシュに戻します。だから、それは少しです、多分「ゲットー」は正しい言葉です。

タスクキューJava APIの概要

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

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

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

両方をします

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

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

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

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

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

いくつかのコードを追加して、各ログ期間の終了時にファイルを切り替えるか、各ログ期間プロセスを再起動します。

ライセンス: CC-BY-SA帰属
所属していません softwareengineering.stackexchange
scroll top