Frage

Wir haben es mit einem interessanten Problem bei StackOverflow zu tun.

Wir haben eine ganze Reihe kleiner Aufgaben, die „bald erledigt werden müssen“.Ein Beispiel ist die Aktualisierung von „Verwandte Fragen“-Listen.In der Vergangenheit haben wir diese Aufgaben auf die Seitenaufrufe einiger Benutzer übertragen.

Das war nie ideal, aber es war nicht wirklich spürbar.Jetzt, da SO die 1.000.000-Fragemarke überschritten hat, beginnen diese unglücklichen Benutzer es zu spüren.

Die natürliche Lösung besteht darin, diese Aufgaben tatsächlich in den Hintergrund zu drängen.Ich denke über zwei Möglichkeiten nach, dies zu erreichen.

1.In IIS als benutzerdefinierter Thread-Pool/Work-Queue

Grundsätzlich drehen wir ein paar (nicht-ThreadPool, um IIS-Threads nicht zu beeinträchtigen und sie einige von uns verschobene Sammlungen bedienen zu lassen Funktionen hinein.

Der große Vorteil hier ist die Einfachheit.Wir müssen uns weder darum kümmern, irgendetwas zu organisieren, noch müssen wir sicherstellen, dass ein externer Dienst verfügbar ist und reagiert.

Wir erhalten auch Zugriff auf unseren gesamten gemeinsamen Code.

Der Nachteil ist, dass wir keine Hintergrundthreads verwenden sollten.Die Einwände, die ich kenne, drehen sich alle um das Aushungern von IIS (wenn Sie ThreadPool verwenden) und das zufällige Absterben von Threads (aufgrund des AppPool-Recyclings).

Wir verfügen über eine vorhandene Infrastruktur, die dafür sorgt, dass der zufällige Thread-Tod kein Problem darstellt (im Grunde ist es möglich, zu erkennen, dass eine Aufgabe abgebrochen wurde), und die Begrenzung der Anzahl der Threads (und die Verwendung von Nicht-ThreadPool-Threads) ist auch nicht schwierig.

Übersehe ich irgendwelche anderen Einwände gegen Thread-Pooling/Arbeitswarteschlangen im IIS-Prozess?

Nach StackOverflow verschoben, da es hier nicht wirklich angesprochen wurde.

2.Als Dienstleistung

Entweder eine Lösung eines Drittanbieters oder eine benutzerdefinierte Lösung.

Im Grunde würden wir eine Aufgabe über die Prozessgrenze hinweg an einen Dienst weiterleiten und sie einfach vergessen.Vermutlich verknüpfen wir Code oder beschränken uns auf rohes SQL + eine Verbindungszeichenfolge.

Der Vorteil ist, dass es der „richtige Weg“ ist, dies zu tun.

Die Nachteile bestehen darin, dass wir entweder in unseren Möglichkeiten sehr eingeschränkt sind oder ein System entwickeln müssen, um diesen Dienst mit unserer Codebasis synchron zu halten.Wir müssen auch alle unsere Überwachungs- und Fehlerprotokollierungsfunktionen irgendwie einbinden, die wir mit der Option „In IIS“ kostenlos erhalten.

Gibt es weitere Vorteile oder Probleme mit dem Serviceansatz?

Kurz gesagt: Gibt es unvorhergesehene und unüberwindbare Probleme, die Ansatz Nr. 1 undurchführbar machen, und wenn ja, gibt es gute Drittanbieterdienste, die wir für Ansatz Nr. 2 in Betracht ziehen sollten?

War es hilfreich?

Lösung

Fragte ich ein paar Wochen Ähnliche Frage auf so. Kurz gesagt, mein Ansatz war seit einiger Zeit, einen Windows -Dienst zu entwickeln. Ich würde NServicebus (im Wesentlichen MSMQ unter den Covers) verwenden, um Anfragen von meiner Web -App zu meinem Dienst zu marschieren. Früher habe ich WCF verwendet, aber eine verteilte Transaktion, die richtig über WCF funktioniert, schien immer ein Schmerz im Arsch zu sein. Nservicebus hat den Trick gemacht, ich konnte Daten begehen und Aufgaben in einer Transaktion erstellen und keine Sorgen machen, ob mein Dienst zu diesem Zeitpunkt in Betrieb war. Wenn ich als einfaches Beispiel jemals eine E -Mail (z. B. eine Registrierungs -E -Mail) senden müsste, würde ich das Benutzerkonto erstellen und ein Signal an meinen Windows -Dienst (um die E -Mail senden) in einer Transaktion abzubauen. Der Nachrichtenhandler auf der Serviceseite würde die Nachricht aufnehmen und entsprechend verarbeiten.

Da ASP .NET 4.0 und AppFabric veröffentlicht wurden, gibt es eine Reihe von praktikablen Alternativen zum oben genannten Mechanismus. Wenn wir uns auf die oben erwähnte Frage beziehen, haben wir jetzt Appinitialize (über net.pipe) sowie die automatische Funktion von ASP .NET 4.0, die die Entwicklung von Windows-Diensten als Web-Apps zu einer praktikablen Alternative macht. Ich habe jetzt aus mehreren Gründen begonnen (der größte Einsatz ist kein Schmerz mehr im Arsch):

  1. Sie können eine Web -Benutzeroberfläche über Ihren Dienst entwickeln (da sie als Web -App ausgeführt wird). Dies ist äußerst nützlich zu sehen, was zur Laufzeit passiert.
  2. Ihr Bereitstellungsmodell für Ihre Web -Apps funktioniert für Ihre Serviceanwendung.
  3. IIS bietet einige nette Funktionen für die Behandlung von Anwendungsfehlern (in gewisser Hinsicht einem Windows -Dienst ähnlich).
  4. Webentwickler sind (natürlich) mit der Entwicklung von Web -Apps vertraut, die meisten wissen nicht viel über bewährte Verfahren bei der Entwicklung eines Windows -Dienstes.
  5. Es bietet eine Reihe von Alternativen, um eine API für andere zu konsumierende Apps aufzudecken.

Wenn Sie diesen Weg gehen (verzeihen Sie mir, dass Sie aus meinem ursprünglichen Beitrag kopiert und eingefügt werden), würde ich auf jeden Fall in Betracht ziehen, die Hintergrundlogik in einer separaten Webanwendung auszuführen. Dafür gibt es eine Reihe von Gründen:

  1. Sicherheit. Möglicherweise gibt es ein anderes Sicherheitsmodell für die Benutzeroberfläche, in der Informationen über die laufenden Hintergrundprozesse angezeigt werden. Ich würde diese Benutzeroberfläche außer dem OPS -Team nicht jemand anderem aussetzen wollen. Außerdem kann die Webanwendung als anderer Benutzer mit erhöhten Berechtigungen ausgeführt werden.
  2. Wartung. Es wäre großartig, Änderungen an der Anwendungshostung der Hintergrundprozesse bereitzustellen, ohne sich auf die Nutzungswebsite zu beeinflussen.
  3. Leistung. Wenn die Anwendung von den Hauptweservenverarbeitungsanfragen getrennt ist, verringert Hintergrund -Threads die Fähigkeit der IIS nicht, die eingehende Anforderungswarteschlange zu verarbeiten. Darüber hinaus könnte die Anwendungsverarbeitung der Hintergrundaufgaben bei Bedarf an einem separaten Server bereitgestellt werden.

Dies kehrt zum Marshaling -Aspekt zurück. WCF, NServicebus/Rabbitmq/Activemq usw., Vanille -MSMQ, RESTful -API (denken Sie an MVC) alle Optionen. Wenn Sie Windows Workflow 4.0 verwenden, können Sie einen Host -Endpunkt freilegen, den Ihre Web -App konsumieren könnte.

Der Webhosting -Ansatz für Dienste ist für mich immer noch ziemlich neu, nur die Zeit wird zeigen, ob es sich um die richtige Wahl handelte. So weit so gut. Wenn Sie AppFabric nicht verwenden möchten (ich könnte es nicht tun, weil die Windows Server-Web-Edition aus irgendeinem bizarren Grund nicht unterstützt wird), funktioniert die im Beitrag des GU genannte automatische Fähigkeit gut. Halten Sie sich jedoch von der Datei applicationHost.config fern. Alles in diesem Beitrag ist möglich, über die IIS -Konsole (Konfigurationseditor auf der Hauptserverebene) eingerichtet zu werden.

Hinweis: Ich hatte ursprünglich ein paar weitere Links in dieser Nachricht gepostet, aber leider ist dies mein erster Beitrag zu diesem Austausch und nur ein Link wird unterstützt! Es gab im Grunde genommen zwei andere, um sie Google "Tod an Windows Services ... Lang Live AppFabric!" und "automatisch-start-asp-net-applications". Das tut mir leid.

Andere Tipps

Es gibt tatsächlich einen dritten Weg in Windows, um Hintergrunddienste auszuführen, und es ist in der Unix -Welt sehr häufig. Der dritte Weg ist a CRON Job, der ein Stück Ihrer Infrastruktur betreibt. In Windows ist dies als die bekannt task scheduler und ist sehr häufig, um Code auf geplanter Basis auszuführen. Um dies zu verwenden, erstellen Sie eine Befehlszeilen-App, die in einem vordefinierten Zeitplan ausgeführt wird. Der Vorteil davon ist, dass Sie sich keine Sorgen machen müssen, ob der Vorgang wie ein Dienst läuft, denn wenn er aus irgendeinem Grund fehlschlägt, wird das nächste Mal nur beginnen.

Was das Marshaling spezifische Aufgaben betrifft, müssen Sie diese Aufgaben in einer anhaltenden Binärspeicherung wirklich nur aufbewahren. Bis die Befehlszeilen -App sie aus dem Speicher heraus wählt und ausführt. Ich habe dies in der Vergangenheit mit der Cassandra -Datenbank als Sitzungsstatemanbieter für die Füllung von Hintergrundaufgaben für bestimmte Benutzer in der Cassandra -Datenbank verwendet und dann die Befehlszeile auswählen und für den Benutzer ausführen.

Dies war vielleicht nicht die typische Marshaling -Lösung, aber es hat für mich sehr gut geklappt und es stellte sich heraus gelagert.

Schamlose Promotion, aber dies ist mein Projekt und die Lösung, die ich gerade kurz detailliert habe, ist, warum ich das Projekt erstellt habe:http://github.com/managedfusion/fluentcassandra/

Cron + Web App

Dies ist ein kattgetestes Design, das Skalen horizontal zusammen mit Ihrem Webfarm und stellt sicher, dass Sie die verwenden Web Technology Stack Sie wissen es schon.

So funktioniert das:

  1. Erstellen Sie eine Controller/Aktion in Ihrer Webanwendung, um geplante Hintergrundaufgaben zu erledigen. Nach der Konvention rufe ich normalerweise meine an http://mydomain.com/system/cron.
  2. Für die Sicherheit sollte diese Aktion nur an authentifizierte IP -Adressen im lokalen Netzwerk gesperrt werden.
  3. Installieren Sie auf einer separaten Maschine Wget und Setup a Geplante Aufgabe Um die Ressource aus Schritt 1 abzurufen, können Sie die Aufgabe so häufig ausführen, wie Sie möchten (ich entscheidet sich normalerweise 30 Sekunden lang). Vergessen Sie nicht, das entsprechende Cookie -Argument an WGet zu übergeben, damit es sich an Ihre Web -App authentifiziert.
  4. Für Redundanz können Sie auch ein zweites geplanter WGE auf einer zweiten Maschine installieren.

Hurra! Jetzt haben Sie eine Route, die alle 30 Sekunden aufgerufen wird. Und wenn die Bearbeitung der Anfrage 5 Minuten dauert, ist es niemandem, der sich darum kümmert, da sie nicht Teil der Seitenanforderung eines Benutzers ist.

Das cron Die Aktion sieht sehr einfach aus: Er hat eine Liste von Methoden, um eine bestimmte Häufigkeit auszuführen. Wenn eine Anfrage eingeht, sieht er, ob es eine Methode gibt, die ausgeführt werden muss und die entsprechende Methode aufruft. Dies bedeutet, dass Sie den Zeitplan in Ihrer Datenbank steuern können, wo Sie wahrscheinlich bereits viele andere wichtige Konfigurationsdaten für Ihre Website haben.

Noch wichtiger ist (für Sie), dies bedeutet, dass Ihre Jobs nicht nach einem festen Zeitplan aufgenommen werden müssen. Sie können jede Logik schreiben, die Sie möchten, um festzustellen, wann eine Methode ausgeführt werden soll.

Vor-und Nachteile

Profis
  • Sie sind bereits sehr gut darin, ASP.NET -MVC -Code zu schreiben. Dadurch schreiben Sie Ihre Hintergrundaufgaben in die Gleiche Plattform in dem Sie den Rest Ihrer Lösung schreiben.
  • Die Aufgaben werden im selben Kontext wie Ihre Web -App ausgeführt, sodass Sie können Teilen Sie den Cache und benutzen Helfermethoden das existiert schon.
  • Wenn Sie WGet A haben, a ladenbalanciert URI, dann sind Ihre Hintergrundaufgaben jetzt ebenfalls geladen.
  • Gleichzeitige Bereitstellung - Sie müssen sich keine Sorgen machen, dass Sie Ihre Web -App mit Ihrer Hintergrundaufgabenlogik synchronisieren, da sie alle in derselben Bereitstellung sind.
Nachteile
  • Im Laufe der Jahre haben mir ein paar Leute gesagt, dass dieses Design "sehr gekoppelt" ist, aber wenn sie gedrückt wurden, konnten sie nicht artikulieren, warum das eine schlechte Sache ist.

Hinweis: Wenn es Fragen oder Bedenken gibt, Bitte fügen Sie einen Kommentar hinzu. Ich bin froh, näher darauf einzugehen.

Ich habe es versucht und in meiner aktuellen Anwendung fast jede mögliche Möglichkeit verwendet. Ich habe angefangen, dasselbe zu tun, was Sie derzeit tun, und Pucky wieder auf eine Benutzeranforderung, um die Daten zu füllen und dann in Zukunft zu leiten. Mir wurde klar, dass dies auch eine schlechte Idee war (insbesondere wenn Sie auf mehrere Webserver skalieren, nehmen mehr Benutzer den Hit).

Ich hatte auch einen geplanten Job, der eine URL in der ASP.NET -App trifft - dies ist eine anständige Lösung, aber sie beginnt, sobald Sie die Minute nach einem Webserver über 1 skalieren.

Derzeit verwende ich zwei verschiedene Methoden, beide mit quartz.net, einer großartigen kleinen Bibliothek. Das erste ist quartz.net, das in process mit ASP.NET ausgeführt wird. Es ist in global.asax eingerichtet und läuft alle paar Minuten. Ich benutze dies, um den ASP.NET -Cache aus der Band zu aktualisieren, was der einzige Grund ist, warum er als Teil von ASP.NET ausgeführt wird.

Das zweite ist, dass ich eine Bibliothek geschrieben habe, um quartz.net namens DaemonMaster zu wickeln. Es macht es einfach, eine DLL in ein Verzeichnis zu fallen und in einem Windows -Dienst auszuführen. Ich fand, dass es einige der nervigen Teile der Arbeit mit einem Windows -Dienst vermeidet und auch die Quartz.net -API einige reinigt. Die Dienste, die durch DaemonMaster ausgehen, sind aus zwei verschiedenen Geschmacksrichtungen. Die ersten sind Jobs, die jeden Abend oder alle X -Minuts laufen müssen. Die anderen Jobs arbeiten von einer Warteschlange, die auf Daten basiert, die aus der ASP.NET -Anwendung stammen. Die ASP.NET -App lässt JSON -Objekte auf Rabbitmq und die Dienste Poll RabbitMQ fallen und verarbeiten die Daten.

Basierend darauf würde ich vorschlagen, dass Sie sich mit einem Windows -Dienst (und besuchen Dämonmaster) und bei Bedarf eine Warteschlange wie Rabbitmq zum Übergeben der Daten aus der ASP.NET -App an die Dienste verwenden - hat das Beste aus all diesen Lösungen herausgearbeitet . Wenn Sie Cache laden, ist es sinnvoll, in ASP.NET zu laufen, sonst glaube ich nicht.

Ich würde es richtig machen und einen Windows -Dienst leiten lassen, der eine "Warteschlange" überwacht. Ich sage "Warteschlange", weil das Programmieren mit MSMQ mit den heißen Pokern in Ihre Augäpfel ähnelt.

Ich habe mich in die Einfachheit von verliebt Verspätet :: Job in Schienen, und ähnliches könnte leicht in .NET gemacht werden.

Grundsätzlich fügen Sie irgendeine Art von hinzu SomethingOperation (etwas, das eine hat Perform() Methode). Dann serialisieren Sie einfach die relevanten Parameter, geben Sie ihm eine Priorität, eine Art Standard -Wiederholungsverhalten und füllen Sie es in eine Datenbank.

Ihr Service würde dies nur überwachen und die Jobs in der Warteschlange bearbeiten.

Wir waren ziemlich zufrieden mit einem Service -Bus- / Message -Warteschlangen- / Service -Ansatz. Die grundlegende Architektur ist dies.

Die Website sendet eine Nachricht an Warteschlange

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

Windows Service empfängt und verarbeitet Nachrichten in seiner eigenen Zeit

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

Der Vorteil besteht darin, dass der Front-End-Dienst keine Verzögerung gibt, mit der auch Benutzer verbunden sind. Der Windows -Dienst kann heruntergefahren und ohne Unterbrechung der Hauptstelle aktualisiert werden. Außerdem ist es extrem schnell.

Wenn Sie nicht alle Ihre Daten in der Nachricht speichern können, können Sie sie jederzeit speichern und später abrufen. Ich schlage vor, einen Dokumentspeichermechanismus zu verwenden, wie z. B.: Ravendb oder MongoDb Wo es sehr einfach ist, Ihre Klassen ohne Änderungen zu speichern.

Die Website sendet eine Nachricht an Warteschlange

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

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

Windows Service empfängt und verarbeitet Nachrichten in seiner eigenen Zeit

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

Um die Dinge einfach zu machen, verwenden wir: Rhino ESB und Obersten Regal. Die Konfiguration ist extrem einfach und es hat sich erwiesen, wenn dies für eine vorhandene Anwendung eingerichtet wurde.

Ich bin gespannt, warum eine Kombination aus beiden keine praktikable Option ist. Im Moment auslösen Sie Jobs auf Seitenansichten, wobei ein unglücklicher Saft 10 Sekunden darauf wartet, dass die Seite auftaucht. Zumindest ist das mein Verständnis für Ihre aktuelle Methode.

Diese Jobs dauern jedoch länger und länger, wenn die Website wächst, und Sie möchten die Benutzererfahrung auf der Website nicht entgleisen. Nicht einmal für ein paar (oder vielleicht viel) unglückliche Benutzer im Laufe des Tages, jetzt denken Sie darüber nach, Jobs im Hintergrund zu planen.

Ich verstehe nicht, warum ein Hintergrundjob in regelmäßigen Abständen keinen Besucher nachahmen kann. Jetzt bin ich kein Windows -Programmierer, aber in der Linux -Welt würde ich einen Cron -Job einrichten, der in einem regulären Intervall ausgeführt wird, und es hätte 2 Codezeilen.

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

Es kombiniert die Profis beider Systeme. Es wird im Hintergrund gemacht. Es wirkt sich nicht von Benutzern aus. Es wird immer noch eine Seitenansicht verwendet, um den Job zu starten. Ich habe diesen Ansatz schon einmal gesehen. Es ist tendenziell der Mittelweg zwischen den einfachen Arten der alten und den komplexeren Wegen, die die Straße hinunterkommen.

Aktualisieren

Ich denke, Sie können das Problem der Lastausgleich umgehen, indem Sie die Stellenläufer auf den Webservern selbst ausführen. Der Jobläufer zieht eine URL aus der Jobwarteschlange und leitet sie so aus:

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

Aufgrund der Art von Job-/Messaging -Warteschlangen werden die Jobs gleichmäßig auf die Stellenläufer verteilt, was bedeutet, dass der speziell_crafted_url schließlich auf Ihre Webserver verteilt wird.

Ich denke, der Betrüger mit dem reinen Serviceansatz ist, dass Sie Code in den Dienst und weg von der Kern -App verteilt haben.

Folgendes haben wir mit großen nicht zeitempfindlichen Bereichen des Hintergrunds gemacht, was den Code zusammenhält und den Service vereinfacht:

  1. Erstellen Sie eine Job-Warteschlange (entweder in Memory oder DB, unabhängig von der Persistenz für die Arten von Jobs)
  2. Erstellen Sie einen Webdienst, der die in der Warteschlange ausführenden Jobs ausführen wird
  3. Dead Simple Service App, die den Webdienst in einem bestimmten Intervall aufruft, überlassen Sie alle komplexen Dinge (Jobabruf und Ausführung) dem Webdienst in Ihrem Core -Codebasis.

Noch einfacher, tätigen Sie einfach den Anruf in einer Konsolen -App und verwenden Sie Task Scheduler oder Visualcron, um ihn in einen "Dienst" zu verwandeln.

Ich mochte Topshelf. Hält die Einfachheit und macht es dennoch so gut wie ein Windows -Dienst. Erstellen Sie im Grunde eine Konsolen-App, fügen Sie ungefähr 15-20 Codezeilen hinzu und installiert dann als Dienst.

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

Wie wäre es mit einem sehr einfachen Windows -Service, der auf dem Webserver ausgeführt wird und regelmäßig eine Wartungs -URL trifft, die Ihre verschiedene Aufgaben erledigt. Haben Sie es drosselt, wie viel Arbeit es in einer bestimmten Anfrage leistet.

Ich werde hier den offensichtlichen Trend brühen und vorschlagen, sich für das In-IIS-Modell zu entscheiden. Ich habe es selbst benutzt und es funktioniert wirklich gut. Es ist wirklich nicht so schwer, eine anständige Thread-Pool-Klasse zu implementieren (im Laufe der Jahre habe ich meine Thread-Pool-Klasse erweitert, um die dynamische Erstellung und Zerstörung von Threads, Wiederholung von Jobs usw. zu unterstützen). Vorteile sind:

  • Kein externer Dienst zu überwachen
  • Einfachheit der Implementierung: Kein Cross-Process-Marshalling, keine fortgeschrittene Jobüberwachung
  • Sie befinden sich immer noch in Ihrem IIS -Prozess, sodass Sie alle Ihre übliche Protokollierung und so weiter ausführen können (keine Mehrfachprotokolldateien).
  • Übereinstimmende Bereitstellung (wenn Sie einen Dienst aktualisieren, müssen Sie den Dienst anhalten, die Dateien kopieren, den Dienst starten. Dies gilt zusätzlich zu Ihren üblichen Aktualisierungen des Website -Code.)

Meiner Meinung nach ist eine In-IIS-Lösung einfach der "nächste Schritt up" von Heackgyback, die die Arbeiten auf zufällige Seitenansichten haben.

Resque ist schön. Oder auch Kthxbye Wenn Sie nach Abschluss des resultierenden Werts informiert werden müssen.

Sowohl Redis/Ruby basieren tho.

Ehrlich gesagt, wenn Sie einen Service-basierten Ansatz verfolgen, muss es wirklich nicht in Ihre aktuelle Plattform integriert sein, was ich für ein Plus für ein Plus für ein Gefühl habe. Ich würde hoffen, dass es sich um ein Set-and-Forget-System handelt, das ausführen würde (mit Überwachung) und vollständigen Jobs. Ich bin mir nicht sicher, ob es überhaupt auf derselben Plattform ausgeführt werden muss, da es nur aktualisiert/geändert wird.

Ich bin mir ziemlich sicher, dass Sie mit viel mehr für viel weniger durchkommen könnten, wenn Sie diese belästigt, wenn Sie diese irgendwie auf ein separates Unternehmen arbeiten, zumal Sie es anscheinend mit Problemen mit Threading zu tun haben. Beide Resque und Kthxbye Verschieben Sie die Verarbeitung auf getrennte Prozesse, damit das Betriebssystem die Parallelität verarbeiten kann.

Resque

Kthxbye

Ich würde ein Hosted WCF -Dienst verwenden, der eine MSMQ -Warteschlange hört.

Pro

  • Feuer und vergessen Sie One -Way -Nachrichten aus der Web -App

  • MSMQ/WCF -Drossel und Wiederholung

  • Garantierte Lieferung; D.

  • Dead Letter Management

  • Verteilte Verarbeitung

  • War / MSMQ -Aktivierung

Con's

  • MSMQ (es ist noch nicht tot ... noch)

Die MSMQ -Funktionen in WCF macht die Verwendung von MSMQ wirklich schön. Ja, Sie werden in der Konfiguration bluten, aber die Vorteile überwiegen das Opfer.

Ich bin ein paar Mal darauf getroffen, wenn ich Webanwendungen entwickelte. Wir haben es gelöst, indem wir eine Windows -Konsolenanwendung erstellt haben, die die Aufgabe ausführt, und eine geplante Aufgabe erstellt, die von Zeit zu Zeit ausgeführt wird, um die Aufgabe tatsächlich zu erledigen.

Sie können die Arbeit mit RX und so etwas wie folgt auf einen Hintergrund -Thread (oder viele Hintergrund -Threads) schütteln:

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

Benutzen:

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

Gastgeber all das in einer Klasse, dass es immer nur eines von (auch bekannt als ein Singleton, aber richtig - verwenden - verwenden Sie Ihren IOC -Container, um den Lebensstil zu bestimmen).

Sie können die Größe des Thread -Pools usw. steuern, indem Sie einen benutzerdefinierten Scheduler anstelle der Verwendung des EventLoopScheduler (der einen einzelnen Thread ausführen) schreiben.

Ich habe diese Art von Dingen ein paar Mal implementiert. Unter Windows habe ich ein Python-Befehlszeilenprogramm eingerichtet, das zu verschiedenen Zeiten etwas tut. Dieses Programm enthält auch eine XMLRPC -Schnittstelle auf einem Port. Anschließend läuft in jeder Minute ein Job-Task-Job und fragt die XMLRPC-Schnittstellen ab. Wenn sie nicht abgelaufen sind, versucht es, sie zu starten. Wenn es nicht möglich ist, schickt es mir eine E -Mail.

Der Vorteil ist, dass der Job, der läuft, nicht Cron oder Zeitplan gebunden ist. Ich habe einen Prozessjob, der alle Sekunden läuft, aber länger und länger wartet, ob ein neuer Job beginnt, je nachdem, ob es zu tun hat. Es kann auch verwendet werden, um auf der Grundlage des Ergebnisses intelligent zu handeln. Hast du einen 500 -Fehler? Hast du eine wirklich lange Verzögerung? Mach etwas anderes. Einen anderen Dienst benachrichtigen. Usw.

Und dasselbe System funktioniert auf UNIX mit geringfügigen Änderungen.

Ich selbst habe keine Antwort für Sie, aber das Problem kam mir bekannt vor – ich erinnere mich an einige zufällige Typen Ich habe es einmal in einem Podcast besprochen.

Spolsky:Mir fiel einer der Fragen, die Sie im Blog gestellt haben, waren Wie sollten Sie mit der Wartung umgehen? wiederkehrende Aufgaben im Allgemeinen?

Atwood:Ja.

Spolsky:Ist das eine faire Charakterisierung?Jede Website hat Einige Aufgaben, die Sie nicht erledigen möchten zu dem Zeitpunkt ausführen, zu dem eine Webseite geladen, aber Sie möchten mit irgendein Wiederholungsfall.

Atwood:Ya, Hintergrundaufgaben.

Spolsky:Ya, also was hast du herausgefunden?

Atwood:Nun, ich fragte ursprünglich nach Twitter, weil ich einfach nur wollte etwas Leichtes.Ich habe wirklich Ich wollte nicht gerne ein Windows schreiben Dienst.Ich hatte das Gefühl, dass das nicht in Ordnung war Bandcode.Plus der Code, der tatsächlich Ist die Arbeit in der Tat eine Webseite, Denn für mich ist das eine logische Einheit der Arbeit auf einer Website ist eine Webseite.Es ist also wirklich so, als würden wir Zurück auf der Website ist es genau wie eine weitere Anfrage auf der Website, so dass ich betrachtete es als etwas, das Bleiben Sie inline, und die kleine Annäherung die wir uns ausgedacht haben, die empfohlen wurde für mich auf Twitter war es im Wesentlichen, Hinzufügen von etwas zum Anwendungscache mit einem festen Ablaufdatum, dann haben Sie ein Rückruf, wenn dieser abläuft ruft eine bestimmte Funktion auf, die die Arbeit, dann fügen Sie sie wieder hinzu den Cache mit dem gleichen Ablaufdatum.Es ist also ein bisschen, vielleicht "Ghetto" ist das richtige Wort.

Task Warteschlange Java API -Übersicht

Aufgabenkonzepte
Bei der Verarbeitung von App Engine -Hintergrund ist eine Aufgabe eine vollständige Beschreibung einer kleinen Arbeitseinheit. Diese Beschreibung besteht aus zwei Teilen:

  • Eine Datennutzlast, die die Aufgabe parametriiert.
  • Code, der die Aufgabe implementiert.

Aufgaben als Offline -Webhaken
Glücklicherweise bietet das Internet bereits eine solche Lösung in Form einer HTTP -Anfrage und seiner Antwort. Die Datennutzlast ist der Inhalt der HTTP -Anforderung, z. B. Webformvariablen, XML, JSON oder codierte Binärdaten. Die Codereferenz ist die URL selbst; Der tatsächliche Code ist die Logik, die der Server bei der Vorbereitung der Antwort ausführt.

Tue beides

Fügen Sie dem Fragenpfad, der die Arbeiten erledigt, die Sie derzeit für Benutzeranfragen erledigen, einen optionalen Parameter hinzu:

Wartung von Hintergrundaufgaben auf einer großen Stelle

Erstellen Sie eine Konsolen -App, die auf jedem Server ausgeführt wird und das IIS -Protokoll -Binärdatum öffnet, und liest sie bis zum aktuellen Ende der Datei. Verwenden Sie einen Dateisystemwatcher oder ein zeitgesteuertes Intervall, um vorwärts zu lesen, um Updates zu sammeln, während IIS das Protokoll spüle.

Verwenden Sie diese Informationen, um festzustellen, welche Seiten derzeit angezeigt wurden.

Verwenden Sie die Seiten -URLs aus dem Parsen -Protokoll, um die "Extrastuff" -Version der URL auf Localhost mit einem Webclient -Objekt aufzurufen.

Fügen Sie einen Code hinzu, um Dateien am Ende jeder Protokollperiode zu wechseln, oder starten Sie den Prozess jeder Protokollperiode neu.

Lizenziert unter: CC-BY-SA mit Zuschreibung
scroll top