2009-05-07 1 views
26

Ich habe eine WCF-Client/Server-App, die über HTTP mit der WSHttpBinding kommuniziert.WCF Concurrent-Anfragen häufen sich auf dem Server bei Verwendung von WSHttpBinding

Serverkonfiguration: Self-Hosting, mit dem Standard WCF ServiceHost. Meine eigentliche Dienstklasse zugeschrieben als:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
InstanceContextMode = InstanceContextMode.PerSession, 
UseSynchronizationContext = false)] 

Client Setup: (. proxy.call_server_method Blöcke so lange, bis der Server vollständig reagiert hat) mit einem visuell-Studio erzeugt Client-Proxy mit synchronen Service Calls

Szenario: Ich habe einen bestimmten Methodenaufruf, der 20 Sekunden dauert, um auf dem Server auszuführen. Der Client ruft diese Methode in einem separaten Thread auf, so dass er nicht aufgehalten wird, und die ConcurrencyMode.Multiple bedeutet, dass WCF sie in einem separaten Thread auf dem Server ausführen sollte.

Diese Theorie wird durch die Tatsache unterstützt, dass alles funktioniert gut, wenn ich meine App für die Verwendung NetTcpBinding konfigurieren.

Problem:
Wenn ich die App konfigurieren WSHttpBinding zu verwenden, dann ist diese lange Methodenaufruf bewirkt, dass die HTTP-Anfragen zu 'back up'. Ich habe dieses Verhalten sowohl durch die Überprüfung meiner Protokolle als auch durch das Debuggen der HTTP-Anfragen mit Fiddler überprüft.

Beispiel:

  • Client leitet 20-Sekunden langen Anfrage auf einem Hintergrund-Thread
  • Client-Anforderung B und C auf den Vordergrund Gewinde
  • Requests B und C an den Server geschickt bekommen einleitet, die doesn ‚t verarbeiten sie, bis sie mit der 20-Sekunden langen Anfrage

