MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB-Verbindungsprobleme in Azure

Ein paar tausend Anfragen pro Minute sind eine große Menge Last, und die einzige Möglichkeit, es richtig zu machen, besteht darin, die maximale Anzahl von Threads zu kontrollieren und zu begrenzen, die gleichzeitig ausgeführt werden können.

Da nicht viele Informationen darüber veröffentlicht werden, wie Sie dies implementiert haben. Ich werde einige mögliche Umstände behandeln.

Zeit zum Experimentieren...

Die Konstanten:

  • Zu verarbeitende Elemente:
    • 50 pro Sekunde , oder anders gesagt...
    • 3.000 pro Minute , und eine weitere Sichtweise...
    • 180.000 pro Stunde

Die Variablen:

  • Datenübertragungsraten:

    • Wie viele Daten Sie pro Sekunde übertragen können, spielt eine Rolle, egal was wir tun, und dies wird im Laufe des Tages je nach Tageszeit variieren.

      Das Einzige, was wir tun können, ist, mehr Anfragen von verschiedenen CPUs abzufeuern, um das Gewicht des Datenverkehrs zu verteilen, den wir hin und her senden.

  • Rechenleistung:

    • Ich nehme an, Sie haben dies in einem WebJob im Gegensatz dazu, dass dies innerhalb der MVC-Site selbst codiert ist. Es ist sehr ineffizient und nicht für den Zweck geeignet, den Sie erreichen möchten. Durch die Verwendung eines WebJobs können wir uns in die Warteschlange stellen Arbeitselemente, die von anderen WebJobs verarbeitet werden sollen . Die Warteschlange fraglich ist die Azure Queue Speicherung .

Die Probleme:

  • Wir versuchen, 50 Transaktionen pro Sekunde abzuschließen, also sollte jede Transaktion in weniger als 1 Sekunde durchgeführt werden, wenn wir 50 Threads verwenden würden. Unsere 45-sekündige Auszeit hat an dieser Stelle keinen Zweck.
  • Wir erwarten, dass 50 Threads gleichzeitig laufen und alle in weniger als einer Sekunde jede Sekunde auf einer einzigen CPU abgeschlossen werden. (Ich übertreibe hier, nur um einen Punkt zu machen ... aber stellen Sie sich vor, Sie laden jede Sekunde 50 Textdateien herunter. Verarbeiten und dann versuchen, sie an einen Kollegen zurückzuschicken, in der Hoffnung, dass sie dazu bereit sind fangen)
  • Wir brauchen eine Wiederholungslogik, wenn das Element nach 3 Versuchen nicht verarbeitet wird, muss es wieder in die Warteschlange gestellt werden. Idealerweise sollten wir dem Server mehr Zeit geben, um bei jedem Fehler zu reagieren, als nur eine Sekunde, sagen wir, wir haben ihm beim ersten Fehler eine Pause von 2 Sekunden gegeben, dann 4 Sekunden, dann 10, dies erhöht die Wahrscheinlichkeit, dass wir bestehen bleiben / Abrufen der von uns benötigten Daten.
  • Wir vermuten dass unsere MongoDb kann diese Anzahl von Anfragen pro Sekunde verarbeiten. Wenn Sie es noch nicht getan haben, suchen Sie nach Möglichkeiten, es zu skalieren. Das Problem liegt nicht in der Tatsache, dass es sich um eine MongoDb handelt, die Datenschicht hätte alles sein können, sondern die Tatsache, dass wir diese Anzahl von Anfragen stellen eine einzelne Quelle, die die wahrscheinlichste Ursache für Ihre Probleme sein wird.

Die Lösung:

  1. Richten Sie einen WebJob ein und nennen Sie ihn EnqueueJob . Dieser WebJob wird nur einen einzigen Zweck haben, um zu verarbeitende Arbeitselemente in den Queue Storage einzureihen .
  2. Erstellen Sie einen Queue Storage Container namens WorkItemQueue , dient diese Warteschlange als Auslöser für den nächsten Schritt und startet unsere Skalierungsvorgänge.
  3. Erstellen Sie einen weiteren WebJob namens DequeueJob . Dieser WebJob wird auch einen einzigen Zweck haben, um die Arbeitselemente aus der WorkItemQueue zu entfernen und senden Sie die Anfragen an Ihren Datenspeicher.
  4. Konfigurieren Sie den DequeueJob zu drehen, sobald ein Element in die WorkItemQueue platziert wurde , starten Sie 5 separate Threads auf jedem und während die Warteschlange nicht leer ist, entfernen Sie Arbeitselemente für jeden Thread und versuchen Sie, den aus der Warteschlange entfernten Job auszuführen.
    1. Versuch 1, falls fehlschlagen, warten und erneut versuchen.
    2. Versuch 2, falls fehlschlagen, warten und erneut versuchen.
    3. Versuch 3, falls fehlschlagen, Element zurück in WorkItemQueue einreihen
  5. Konfigurieren Sie Ihre Website so, dass sie automatisch auf x CPUs skaliert wird (beachten Sie, dass Ihre Website und Webjobs dieselben Ressourcen nutzen)

Hier ist ein kurzes 10-minütiges Video das gibt einen Überblick über die Verwendung von Queue-Speichern und Web-Jobs.

Bearbeiten:

Ein weiterer Grund, warum Sie diese Fehler erhalten, könnte auch auf zwei andere Faktoren zurückzuführen sein, die wiederum dadurch verursacht werden, dass sie sich in einer MVC-App befinden ...

Wenn Sie die Anwendung mit dem DEBUG kompilieren Attribut angewendet, aber RELEASE drücken Version, könnten Sie aufgrund der Einstellungen in Ihrer web.config auf Probleme stoßen , ohne DEBUG -Attribut führt eine ASP.NET-Webanwendung eine Anfrage maximal 90 Sekunden lang aus. Wenn die Anfrage länger dauert, wird die Anfrage verworfen.

Zum Erhöhen des Zeitlimits auf mehr als 90 Sekunden Sie müssen den [httpRuntime][3] ändern -Eigenschaft in Ihrer web.config ...

<!-- Increase timeout to five minutes -->
<httpRuntime executionTimeout="300" />

Die andere Sache, die Sie beachten müssen, sind die Timeout-Einstellungen Ihres Browsers> Web-App. Ich würde sagen, wenn Sie darauf bestehen, den Code in MVC zu behalten, anstatt ihn zu extrahieren und in einen WebJob einzufügen, dann Sie können den folgenden Code verwenden, um eine Anfrage an Ihre Web-App zu senden und das Zeitlimit der Anfrage auszugleichen.

string html = string.Empty;
string uri = "http://google.com";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Timeout = TimeSpan.FromMinutes(5);

using (HttpWebResponse response = (HttpWebResonse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
    html = reader.ReadToEnd();
}