MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Problemi di connessione di MongoDB in Azure

Poche migliaia di richieste al minuto sono un grande carico, e l'unico modo per farlo correttamente, è controllare e limitare il numero massimo di thread che potrebbero essere in esecuzione in qualsiasi momento.

Poiché non ci sono molte informazioni pubblicate su come l'hai implementato. Tratterò alcune possibili circostanze.

È ora di sperimentare...

Le costanti:

  • Articoli da elaborare:
    • 50 al secondo , o in altre parole...
    • 3.000 al minuto , e un altro modo per vederlo...
    • 180.000 all'ora

Le variabili:

  • Tassi di trasferimento dati:

    • La quantità di dati che puoi trasferire al secondo avrà un ruolo, indipendentemente da ciò che facciamo, e questo varierà nel corso della giornata a seconda dell'ora del giorno.

      L'unica cosa che possiamo fare è inviare più richieste da diverse CPU per distribuire il peso del traffico che stiamo inviando avanti e indietro.

  • Potere di elaborazione:

    • Presumo che tu abbia questo in un WebJobs invece di averlo codificato all'interno del sito MVC è di per sé. È altamente inefficiente e non adatto allo scopo che stai cercando di raggiungere. Utilizzando un lavoro Web possiamo fare la coda elementi di lavoro che devono essere elaborati da altri WebJobs . La coda in questione è Coda di Azure Archiviazione .

I problemi:

  • Stiamo tentando di completare 50 transazioni al secondo, quindi ogni transazione dovrebbe essere eseguita in meno di 1 secondo se utilizzassimo 50 thread. Il nostro timeout di 45 secondi non serve a nulla a questo punto.
  • Ci aspettiamo che 50 thread vengano eseguiti contemporaneamente e che tutti vengano completati in meno di un secondo, ogni secondo, su una singola CPU. (Sto esagerando un punto qui, solo per fare un punto... ma immagina di scaricare 50 file di testo ogni singolo secondo. Elaborarlo, quindi provare a riportarlo a un collega nella speranza che siano anche pronti a prendilo)
  • È necessario disporre di una logica di ripetizione in atto, se dopo 3 tentativi l'elemento non viene elaborato, è necessario rimetterlo in coda. Idealmente dovremmo fornire più tempo al server per rispondere di un solo secondo per ogni errore, diciamo che gli abbiamo dato una pausa di 2 secondi al primo errore, poi 4 secondi, quindi 10, questo aumenterà notevolmente le probabilità che persistiamo / recuperare i dati di cui avevamo bisogno.
  • Stiamo supponendo che il nostro MongoDb può gestire questo numero di richieste al secondo. Se non lo hai già fatto, inizia a cercare modi per ridimensionarlo, il problema non è nel fatto che si tratta di un MongoDb, il livello dati potrebbe essere qualsiasi cosa, è il fatto che stiamo facendo questo numero di richieste da un'unica fonte che sarà la causa più probabile dei tuoi problemi.

La soluzione:

  1. Imposta un WebJobs e chiamalo EnqueueJob . Questo WebJobs avrà un unico scopo, mettere in coda gli elementi di lavoro da elaborare nella Queue Storage .
  2. Crea un Queue Storage Container denominato WorkItemQueue , questa coda fungerà da trigger per il passaggio successivo e avvierà le nostre operazioni di scalabilità orizzontale.
  3. Crea un altro WebJobs denominato DequeueJob . Questo WebJobs avrà anche un unico scopo, togliere dalla coda gli elementi di lavoro da WorkItemQueue e invia le richieste al tuo archivio dati.
  4. Configura il DequeueJob per girare una volta che un elemento è stato posizionato all'interno di WorkItemQueue , avviare 5 thread separati su ciascuno e, mentre la coda non è vuota, rimuovere dalla coda gli elementi di lavoro per ciascun thread e tentare di eseguire il lavoro rimosso dalla coda.
    1. Tentativo 1, se fallito, attendi e riprova.
    2. Tentativo 2, se fallito, attendi e riprova.
    3. Tentativo 3, se fallisce, accoda l'elemento a WorkItemQueue
  5. Configura il tuo sito Web per scalare automaticamente fino a una quantità x di CPU (tieni presente che il tuo sito Web e i lavori Web condividono le stesse risorse)

Ecco un breve video di 10 minuti che offre una panoramica su come utilizzare gli archivi di coda e i lavori Web.

Modifica:

Un altro motivo per cui potresti ricevere quegli errori potrebbe essere dovuto anche ad altri due fattori, sempre causati dal fatto che si trova in un'app MVC...

Se stai compilando l'applicazione con il DEBUG attributo applicato ma spingendo il RELEASE versione invece, potresti riscontrare problemi a causa delle impostazioni nel tuo web.config , senza il DEBUG attributo, un'applicazione Web ASP.NET eseguirà una richiesta per un massimo di 90 secondi, se la richiesta richiede più tempo, eliminerà la richiesta.

Per aumentare il timeout a più di 90 secondi dovrai cambiare il [httpRuntime][3] proprietà nel tuo web.config ...

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

L'altra cosa di cui devi essere a conoscenza sono le impostazioni di timeout della richiesta del tuo browser> app web, direi che se insisti a mantenere il codice in MVC invece di estrarlo e inserirlo in un WebJob, allora tu può utilizzare il codice seguente per inviare una richiesta alla tua app web e compensare il timeout della richiesta.

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