2009-10-29 3 views
9

Unsere Website funktioniert gut für 90% des Tages, dann während unserer Hauptverkehrszeiten, wenn der Verkehr etwa doppelt so schwer wie normal ist, wird alles zu einem Crawlen. Seitenladezeiten, die normalerweise 1 Sekunde betragen, dauern 30 Sekunden. Bei der Überprüfung unserer Fehlerprotokolle scheint es sich um ein Problem mit dem Verbindungspool zu handeln. Wir haben 3 Webserver mit 1 sql Server db verbunden. Der SQL Server fliegt auf allen Kernen unter 25% Auslastung.Das Zeitlimit, das vor dem Erhalt einer Verbindung vom Pool verstrichen ist

Ich schaue auf den User Connections-Zähler auf unserem SQL-Server und sehen, dass während unserer Spitze haben wir 400+ User Connections, aber außerhalb der Stunden ist es rund 120+.

Ich bin mir ziemlich sicher, dass wir nur die Standardeinstellungen verwenden, die MS für den Umgang mit unserem App-Pool vorsieht. Was kann ich tun, um zu testen, ob ein App-Pool-Problem besteht? Was ist das Negative, wenn die Größe des App-Pools auf 1000 erhöht wird (und wie mache ich das?).

Danke!

+0

Welche Versionen von ASP.Net und SqlServer? – zendar

+4

Als ich zuerst die Betreffzeile las, dachte ich, du wärst ein Rettungsschwimmer. – Jason

Antwort

7

Dies könnte damit zusammenhängen, dass SQL-Verbindungen nicht ordnungsgemäß entsorgt werden (zurück in den Pool). Stellen Sie sicher, dass Sie SqlConnection.Dispose anrufen.

+0

+1: Gleicher Gedanke. – Arthur

+2

Oder implizit disponieren, indem Sie die Verbindung in 'using() {...}' construction einfügen. –

+0

In meinem Fall habe ich die Verbindung nicht geschlossen. – Mahmoodvcs

5

sein Dies könnte, da der Pool von SQL-Verbindungen erschöpft ist (dies unterscheidet sich von der App-Pool). Sie können das überprüfen, indem Sie increasing the pool size durch die Verbindungszeichenfolge:

Integrated Security=SSPI;Initial Catalog=northwind;Max Pool Size=100; 

Aber wahrscheinlicher ist, Ihre Datenbank nicht mit dem Strom der eingehenden Anfragen Schritt halten. Dies führt dazu, dass Verbindungen darauf warten, dass ihre Abfrage beendet wird. Das Hinzufügen von mehr Verbindungen hilft gegen Burst-Anfragen, aber nicht gegen anhaltend hohen Datenverkehr.

Hier einige Vorschläge, die Leistung Ihres SQL Server unter anhaltend hohen Last zu verbessern:

  • Wurf Hardware auf dem Problem (vor allem RAM auf dem SQL-Server)
  • Bringen Sie SQL Server Profiler an den Server, erhalten eine Spur von einer Hochlastzeit und folgen Sie den vorgeschlagenen Indizes
  • aus dem Protokoll der Ablaufverfolgung untersuchen lange laufende Abfragen und verbessern diese zusammen mit einem T-SQL-Entwickler

Viel Glück, diese Dinge können sehr komplex sein!

15

Nach meiner Erfahrung gibt es drei Haupttypen von Timeouts Sie von SQL Server empfangen können:

1) InvalidOperationException - Ein Ausfall für die Kunden eine zusammengefasste Verbindung vom eigenen Pool vor dem Timeout auf dem Befehl angegeben zu erhalten Zeichenfolge (Standard 15 Sekunden). Der Pool des Clients hat die maximale Größe und alle gepoolten Verbindungen werden verwendet und bleiben vor Ablauf des Zeitlimits in Verwendung.

2) SQLException - Verbindungstimeout. Der Verbindungspool des Clients erstellt eine neue Verbindung zur Datenbank, aber die Datenbank antwortet nicht vor dem in der Befehlszeichenfolge angegebenen Zeitlimit (Standard 15 Sekunden).

3) SQLException - Befehlszeitüberschreitung. Eine Verbindung wurde erhalten, aber die Zeit, die die SQL-Anweisung für die Ausführung des Befehls benötigte, überschritt das in der CommandTimeout-Eigenschaft des Befehls angegebene Zeitlimit (standardmäßig 30 Sekunden)

Ihre Umstände eines Servers, der bis zum Laden normal funktioniert, klingen wie Fall # 1. Ich habe festgestellt, dass die Timeouts sehr schnell sind - normalerweise 2 Sekunden.

Ich habe die Lösung gefunden, um die maximalen Threads in SQL Server zu erhöhen. Der Standardwert ist Null - lassen Sie SQL Server entscheiden. Ich habe Fälle gesehen, in denen ein starker Server mit wenig Ressourcennutzung sitzt, während er sich durch Zuordnen von zu wenigen Threads eingeschränkt hat.

Sie können die max Threads mit diesem Transact-SQL-Einstellung erhöhen:

sp_configure 'max worker threads', 8192 
go 
Reconfigure 

Dann starten Sie den SQL-Dienst.

BTW, können Sie sehen, wie viele Threads zur Zeit von SQL Server mit diesem Befehl zugeordnet sind:

select sum(current_workers_count) from sys.dm_os_schedulers 

Dieses Einfädeln Einstellung macht einen enormen Unterschied, wie SQL Server unter vielen Verbindungen führt. SQL Server reagiert sehr wenig, sobald es keine Threads mehr aufweist.

1

Wenn ich diesen Fehler erhalten:

The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached

Es war aufgrund der Tatsache, dass ich die SqlCommand.ExecuteQuery() Methode anstelle von SqlCommand.ExecuteNonQuery() wurde mit.

Zum Beispiel: Mein ursprünglicher gespeichert procdure Anruf in etwa so aussehen:

using (SqlCommand cmd = new SqlCommand()) 
{ 
    cmd.CommandType = System.Data.CommandType.StoredProcedure; 
    cmd.CommandText = "InsertSproc"; 
    cmd.Parameters.AddWithValue("@Value", myValue); 
    cmd.Parameters.AddWithValue("@LoggedDate", myDate); 
    DatabaseManager.instance.ExecuteQuery(cmd); 
} 

Der obigen Code ist, was die Ausnahme ausgelöst hat. den Anruf ändert jedoch verwenden ExecuteNonQuery() das Problem behoben:

using (SqlCommand cmd = new SqlCommand()) 
{ 
    cmd.CommandType = System.Data.CommandType.StoredProcedure; 
    cmd.CommandText = "InsertSproc"; 
    cmd.Parameters.AddWithValue("@Value", myValue); 
    cmd.Parameters.AddWithValue("@LoggedDate", myDate); 
    DatabaseManager.instance.ExecuteNonQuery(cmd); 
} 
1

Ich hatte dieses Problem mit Powershell und Rücken an Rücken Abfragen (invoke-sqlcmd von einer anderen invoke-sqlcmd gefolgt). Beide Abfragen umfassten Datenänderungen. Gelöst durch Hinzufügen von -connectiontimeout 1 zum Parameteraufruf.

Beispiel:

invoke-sqlcmd "insert into testdb..tab1 (cname) select 'x'" -connectiontimeout 1 
invoke-sqlcmd "update testdb..tab1 set ctr=ctr+1 where cname='aaa'" 

Länge des Timeout kann variieren abhängig von der Anzahl der Zeilen betroffen.

Verwandte Themen