2009-03-25 16 views
6

Mam usługę WCF net.tcp obsługiwaną przez wbudowany ServiceHost, a podczas wykonywania testów skrajnych dostaję dziwne zachowanie. Za pierwszym razem, gdy wysyłam pakiet żądań, od 5 do 10 żądań odpowiada szybko, a reszta wraca z około 2-sekundowymi przerwami. Za drugim razem, gdy wysyłam żądania, 10-20 zwraca się szybko i odpoczywa z 2 okresami sensu.Wydajność WCF z net.tcp

Powyższe powtarza się, aż mogę uzyskać ponad 100 żądań szybko zwróciło, ale jeśli poczekam minutę lub mniej, pamięć korzystania z usługi spada, a żądania wracają szybko do 5-10.

Usługa, którą testuję ma małe opóźnienie, więc mogę uzyskać wiele otwartych połączeń w tym samym czasie, jeśli to opóźnienie zostanie usunięte, żądania zwrócą się tak szybko, że mam może 2-5 połączeń otwartych w tym samym czasie . To opóźnienie ma symulować połączenia DB i inne wychodzące rzeczy.

Z zachowania wygląda na to, że ServiceHost przydziela coś, wątki, instancje klasy, ale nie wiem, co to jest.

Mogę mieć licznik czasu w kliencie, który wywołuje usługę, aby działał, ale to wygląda na złe rozwiązanie.

Jeśli mam wysoki ciągły ładunek do usługi, wszystkie żądania zostaną szybko skrócone, ale jeśli mam okres niskiej aktywności, a następnie wzrost połączeń przychodzi, usługa będzie działać wolno.

Domyślam się, że moje pytanie brzmi: CO jest to przyznanie przydzielone podczas wysokiego obciążenia usługi WCF, i JAK mogę skonfigurować usługę, aby przedalokować więcej rzeczy, które zostaną przydzielone.

EDIT: Zrobiłem więcej testów i patrząc na taskmgr dla procesu Widzę, że kiedy servicehost jest "spoczynkowy", jest 10 wątków otwartych, ale kiedy zaczynam wysyłać prośby, liczba wątków rośnie. Dopóki ilość wątków jest wysoka, servicehost może szybko przetworzyć przychodzące żądania, ale jeśli wstrzymam wysyłanie żądań, liczba otwartych wątków maleje, a kolejne żądania zaczynają zabierać więcej czasu na przetwarzanie.

Teraz, w jaki sposób mogę powiedzieć serwisowi, aby pozostawił kilka wątków otwartych? Lub więcej niż 10-12, które utrzymuje domyślnie?

Odpowiedz

1

Rzeczą, która określa, w jaki sposób żądanie może być obsługiwane jednocześnie, jest ServiceThrottlingBehavior. Istnieje wiele różnych threasholdów, które ograniczą ilość przetwarzanych żądań. Zależy to również od powiązania, którego używasz, na przykład wsHttpBinding jest domyślnie włączone do sesji, podczas gdy basicHttpBinding nie używa żadnych sesji, a domyślny limit sesji 10 nie stanowi problemu.

Aby uzyskać więcej informacji, patrz http://msdn.microsoft.com/en-us/library/ms735114.aspx.

+0

Dzięki, sprawdziłem na stronie, a ustawienia są już w moim pliku konfiguracyjnego, z wysokimi limitami, tak wysoko, że powinienem być w stanie obsługiwać wszystkie połączenia przychodzące na raz zamiast pierwszej 5-10, a następnie jeden na 2 sekundy. – Kim

6

Po wielu badaniach google wygląda na to, że problemem jest wątek. Puli wątków CLR przydziela kilka wątków, a gdy są używane, dławi tworzenie nowych wątków, a po pewnym czasie zwolni również nieużywane wątki.

Istnieje pewne zamieszanie związane z błędem, który oznaczał, że ThreadPool nie honorował wywołania SetMinThreads.

http://www.michaelckennedy.net/blog/PermaLink,guid,708ee9c0-a1fd-46e5-8fa0-b1894ad6ce0f.aspx

Nie jestem pewien, czy ten błąd jest rozwiązany, czy co, bo kiedy zmodyfikować ustawienia puli wątków, problem będzie się powtarzał.

1

Błąd, do którego się odwołujesz, został naprawiony w .NET 3.5 SP1.To mogło mieć coś wspólnego z problemem, myślę, że jest bardziej prawdopodobne (o wiele bardziej prawdopodobne), że dławienie jest twoim problemem, a nie wątkiem, w jaki wpisał się Maurice.

<system.serviceModel> 
    <service name="???" > 
    <endpoint ... /> 
    </service> 
</system.serviceModel> 

Jaki jest limit przepustnicy dla tej "pustej" konfiguracji? 10 sesji, 16 jednoczesnych połączeń! Strzec się.

Oto więcej na gwint: http://www.michaelckennedy.net/blog/2008/08/20/ThreadPoolBugInNET20SP1IsFixed.aspx

0

to czuje się jak hack, ale wydaje się, aby rozwiązać swój problem. Problem polega na tym, że wątek będzie wymagał czasu, aby uruchomić nowy wątek, więc to, czego naprawdę potrzebujesz, to wątki oczekujące w trybie gotowości. Dodaj konstruktora do swojej usługi i ustaw minimalną liczbę wątków, które chcesz.

public YourService() 
    { 
     int workerThreads; 
     int portThreads; 
     ThreadPool.GetMinThreads(out workerThreads, out portThreads); 
     ThreadPool.SetMinThreads(200, portThreads); 
    } 
Powiązane problemy