Aber manchmal getan wird:

  • Anfragen B und C werden nicht gesendet (sie erscheinen nicht einmal in Fiddler), bis die 20-Sekunden-Anfrage zurückkommt (das ist selten).
  • Hinweis: Die Einstellung <add address="*" maxconnection="100"/> in der app.config des Clients hat dies (scheinbar) zum Stoppen gebracht.
  • Anforderung B wird gesendet und empfängt eine Antwort sofort, während der Anforderung C bis zur 20-Sekunden zurückgehalten wird eine vollendet (dies ist selten)
  • Hier ist eine Zeitleiste von Fiedler das Problem demonstriert: (klicken für größere Version)

    Wie Sie sehen können, werden die Anfragen alle auf dem Server gesichert zu werden. Sobald die 20-Sekunden-Anfrage abgeschlossen ist, kommen die Antworten alle durch, aber beachten Sie, dass einige Anfragen, die sind nicht halten werden ...

    So Fragen:

    • Was zum Teufel ist hier los? Warum funktioniert es gut mit NetTcpBinding und nicht mit WSHttpBinding arbeiten?
    • Warum das inkonsistente Verhalten?
    • Was kann ich tun, um es zu beheben?

    Hinweise:

    • Es ist nicht auf dem Server sperren. Ich habe Breakpoints gesetzt und !syncblk verwendet und es meldet ständig, dass keine Sperren gehalten werden.
    • Es ist nicht mein Gewinde (NetTcpBinding sollte nicht anders funktionieren)
    • Ich habe <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" /> Satz in dem app.config des Server
    • Der 20-Sekunden-Anruf auf einem Timer nur darauf wartet, ist es nicht die CPU oder Festplatte ist Dreschen oder Netzwerk
    • Ich würde eine Lösung bevorzugen, die die Anwendung nicht re-architecting, um asynchrone Anrufe zu verwenden ... es ist ein großer Haufen von Legacy-Code, und ich will wirklich nicht mit Sachen herumalbern, die ich nicht ' ich verstehe nicht.
    +0

    +1 Ausgezeichnetes Layout der Frage. –

    +1

    Haben Sie dieses Problem jemals gelöst? Wenn ja, wie hast du es gelöst? – DivisionByZorro

    +0

    Hinzugefügt eine Selbst-Antwort beschreibt unsere endgültige "Lösung" –

    Antwort

    2

    [Selbst Antwort andere Benutzer zu zeigen, was unsere Lösung war,]

    Am Ende habe ich nie dieses Problem zu lösen geführt.
    Unsere endgültige Lösung war es, unsere App von WSHttpBinding auf in Produktion zu schalten - wir hatten dies aus Leistungsgründen sowieso geplant.

    Dies ist jedoch eher bedauerlich, da es eine schwarze Markierung auf WSHttpBinding hinterlässt, die garantiert sein kann oder nicht. Wenn jemand schon einmal mit einer Lösung kommt auf die nicht WSHttpBinding mit sich bringt Notwasserung, würde ich gerne davon Dienste

    +1

    gesetzt Ich denke du solltest nicht selbst antworten als eigentlich Wir haben keine Antwort. Haben Sie versucht, Fehler zu connect.microsoft.com zu veröffentlichen? – Shrike

    +0

    Nun, da ich ein bisschen mehr darüber gelernt habe, wie die Dinge funktionieren, denke ich, dass es möglicherweise mit der Überlastung des ThreadPools zusammenhängt. Wenn Sie eine Menge lang andauernder Operationen in den Threadpool einreihen, erhalten Sie ein Verhalten, das fast genau so aussieht. –

    +0

    Ich habe genau das gleiche Problem mit WSHttpBinding und ich glaube nicht, dass es an einem überladenen Thread-Pool liegt. Ich habe NetTcpBinding benutzt und es funktioniert plötzlich perfekt. Ich kann das, was Sie beschreiben, einfach dadurch erreichen, dass ich meinen ersten Anruf beim Dienst tätige und ihn schließe, während ich versuche, einen anderen Anruf parallel von einem anderen Server anzuzeigen. Nichts anderes kann den Dienst kontaktieren, unabhängig davon, auf was mein Dienstverhalten und Dienstdrosselung eingestellt wurde. – Mike737

    10

    Es gibt eine Drosselung außerhalb von WCF (eine .Net oder Windows-Sache), die standardmäßig nur maximal zwei gleichzeitig ausgehende HTTP-Verbindungen zulassen. Leider kann ich mich für das Leben von mir nicht den Namen der Sache merken (und was du in app.config oder deine App setzen würdest). Da Sie nicht sehen, dass die Anfragen den Client verlassen und dass es nur HTTP ist, denke ich, dass Sie "dieses Ding" treffen. Ich werde weiter nach seinem Namen suchen.

    Update: Fand es - versuchen, dies auf dem Client (aber die '2' zu einer größeren Zahl aus):

    <configuration> 
        <system.net> 
        <connectionManagement> 
         <add address = "*" maxconnection = "2" /> 
        </connectionManagement> 
        </system.net> 
    </configuration> 
    
    +0

    Leider hat dies nicht gelöst ... Es änderte das Verhalten etwas, aber jetzt scheinen alle Anfragen auf dem Server zu sichern –

    +0

    Aktualisiert meine Frage mit einer Zeitachse Grafik von Fiddler, der hoffentlich helfen sollte –

    0

    I Forget - könnte es die Bestellung werden? Ich denke, vielleicht RM über HTTP bewahrt Ordnung, aber vielleicht Tcp-Sitzungen nicht (es sei denn, Sie fordern es ausdrücklich)? Gibt es im Servicevertrag ein Attribut, das geordnete/ungeordnete Sitzungen beschreibt (ich vergesse).

    +0

    Es gibt welches ein geordnetes Attribut hat ... Ich habe es auf

    1

    Wenn Sie zu BasicHttpBinding wechseln, funktioniert es?

    Ist so, es klingt wie this is your problem, Session-Throttling, etwas, das mich in den Arsch gebissen.

    1

    Erwägen Sie ConcurrencyMode.Multiple auf pro-Anruf wissen gleichzeitige Anrufe zu ermöglichen.

    4

    Wir haben genau die gleichen Symptome mit einem JSON-Dienst gesehen, der in IIS/ASP.NET gehostet wird.

    Die Ursache war, dass ASP.NET die Anforderungen synchronisiert - nicht WCF. Wir mussten den Sitzungsstatus (auf Anwendungsebene) deaktivieren, um gleichzeitige WCF-Methoden zu erhalten.

    Web.config: <system.web> <sessionState mode="Off" /> </system.web>

    Bitte beachten Sie, dass unser Dienst verwendet webHttpBinding, nicht WSHttpBinding. Ich bin mir also nicht sicher, ob damit auch Orions Problem gelöst wird.

    2

    Ich denke, das Protokoll Grenze getroffen und um ihn arbeiten Sie die Standardeinstellungen auf dem Clientcomputer ändern müssen:

    http://support.microsoft.com/kb/183110

    http://support.microsoft.com/kb/282402

    Ich denke, WSHttpBinding verwendet WinINET Einstellungen bei der Ausgabe von die Anfragen.

    +0

    Das scheint wahrscheinlich, aber ich habe den ursprünglichen Code längst verloren. Trotzdem danke! –

    Verwandte Themen