2009-04-08 16 views
0

Ich habe eine Anwendung, die jedes Mal, wenn eine Seite angefordert wird, ein Schreiben in eine Datenbank ausführt. Diese db-Schreiboperation ist nicht zeitkritisch. Aus Gründen der Leistung muss die Seite das Objekt unter Verwendung von MSMQ in die Warteschlange stellen. Natürlich, ich habe etwas haben, um die Warteschlange und Prozessanforderungen zu lesen, so schrieb ich eine Klasse, die in etwa so aussieht:ASP.NET Threading + Design-Frage

public class QueueProcessor { 
    public void Start() 
    { 
     // Create background thread to run ProcessInternal() 
    } 

    public void Stop() 
    { 
     // Stop the previously created thread 
    } 

    public void ProcessInternal() 
    { 
     while (runnable) 
     { 
      // check queue for messages, process them one at a time, 
      // then wait indefinitely for more messages 
     } 
    } 
} 

Jetzt, da diese Website ziemlich klein in der Natur ist, ich wirklich don‘ Ich möchte der Bereitstellungsroutine einen Windows-Dienst hinzufügen müssen. Daher mache ich gerade einen neuen QueueProcessor im Ereignis Application_Start und starte ihn dort. Mein Gedanke ist, dass der Thread für die Lebensdauer der Anwendung ausgeführt wird, und wenn die Anwendung von IIS beendet wird, wird es beim nächsten Zugriff auf eine Seite einfach neu gestartet.

Um lange Leerlaufzeiten zu vermeiden, in denen Nachrichten in der Warteschlange nicht verarbeitet werden, weil die Anwendung von IIS beendet wurde, habe ich eine wget-Anfrage eingerichtet, die alle paar Minuten auf einer der Seiten der Site ausgeführt wird und sicherstellen, dass der Hintergrund-Thread weiterläuft.

Meine Frage ist, ich sehe diesen Entwurf nicht sehr oft, und ich frage mich, ob es mögliche Probleme damit gibt?

EDIT:

Nach einiger Lesung zu dem Thema zu tun, fand ich, dass das Hauptproblem bei diesem Ansatz (und ähnlichen, wie die Entfernung aus dem Cache Callback-Funktion) ist die Art der Funktion, die sie aufgefordert wurden zu Leistung in Bezug auf Skalierbarkeit. Wenn Sie beispielsweise ein Massenupdate oder ähnliches durchführen, möchten Sie offensichtlich nicht, dass die Aufgabe auf allen Ihren Webservern ausgeführt wird. Auf diese Weise treten Konflikte bei Updates und potenziellen Datenverlusten auf.

In meinem ganz besonderen Fall verarbeitet der Thread jedoch NUR Anforderungen, die von diesem Server empfangen werden und in der Nachrichtenwarteschlange dieses Servers liegen. Wenn ich also diese App auf 5 Server skalieren würde, würde jeder Thread die Nachrichten in der Warteschlange des Servers problemlos verarbeiten. Auch hier ist die Reihenfolge der Datensätze in der Datenbank nicht so wichtig, dass ein paar ähnliche Anfragen von verschiedenen Servern innerhalb eines kleinen Intervalls ein Problem darstellen würden. Daher halte ich diese Lösung für mein Problem für sinnvoll.

Antwort

1

Ich habe ein ähnliches Schema auf einigen Websites verwendet, die ich ohne Schwierigkeiten beibehalten habe. Die Hauptsache ist, sicherzustellen, dass alle Ausnahmen im Thread ordnungsgemäß erfasst werden. Was Sie nicht haben möchten, ist der Thread, den Sie ohne Ihr Wissen sterben müssen, und dann im Stillen wieder neu starten, wenn Ihre Anwendung recycelt wird.

1

Ich glaube, das Einrichten der wget-Anfrage ist nicht viel einfacher als die Bereitstellung eines Windows-Dienstes. Ansonsten sehe ich keine spezifischen Probleme damit. Wenn Zuverlässigkeit und genaues Timing nicht kritisch sind, würde dies funktionieren.

+0

Das Wget Stück ist extra, und nicht wirklich erforderlich. Wie von einem anderen Poster erwähnt, gibt es, solange ich alle Ausnahmen auf diesem Thread erwische, keine Chance, jemals vorzeitig zu sterben, und da Leerlauf-Applikations-Kills keinen Warteschlangenverkehr bedeuten, bin ich auch dort wirklich OK. – Chris

1

Während ich nicht gedacht hätte, es wäre eine gute Idee, Jeff und Co. seem to use similar hackery einen Windows-Service auf dieser Website zu vermeiden (und Joel tut auch für FogBugz). Da sich Maßstab und Performance hier recht gut bewährt haben, erscheint es durchaus sinnvoll und praktikabel.

+0

Eigentlich verwenden sie diesen Trick nicht mehr, lesen Sie den letzten Kommentar von Jeff (als Antwort auf Joes Frage, am Ende der Seite) –