Mam aplikację ASP.NET 4.0 działającą na szczycie IIS 7.5 na 64-bitowym komputerze z systemem Windows Server 2008 R2 Enterprise z dużą ilością pamięci RAM, procesora, dysku itp.
Przy każdym żądaniu sieci Web aplikacja ASP.NET nawiązuje połączenie z usługą internetową zaplecza (za pośrednictwem surowych gniazd), która działa na tym samym komputerze.
Problem: wydaje się, że coś ogranicza liczbę jednoczesnych połączeń z usługą internetową zaplecza. Podejrzewa się, że liczba jednoczesnych połączeń dochodzi do 16.
Znalazłem ten kluczowy artykuł firmy Microsoft wyjaśniający, jak dostosować ustawienia usług IIS, aby dostosować je do aplikacji ASP.NET, które wysyłają wiele żądań usług internetowych: http://support.microsoft.com/?id=821268#tocHeadRef
Postępowałem zgodnie z zaleceniami artykułu, ale nadal nie miałem szczęścia. Szczególnie interesujące jest maxconnection
ustawienie, na które zderzyłem się nawet z 999.
Jakieś pomysły, co jeszcze mogłoby ograniczać połączenia?
Uwaga: kiedy wyłączę usługi IIS z mieszanki i każę klientom łączyć się bezpośrednio z usługą sieciową zaplecza, z radością otworzy ona tyle połączeń, ile potrzebuję, więc jestem pewien, że zaplecze nie jest wąskim gardłem. To musi być coś w IIS / ASP.NET-land.
Oto odpowiednia sekcja, z machine.config
której jestem pewien, że jest czytana przez aplikację (weryfikowana przez appcmd.exe
):
<system.web>
<processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
<httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>
<httpHandlers />
<membership>
<providers>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<profile>
<providers>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>
<roleManager>
<providers>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="AspNetWindowsTokenRoleProvider" applicationName="/"
type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
</system.web>
<system.net>
<connectionManagement>
<add address="*" maxconnection="999"/>
</connectionManagement>
</system.net>
źródło
Odpowiedzi:
Większość udzielonych tutaj odpowiedzi dotyczy liczby żądań przychodzących do usługi wewnętrznej zaplecza, a nie liczby żądań wychodzących, które możesz wysłać z aplikacji ASP.net do usługi wewnętrznej bazy danych.
To nie usługa sieciowa zaplecza ogranicza tutaj szybkość żądań, jest to liczba otwartych połączeń, które aplikacja wywołująca chce nawiązać z tym samym punktem końcowym (tym samym adresem URL).
Możesz usunąć to ograniczenie, dodając następującą sekcję konfiguracji do pliku machine.config:
<configuration> <system.net> <connectionManagement> <add address="*" maxconnection="65535"/> </connectionManagement> </system.net> </configuration>
Możesz oczywiście wybrać bardziej rozsądną liczbę, jeśli chcesz, na przykład 50 lub 100 jednoczesnych połączeń. Ale powyższe otworzy go aż do max. Możesz również określić konkretny adres dla reguły otwartego limitu powyżej zamiast znaku „*”, który wskazuje wszystkie adresy.
Dokumentacja MSDN dotycząca System.Net.connectionManagement
Kolejny wspaniały zasób do zrozumienia ConnectManagement w .NET
Mam nadzieję, że to rozwiązuje Twój problem!
EDYCJA: Ups, widzę, że masz zarządzanie połączeniami wymienione w powyższym kodzie. Zostawię powyższe informacje, ponieważ są one istotne dla przyszłych pytających z tym samym problemem. Należy jednak pamiętać, że obecnie na większości nowoczesnych serwerów znajdują się 4 różne pliki machine.config!
Istnieje .NET Framework v2 działający zarówno w wersji 32-bitowej, jak i 64-bitowej, a także .NET Framework v4 również działający w wersji 32-bitowej i 64-bitowej. W zależności od wybranych ustawień puli aplikacji możesz używać jednego z tych 4 różnych plików machine.config! Sprawdź wszystkie 4 pliki machine.config, które zazwyczaj znajdują się tutaj:
źródło
machine.config
(64-bitowy 4.0).Zdaję sobie sprawę, że pytanie może być dość stare, ale mówisz, że backend działa na tym samym serwerze. Oznacza to na innym porcie, prawdopodobnie innym niż domyślny port 80.
Czytałem, że kiedy używasz elementu konfiguracyjnego "connectionManagement", musisz podać numer portu, jeśli różni się od domyślnego 80.
LINK: ustawienie maxConnection może nie działać nawet autoConfig = false w ASP.NET
Po drugie, jeśli zdecydujesz się użyć domyślnej konfiguracji (adres = "*") rozszerzonej o własną wartość specyficzną dla zaplecza, możesz rozważyć umieszczenie tej wartości na pierwszym miejscu! W przeciwnym razie, jeśli zostanie wysłane żądanie, * pasuje jako pierwsze i przyjmowane są domyślnie 2 połączenia. Podobnie jak w przypadku korzystania z sekcji w pliku web.config.
LINK: <remove> Element do zarządzania połączeniami (ustawienia sieci)
Mam nadzieję, że to komuś pomoże.
źródło
Czy to możliwe, że używasz odwołania do usługi sieci Web opartej na WCF? Domyślnie ServiceThrottlingBehavior.MaxConcurrentCalls to 16.
Możesz spróbować zaktualizować
<serviceThrottling>
element zachowania odwołania do usługi<serviceThrottling maxConcurrentCalls="999" maxConcurrentSessions="999" maxConcurrentInstances="999" />
(Zauważ, że polecam powyższe ustawienia.) Zobacz MSDN, aby uzyskać więcej informacji na temat konfigurowania odpowiedniego
<behavior>
elementu.źródło
TcpClient
(usługa sprzedaje niestandardowe binarne obiekty blob, a nie WCF / SOAP lub podobne). Wydaje się, że te opcje konfiguracji mają na ciebie wpływ, jeśli używaszServiceHost
, a nieTcpClient
; brakuje mi czegośCzy próbowałeś programowo ustawić wartość statycznej właściwości DefaultConnectionLimit ?
Oto dobre źródło informacji o tym prawdziwym bólu głowy ... Wykorzystanie wątków ASP.NET w usługach IIS 7.5, IIS 7.0 i IIS 6.0 z aktualizacjami dla platformy 4.0.
źródło
Zobacz sekcję „Threading” na tej stronie: http://msdn.microsoft.com/en-us/library/ff647786.aspx wraz z sekcją „Połączenia”.
Czy próbowałeś podnieść atrybut maxconnection ustawienia processModel?
źródło
maxconnection
atrybut nie dotyczy wywołań lokalnych usług sieciowych. W tym konkretnym przypadku usługa sieciowa jest lokalna, ale mamy ten sam problem w innym środowisku, w którym usługa nie jest lokalna.minLocalRequestFreeThreads
- ten proces roboczy używa tego ustawienia do kolejkowania żądań z hosta lokalnego (gdy aplikacja WWW wywołuje usługę WWW na tym samym serwerze ), jeśli liczba dostępnych wątków w puli wątków spadnie poniżej tej liczby. To ustawienie jest podobne do minFreeThreads, ale dotyczy tylko żądań używających localhost .minLocalRequestFreeThreads
(patrz mojemachine.config
w pytaniu.Jeśli nie jest zdefiniowany w usłudze sieci Web, aplikacji lub serwerze (Apache lub IIS), który obsługuje usługę sieci Web, można utworzyć nieskończone połączenia aż do awarii
źródło
podczas testowania wydajności miarą, którą się kieruję, jest RPS, czyli liczba żądań na sekundę, które serwer może obsłużyć w ramach akceptowalnego opóźnienia.
teoretycznie jeden serwer może obsługiwać tylko tyle żądań jednocześnie, ile ma jego rdzeni.
Nie wygląda na to, że problemem jest model wątków ASP.net, ponieważ może on potencjalnie obsłużyć tysiące obrotów na sekundę. Wygląda na to, że problem może dotyczyć Twojej aplikacji. Czy używasz jakichkolwiek prymitywów synchronizacji?
jakie jest również opóźnienie w twoich usługach internetowych, czy reagują one bardzo szybko (w ciągu mikrosekund), jeśli nie, możesz rozważyć połączenia asynchroniczne, aby nie blokować
Jeśli to nie pomoże, możesz wyprofilować swój kod za pomocą programu Visual Studio lub profilera Redgate
źródło