W ciągu ostatnich kilku dni zbyt często widzimy ten komunikat o błędzie w naszej witrynie:
„Upłynął limit czasu. Limit czasu upłynął przed uzyskaniem połączenia z puli. Mogło to nastąpić, ponieważ wszystkie połączenia w puli były w użyciu i osiągnięto maksymalny rozmiar puli.”
Od dłuższego czasu nic nie zmieniliśmy w naszym kodzie. Poprawiłem kod, aby sprawdzić otwarte połączenia, które się nie zamknęły, ale stwierdziłem, że wszystko jest w porządku.
Jak mogę to rozwiązać?
Czy muszę edytować tę pulę?
Jak mogę edytować maksymalną liczbę połączeń w tej puli?
Jaka jest zalecana wartość witryny o dużym natężeniu ruchu?
Aktualizacja:
Czy muszę coś edytować w IIS?
Aktualizacja:
Przekonałem się, że liczba aktywnych połączeń wynosi od 15 do 31, i odkryłem, że maksymalna dozwolona liczba połączeń skonfigurowana na serwerze SQL to ponad 3200 połączeń, jest o 31 za dużo lub powinienem coś edytować w konfiguracji ASP.NET ?
źródło
Odpowiedzi:
W większości przypadków problemy z pulowaniem połączeń są związane z „przeciekami połączeń”. Twoja aplikacja prawdopodobnie nie zamyka poprawnie i konsekwentnie połączeń z bazą danych. Po pozostawieniu otwartych połączeń pozostają one zablokowane, dopóki moduł do usuwania śmieci .NET nie zamknie ich za Ciebie, wywołując ich
Finalize()
metodę.Chcesz się upewnić, że naprawdę zamykasz połączenie . Na przykład następujący kod spowoduje wyciek połączenia, jeśli kod pomiędzy
.Open
iClose
zgłasza wyjątek:Prawidłowy sposób byłby następujący:
lub
Gdy funkcja zwróci połączenie z metody klasy, pamiętaj, aby buforować ją lokalnie i wywołać jej
Close
metodę. Wyciekniesz z połączenia za pomocą tego kodu, na przykład:Połączenie zwrócone z pierwszego połączenia do
getConnection()
nie jest zamykane. Zamiast zamykać połączenie, ta linia tworzy nowe i próbuje je zamknąć.Jeśli używasz
SqlDataReader
lub aOleDbDataReader
, zamknij je. Chociaż wydaje się, że zamknięcie samego połączenia załatwia sprawę, włóż dodatkowy wysiłek, aby jawnie zamknąć obiekty czytnika danych podczas ich używania.W artykule „ Dlaczego przepełnienie puli połączeń? ” Z magazynu MSDN / SQL Magazine wyjaśnia wiele szczegółów i sugeruje niektóre strategie debugowania:
sp_who
lubsp_who2
. Te systemowe procedury składowane zwracają informacje zsysprocesses
tabeli systemowej, która pokazuje status i informacje o wszystkich działających procesach. Zasadniczo zobaczysz jeden identyfikator procesu serwera (SPID) na połączenie. Jeśli nazwa połączenia została nazwana przy użyciu argumentu Nazwa aplikacji w ciągu połączenia, można łatwo znaleźć działające połączenia.TSQL_Replay
szablonem SQLProfiler do śledzenia otwartych połączeń. Jeśli znasz program Profiler, ta metoda jest łatwiejsza niż odpytywanie za pomocą sp_who.źródło
Po zainstalowaniu .NET Framework wer. 4.1.1 nasze połączenia ze zdalną bazą danych natychmiast zaczęły wygasać z powodu tej zmiany .
Aby to naprawić, po prostu dodaj parametr
TransparentNetworkIPResolution
do ciągu połączenia i ustaw go na false :źródło
Jeśli twoje użycie nie wzrosło, wydaje się mało prawdopodobne, aby zaległa praca. IMO, najbardziej prawdopodobną opcją jest to, że coś korzysta z połączeń i nie zwalnia ich natychmiast. Czy na pewno używasz
using
we wszystkich przypadkach? Lub (poprzez dowolny mechanizm) zwalniając połączenia?źródło
Czy sprawdziłeś, czy czytniki danych nie są zamknięte i czy odpowiedz.redirects przed zamknięciem połączenia lub centrum danych? Połączenia pozostają otwarte, jeśli nie zamkniesz ich przed przekierowaniem.
źródło
Od czasu do czasu napotykamy ten problem również na naszej stronie internetowej. Winowajcą w naszym przypadku są nieaktualne statystyki / indeksy. Powoduje to, że wcześniej szybko działające zapytanie (ostatecznie) staje się wolne i kończy się limit czasu.
Spróbuj zaktualizować statystyki i / lub odbudować indeksy w tabelach objętych zapytaniem i sprawdź, czy to pomoże.
źródło
Możesz określić minimalny i maksymalny rozmiar puli, określając
MinPoolSize=xyz
i / lubMaxPoolSize=xyz
w ciągu połączenia. Ta przyczyna problemu może być jednak inna.źródło
Ten problem również napotkałem, gdy korzystałem z warstwy danych innej firmy w jednej z moich aplikacji .NET. Problem polegał na tym, że warstwa nie zamykała poprawnie połączeń.
Wyrzuciliśmy warstwę i sami ją stworzyliśmy, która zawsze zamyka i usuwa połączenia. Od tego czasu nie otrzymujemy już błędu.
źródło
Możesz także tego spróbować, aby rozwiązać problem z przekroczeniem limitu czasu:
Jeśli nie dodałeś httpRuntime do webconfig, dodaj to w
<system.web>
tagui
Zmodyfikuj parametry połączenia w ten sposób;
Przy ostatnim użyciu
źródło
Wynika to głównie z faktu, że połączenie nie zostało zamknięte w aplikacji. Użyj „MinPoolSize” i „MaxPoolSize” w ciągu połączenia.
źródło
W moim przypadku nie zamykałem obiektu DataReader.
źródło
Jeśli pracujesz nad złożonym starszym kodem, w którym proste użycie (..) {..} nie jest możliwe - tak jak ja - możesz zajrzeć do fragmentu kodu, który opublikowałem w tym pytaniu SO, w celu ustalenia sposobu stos wywołań tworzenia połączenia, gdy połączenie jest potencjalnie wyciekiem (nie jest zamykane po upływie określonego czasu). Ułatwia to wykrycie przyczyny wycieków.
źródło
Nie twórz zbyt często połączenia SQL. Otwórz jedno lub dwa połączenia i użyj ich do wszystkich następnych operacji SQL.
Wydaje się, że nawet podczas
Dispose
inicjowania połączeń zgłaszany jest wyjątek.źródło
Oprócz opublikowanych rozwiązań ....
W przypadku 1000 stron starszego kodu, z których każdy wywołuje wspólny GetRS wiele razy, oto inny sposób na rozwiązanie tego problemu:
W istniejącej wspólnej bibliotece DLL dodaliśmy opcję CommandBehavior.CloseConnection :
Następnie na każdej stronie, o ile zamykasz czytnik danych, połączenie jest również automatycznie zamykane, aby zapobiec wyciekowi połączenia.
źródło
Właśnie miałem ten sam problem i chciałem podzielić się tym, co pomogło mi znaleźć źródło: dodaj nazwę aplikacji do ciągu połączenia, a następnie zainicjuj otwarte połączenie z serwerem SQL
źródło
Ten problem miałem w kodzie. Wkleję przykładowy kod, który przekroczyłem, poniżej błędu. Limit czasu upłynął przed uzyskaniem połączenia z puli. Może się tak zdarzyć, ponieważ wszystkie połączenia w puli były w użyciu i osiągnięto maksymalny rozmiar puli.
Chcesz zamknąć połączenie za każdym razem. Wcześniej nie miałem bliskiego połączenia z tego powodu, dostałem błąd. Po dodaniu instrukcji close nadszedł ten błąd
źródło
Wyciekałeś z połączeń w swoim kodzie. Możesz spróbować użyć przy użyciu do potwierdzenia, że je zamykasz.
https://blogs.msdn.microsoft.com/angelsb/2004/08/25/connection-pooling-and-the-timeout-expired-exception-faq/
źródło
Ten problem, z którym się wcześniej spotkałem. Skończyło się to problemem z zaporą ogniową. Właśnie dodałem regułę do zapory. Musiałem otworzyć port,
1433
aby serwer SQL mógł połączyć się z serwerem.źródło
Użyj tego:
źródło
SqlConnection.ClearPool
, ale czy to po prostu zapobiega zwalnianiu twojego aktualnego połączenia z powrotem do puli połączeń? Myślałem, że idea puli połączeń polega na umożliwieniu szybszych połączeń. Z pewnością uwalnianie połączenia z puli za każdym razem, gdy jest ono zakończone, oznacza, że NOWYCH połączeń trzeba będzie tworzyć KAŻDYM raz, zamiast wyciągać zapasowe z puli? Proszę wyjaśnić, w jaki sposób i dlaczego ta technika jest przydatna.Tak, istnieje sposób na zmianę konfiguracji. Jeśli korzystasz z serwera dedykowanego i potrzebujesz więcej połączeń SQL, możesz zaktualizować wpisy „maksymalnego rozmiaru puli” w obu ciągach połączeń, postępując zgodnie z tymi instrukcjami:
Znajdź parametry połączenia, będą one wyglądać podobnie do poniższych przykładów:
"add name =" SiteSqlServer "connectionString =" server = (lokalny); baza danych = nazwa_db; uid = dbuser; pwd = dbpassword; pooling = true; czas życia połączenia = 120; maksymalny rozmiar puli = 25; ""
5.Zmień maksymalny rozmiar puli = wartość X na wymagany rozmiar puli.
źródło
Upewnij się, że skonfigurowałeś prawidłowe ustawienia dla puli połączeń. Jest to bardzo ważne, jak wyjaśniłem w następującym artykule: https://medium.com/@dewanwaqas/configurations-that-s Znacząco-improves-your-app-performance-built-using-sql-server- and- net- ed044e53b60 Jeśli to zrobisz, zobaczysz drastyczną poprawę wydajności aplikacji.
źródło
W moim przypadku miałem nieskończoną pętlę (z właściwości Get próbującej uzyskać wartość z bazy danych), która ciągle otwierała setki połączeń Sql.
Aby odtworzyć problem, spróbuj:
źródło