Några tusen förfrågningar per minut är stort load, och det enda sättet att göra det rätt, är genom att kontrollera och begränsa det maximala antalet trådar som kan köras samtidigt.
Eftersom det inte finns mycket information om hur du har implementerat detta. Jag ska ta upp några möjliga omständigheter.
Dags att experimentera...
Konstanterna:
- Objekt att bearbeta:
- 50 per sekund , eller med andra ord...
- 3 000 per minut , och ytterligare ett sätt att se på det...
- 180 000 per timme
Variablerna:
-
Dataöverföringshastigheter:
-
Hur mycket data du kan överföra per sekund kommer att spela en roll oavsett vad vi gör, och detta kommer att variera under dagen beroende på tid på dygnet.
Det enda vi kan göra är att avfyra fler förfrågningar från olika processorer för att fördela vikten av trafik vi skickar fram och tillbaka.
-
-
Bearbetningskraft:
-
Jag antar att du har detta i ett
WebJob
i motsats till att ha detta kodat på MVC-webbplatsen. Det är mycket ineffektivt och passar inte för det syfte du försöker uppnå. Genom att använda ett WebJob kan vi köa arbetsobjekt som ska bearbetas av andraWebJobs
. kön ifrågavarande är Azure Queue Lagring .
-
Problemen:
- Vi försöker slutföra 50 transaktioner per sekund, så varje transaktion bör göras på mindre än 1 sekund om vi använde 50 trådar. Vår 45 sekunders timeout tjänar inget syfte just nu.
- Vi förväntar oss att 50 trådar ska köras samtidigt, och alla slutförs på under en sekund, varje sekund, på en enda cpu. (Jag överdriver en poäng här, bara för att göra en poäng... men tänk dig att ladda ner 50 textfiler varje sekund. Bearbeta det och sedan försöka skjuta tillbaka det till en kollega i hopp om att de till och med är redo att fånga det)
- Vi måste ha en logik för ett nytt försök på plats. Om objektet inte har bearbetats efter tre försök måste de placeras tillbaka i kön. Helst borde vi ge servern mer tid för att svara än bara en sekund med varje fel, låt oss säga att vi gav den en 2 sekunders paus vid första felet, sedan 4 sekunder, sedan 10, detta kommer avsevärt att öka oddsen för att vi fortsätter / hämtar den data som vi behövde.
- Vi utgår från att vår MongoDb kan hantera detta antal förfrågningar per sekund. Om du inte redan har gjort det, börja titta på sätt att skala ut det, problemet ligger inte i det faktum att det är en MongoDb, datalagret kunde ha varit vad som helst, det är det faktum att vi gör det här antalet förfrågningar från en enda källa som kommer att vara den mest troliga orsaken till dina problem.
Lösningen:
- Konfigurera ett
WebJob
och döp det tillEnqueueJob
. DennaWebJob
kommer att ha ett enda syfte, att köa arbetsobjekt som ska bearbetas iQueue Storage
. - Skapa en
Queue Storage Container
heterWorkItemQueue
, kommer den här kön att fungera som en utlösare till nästa steg och sätta igång våra utskalningsoperationer. - Skapa en annan
WebJob
heterDequeueJob
. DennaWebJob
kommer också att ha ett enda syfte, att avköa arbetsobjekten frånWorkItemQueue
och avfyra förfrågningarna till ditt datalager. - Konfigurera
DequeueJob
att snurra upp när ett föremål har placerats iWorkItemQueue
, starta 5 separata trådar på varje och medan kön inte är tom, lägg ur kö arbetsobjekt för varje tråd och försök att köra det urköade jobbet.- Försök 1, om det misslyckas, vänta och försök igen.
- Försök 2, om det misslyckas, vänta och försök igen.
- Försök 3, om det misslyckas, ställ objektet tillbaka till
WorkItemQueue
- Konfigurera din webbplats för att automatiskt skala ut till x antal processorer (observera att din webbplats och webbjobb delar samma resurser)
Här är en kort 10 minuters video som ger en översikt över hur man använder kölagringar och webbjobb.
Redigera:
En annan anledning till att du kan få dessa fel kan också bero på två andra faktorer, återigen orsakade av att det finns i en MVC-app...
Om du kompilerar programmet med DEBUG
attribut tillämpat men trycker på RELEASE
version istället kan du stöta på problem på grund av inställningarna i din web.config
, utan DEBUG
attribut, kommer en ASP.NET-webbapplikation att köra en begäran i högst 90 sekunder, om begäran tar längre tid än detta kommer den att avyttra begäran.
För att öka timeouten till längre än 90 sekunder du måste ändra [httpRuntime][3]
egenskap i din web.config
...
<!-- Increase timeout to five minutes -->
<httpRuntime executionTimeout="300" />
Den andra saken som du måste vara medveten om är inställningarna för begäran om timeout i din webbläsare> webbapp, jag skulle säga att om du insisterar på att behålla koden i MVC i motsats till att extrahera den och lägga den i ett WebJob, då kan använda följande kod för att skicka en begäran till din webbapp och kompensera för tidsgränsen för begäran.
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();
}