Service Broker-Nachrichten start to get hung up nach etwa einem Tag
Ich habe eine Anwendung, die der Service Broker von SQL 2008. Etwa einmal am Tag die Datenbank-performance beginnt, nehmen Sie eine deutliche Treffer und ich habe festgestellt, dass dies ist, weil der Service Broker. Wenn ich hard reset alle broker-verbindungen mit den folgenden Befehlen:
ALTER DATABASE [RegencyEnterprise] SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [RegencyEnterprise] SET ONLINE
Dann ist die Leistung wieder normal, bis über den nächsten Tag. Ich habe auch bemerkt, dass, wenn die Leistung schlecht ist, läuft die folgende Abfrage gibt eine große Zahl (etwa 1000-aktuell), Gespräche, die stecken in der STARTED_OUTBOUND Zustand:
SELECT * FROM sys.conversation_endpoints
Auch die folgenden Abfragen nicht wieder alle Einträge in:
SELECT * FROM sys.dm_qn_subscriptions
SELECT * FROM sys.transmission_queue
Leistung scheint in Ordnung zu sein, wo es gibt viele Elemente, die von dieser Abfrage zurückgegeben werden. Die einzige Zeit, wenn es Probleme gibt, wenn es gibt verbindungen, die sind STARTED_OUTBOUND, stecken zu bleiben in diesem Zustand.
Ist die einzige Konfiguration, die ich getan haben, um die Service Broker-auf meinem SQL Server 2008-Instanz den folgenden Befehl ausführen:
ALTER DATABASE RegencyEnterprise SET ENABLE_BROKER
Graben durch den SQL-error-log fand ich diesen Eintrag über 1000 mal so gut:
07/11/2013 01:00:02,spid27s,Unknown,The query notification dialog on conversation handle '{6DFE46F5-25E9-E211-8DC8-00221994D6E9}.' closed due to the following error: '<?xml version="1.0"?><Error xmlns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"><Code>-8490</Code><Description>Cannot find the remote service 'SqlQueryNotificationService-cb4e7a77-58f3-4f93-95c1-261954d3385a' because it does not exist.</Description></Error>'.
Ich auch sehen, diesen Fehler, ein Dutzend oder so mal die ganze log, obwohl ich glaube, dass ich den beheben kann dies nur durch die Schaffung eines master-Schlüssel in der Datenbank:
06/26/2013 14:25:01,spid116,Unknown,Service Broker needs to access the master key in the database '<Database name>'. Error code:26. The master key has to exist and the service master key encryption is required.
Ich denke die Anzahl dieser Fehler kann in Bezug auf die Anzahl der Gespräche, die bleiben in der Warteschlange hängen. Hier ist der C# - code, den ich verwende abonnieren Sie die query notifications:
private void EstablishSqlConnection(
String storedProcedureName,
IEnumerable<SqlParameter> parameters,
Action sqlQueryOperation,
String serviceCallName,
Int32 timeout,
params MultipleResult[] results)
{
SqlConnection storeConnection = (SqlConnection) ((EntityConnection) ObjectContext.Connection).StoreConnection;
try
{
using (SqlCommand command = storeConnection.CreateCommand())
{
command.Connection = storeConnection;
storeConnection.Open();
SqlParameter[] sqlParameters = parameters.ToArray();
command.CommandText = storedProcedureName;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddRange(sqlParameters);
if (sqlQueryOperation != null)
{
// Register a sql dependency with the SQL query.
SqlDependency sqlDependency = new SqlDependency(command, null, timeout);
sqlDependency.OnChange += OnSqlDependencyNotification;
}
using (DbDataReader reader = command.ExecuteReader())
{
results.ForEach(result => result.MapResults(this, reader));
}
}
}
finally
{
storeConnection.Close();
}
}
Hier ist, wie umgehe ich die Meldung:
public static void OnSqlDependencyNotification(object sender, SqlNotificationEventArgs e)
{
if (e.Info == SqlNotificationInfo.Invalid)
{
// If we failed to register the SqlDependency, log an error
<Error is loged here...>
// If we get here, we are not in a valid state to requeue the sqldependency. However,
// we are on an async thread and should NOT throw an exception. Instead we just return
// here, as we have already logged the error to the database.
return;
}
// If we are able to find and remove the listener, invoke the query operation to re-run the query.
<Handle notification here...>
}
Weiß jemand, was kann die Ursache für die broker, die verbindungen zu bekommen in diesem Zustand? Oder welche tools ich verwenden könnte, um darüber zu gehen, um herauszufinden, was ist die Ursache? Ich habe derzeit nur einen einzigen web-server, der registriert ist, seine Meldungen, so mein Szenario ist nicht allzu Komplex.
UPDATE:
Ok, so habe ich festgestellt, das aus dieser Beitrag, dass der Fehler "Nicht finden können, die remote-service ... weil es nicht existiert" ist aufgrund SqlDependency nicht bereinigen, nachdem sich richtig. Der Makler ist immer noch versuchen, das senden von Benachrichtigungen an meine Anwendung, nachdem der Dienst beendet wurde. So, jetzt klingt es so als ob ich nur noch einen Weg finden, heraus zu löschen, was auch immer es ist nicht richtig reinigen, wenn meine app gestartet wird vor dem Aufruf von SqlDependency.Start(), aber ich habe nicht gefunden, einen Weg, dies zu tun, außer meiner ursprünglichen Methode vor, die die Datenbank offline geschaltet und ist nicht akzeptabel. Weiß jemand, wissen, reinigen Sie das?
Ich bin nur mit dem Standard - habe ich nicht erstellt benutzerdefinierte Warteschlangen noch. Ich bin die Verbindung mit dem C# SqlDependency-Objekt in meiner web-Anwendung. Gibt es bestimmte Konfigurations-Informationen, die helfen würden?
Können Sie uns zeigen, der C# - code, bitte?
Was Warteschlange sind diese Gespräche dann? Das herauszufinden und dann Woher kommen?
Ich habe mein C# - code vor.
InformationsquelleAutor lehn0058 | 2013-07-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich gefunden, der einen akzeptablen Ansatz zur Lösung dieses Problems. Zuerst wanderte ich meinen code Weg von SqlDependency und ich bin jetzt mit SqlNotificationRequest statt. Dies verhindert, dass Broker-Warteschlangen und Dienstleistungen erstellt/zerstört zu unerwarteten Zeiten.
Selbst mit dabei aber wenn meine Anwendung beendet wird, gibt es noch ein paar Gespräche, die es nicht als "geschlossen" markiert, weil die ursprüngliche Endpunkt, dass das setup die Meldung ist nicht mehr da. Deshalb, jedes mal, wenn mein server re-initialisiert mein code ich bin Entrümpelung bestehender Gespräche.
Diese Anpassung hat eine Reduktion der Zahl der verbindungen, die ich auf einer täglichen Basis von über 1000 und mit manuell zu töten, mit ein max von über 20 zu allen Zeiten. Ich hoch empfehlen, mit SqlNotificationRequest statt SqlDependency.
InformationsquelleAutor lehn0058
Ich habe einen Weg gefunden, um die Gespräche, die hängen geblieben sind. Ich alle abrufen der generierten SqlDependency-Warteschlangen, die noch existieren und die Iteration über die Gespräche, die gehören nicht zu diesen und Ende dieser Gespräche. Unten ist der code:
SqlNotificaitonRequest
können Sie bauen Ihre eigene 'Sanitär' (target service etc). Ist nicht trivial, aber Sie vermeiden die ProblemeSqlDependency
verursacht.Ja, ich fand das Klasse und ich überlege, es zu benutzen. Dies würde mir erlauben, zu definieren, meine eigenen service-broker-Objekte anstatt es sich auto-generiert jedes mal eine neue Verbindung hergestellt wird.
OK - das sieht aus wie ein Schmerz zu tun auf einer regelmäßigen basis. Zurück bis die "Gedanken-stack" ein bisschen - haben Sie umgesetzt beliebigen code zur Deaktivierung der Benachrichtigungen, wenn Ihre Kunden schließt?
Habe ich, aber würde das problem immer noch auftreten, wenn die Anwendung unerwartet beendet. Auch, SqlDependency nicht erlauben, Sie zu bereinigen, eröffnet Gespräche - Sie alle müssen geschlossen werden, für die es in der Lage sein, Sie zu bereinigen. Es ist, weil, wie es erstellt dynamisch alle von der Broker-Entitäten. Als solche, ich bin auf der Suche in SqlNotificationRequest statt.
InformationsquelleAutor lehn0058
Schritte Ausgehende bedeutet " SQL Server verarbeitet eine BEGIN CONVERSATION für dieses Gespräch, aber keine Nachrichten, die noch nicht gesendet wurden.' (aus der Onlinedokumentation)
Wie es aussieht, sind das erstellen von Konversationen, die dann nicht verwendet werden, so dass Sie nie geschlossen.
Nicht ganz sicher, warum das sein würde, verursacht eine Verschlechterung in der Leistung obwohl.
InformationsquelleAutor Rikalous