Naprawianie powolnego ładowania początkowego dla usług IIS

132

Usługi IIS mają irytującą funkcję dla witryn o małym ruchu, w których ponownie przetwarzają nieużywane procesy robocze, powodując, że pierwszy użytkownik odwiedzający witrynę po pewnym czasie uzyskuje wyjątkowo duże opóźnienie (ponad 30 sekund).

Szukałem rozwiązania problemu i znalazłem te potencjalne rozwiązania.

A. Użyj wtyczki Application Initialization

B. Użyj funkcji Auto-Start z .NET 4

C. Wyłącz limit czasu bezczynności (w obszarze Resetowanie usług IIS)

D. Wstępnie skompiluj witrynę

Zastanawiam się, który z nich jest preferowany, a co ważniejsze, dlaczego istnieje tak wiele rozwiązań tego samego problemu? (Domyślam się, że nie, i po prostu nie rozumiem czegoś poprawnie).

Edytować

Wydaje się, że wykonanie C wydaje się wystarczać, aby moja witryna była rozgrzana, ale odkryłem, że prawdziwy korzeń powolności mojej witryny ma związek z Entity Framework, którego nie mogę zrozumieć, dlaczego robi się zimno. Zobacz to pytanie, na które niestety nie ma jeszcze odpowiedzi!

W końcu musiałem po prostu przygotować skrypt rozgrzewający, aby od czasu do czasu odwiedzać moją witrynę, aby upewnić się, że działa szybko.

Cavyn VonDeylen
źródło
Cześć przyjacielu, czy wystarczy wykonanie C? Czemu ? Czy potrzebujemy go tylko używać, czy też potrzebujemy go wyłączyć? Zawsze uważam, że pierwsze żądanie drugiego dnia jest bardzo wolne od IIS7.5
qakmak

Odpowiedzi:

36

Opcje A, B i D wydają się należeć do tej samej kategorii, ponieważ wpływają tylko na początkowy czas uruchomienia, powodują rozgrzanie strony internetowej, takie jak kompilacja i ładowanie bibliotek do pamięci.

Użycie C, ustawienie limitu czasu bezczynności, powinno wystarczyć, aby kolejne żądania do serwera były obsługiwane szybko (ponowne uruchomienie puli aplikacji zajmuje trochę czasu - w kolejności sekund).

O ile wiem, istnieje limit czasu potrzebny do zaoszczędzenia pamięci, której mogą potrzebować inne strony internetowe działające równolegle na tym komputerze. Cena jest taka, że ​​jednorazowo powolny czas ładowania.

Oprócz tego, że pula aplikacji jest zamykana w przypadku braku aktywności użytkownika, pula aplikacji będzie również domyślnie odtwarzana co 1740 minut (29 godzin).

Z technet:

Pule aplikacji Internetowych usług informacyjnych (IIS) można okresowo odtwarzać, aby uniknąć niestabilnych stanów, które mogą prowadzić do awarii aplikacji, zawieszeń lub wycieków pamięci.

Dopóki recykling puli aplikacji jest włączony, powinno wystarczyć. Ale jeśli naprawdę chcesz uzyskać najwyższą wydajność dla większości komponentów, powinieneś również użyć czegoś takiego jak wspomniany moduł inicjowania aplikacji.

Răzvan Flavius ​​Panda
źródło
Czy poleciłbyś po prostu wyłączenie limitu czasu bezczynności? Czy spowodowałoby to problemy wzdłuż linii (zgaduję, że jest tam z jakiegoś powodu)?
Cavyn VonDeylen
3
To właściwie nie rozwiązuje mojego problemu (zobacz moją edycję), ale zgodziłem się, ponieważ odpowiedziałeś na moje pierwotne pytanie.
Cavyn VonDeylen
10

Wyzwanie hostingowe

Musisz pamiętać, że żadna z opcji konfiguracji maszyny nie jest dostępna, jeśli jesteś hostowany na serwerze współdzielonym, jak wielu z nas (mniejsze firmy i osoby prywatne).

Narzut ASP.NET MVC

Moja witryna zajmuje co najmniej 30 sekund, jeśli nie została wyświetlona od ponad 20 minut (a aplikacja internetowa została zatrzymana). To jest okropne.

Inny sposób testowania wydajności

Istnieje inny sposób sprawdzenia, czy jest to uruchomienie ASP.NET MVC, czy coś innego. Upuść zwykłą stronę HTML w swojej witrynie, na którą możesz trafić bezpośrednio.
Jeśli problem jest związany z uruchomieniem ASP.NET MVC, strona HTML zostanie renderowana prawie natychmiast, nawet jeśli aplikacja internetowa nie została uruchomiona.
W ten sposób po raz pierwszy rozpoznałem, że problem tkwi w starcie ASP.NET MVC. Załadowałem stronę HTML w dowolnym momencie i ładowała się błyskawicznie. Następnie po wejściu na tę stronę HTML trafiałem na jeden z moich adresów URL ASP.NET MVC i otrzymałem komunikat Chrome „Oczekiwanie na raddev.us ...”

Kolejny test z pomocnym skryptem

Następnie napisałem skrypt LINQPad (sprawdź http://linqpad.net po więcej), który będzie trafiał na moją stronę internetową co 8 minut (mniej niż czas na rozładowanie aplikacji - który powinien wynosić 20 minut) i pozwoliłem działa godzinami.

Podczas działania skryptu trafiałem na moją witrynę internetową i za każdym razem moja witryna wyświetlała się niesamowicie szybko. To daje mi dobre wyobrażenie, że najprawdopodobniej spowolnienie, którego doświadczyłem, było spowodowane czasami uruchamiania ASP.NET MVC.

Pobierz LinqPad i uruchom następujący skrypt - po prostu zmień adres URL na własny i pozwól mu działać, a możesz to łatwo przetestować. Powodzenia.

UWAGA : W LinqPad musisz nacisnąć F4 i dodać odwołanie do System.Net, aby dodać bibliotekę, która pobierze twoją stronę.

TAKŻE : upewnij się, że zmienisz zmienną String URL, aby wskazywała na adres URL, który będzie ładował trasę z witryny ASP.NET MVC, aby silnik działał.

System.Timers.Timer webKeepAlive = new System.Timers.Timer();
Int64 counter = 0;
void Main()
{
    webKeepAlive.Interval = 5000;
    webKeepAlive.Elapsed += WebKeepAlive_Elapsed;
    webKeepAlive.Start();
}

private void WebKeepAlive_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    webKeepAlive.Stop();
    try
    {
        // ONLY the first time it retrieves the content it will print the string
        String finalHtml = GetWebContent();
        if (counter < 1)
        {
            Console.WriteLine(finalHtml);
        }
        counter++;
    }
    finally
    {
        webKeepAlive.Interval = 480000; // every 8 minutes
        webKeepAlive.Start();
    }
}

public String GetWebContent()
{
    try
    {
    String URL = "http://YOURURL.COM";
    WebRequest request = WebRequest.Create(URL);
    WebResponse response = request.GetResponse();
    Stream data = response.GetResponseStream();
    string html = String.Empty;
    using (StreamReader sr = new StreamReader(data))
    {
        html = sr.ReadToEnd();
    }
    Console.WriteLine (String.Format("{0} : success",DateTime.Now));
    return html;
    }
    catch (Exception ex)
    {
        Console.WriteLine (String.Format("{0} -- GetWebContent() : {1}",DateTime.Now,ex.Message));
        return "fail";
    }
}
raddevus
źródło
3

Pisanie usługi / skryptu pinga, aby trafić na twoją bezczynną witrynę, jest raczej najlepszym sposobem, ponieważ będziesz mieć pełną kontrolę. Inne opcje, o których wspomniałeś, byłyby dostępne, jeśli wydzierżawiłeś dedykowaną skrzynkę hostingową.

We współdzielonej przestrzeni hostingowej skrypty rozgrzewkowe są najlepszą obroną pierwszego poziomu (najlepszą pomocą jest samopomoc). Oto artykuł, w którym przedstawiono pomysł, jak to zrobić z własnej aplikacji internetowej .

David Chelliah
źródło
właśnie zaktualizowałem ten stary wątek, na wypadek, gdyby ktoś
szukał
2

Użyłbym B, ponieważ w połączeniu z recyklingiem w procesie pracowniczym oznacza to, że będzie tylko opóźnienie podczas recyklingu. Pozwala to uniknąć opóźnienia zwykle związanego z inicjalizacją w odpowiedzi na pierwsze żądanie po bezczynności. Możesz również zachować korzyści płynące z recyklingu.

Zestaw
źródło
2

Dobrą opcją pingowania witryny zgodnie z harmonogramem jest skorzystanie z Microsoft Flow, który jest bezpłatny do 750 uruchomień miesięcznie. Bardzo łatwo jest stworzyć przepływ, który będzie odwiedzał Twoją witrynę co godzinę, aby była ciepła. Możesz nawet obejść ich limit 750, tworząc pojedynczy przepływ z opóźnieniami oddzielającymi wiele trafień w Twojej witrynie.

https://flow.microsoft.com

LMK
źródło
2

Zobacz ten artykuł, aby uzyskać wskazówki, jak rozwiązać problemy z wydajnością. Obejmuje to zarówno problemy z wydajnością związane z uruchamianiem, w sekcji „zimny start”. Większość z nich będzie miała znaczenie bez względu na typ serwera, z którego korzystasz, lokalnie czy na produkcji.

https://blogs.msdn.microsoft.com/b/mcsuksoldev/2011/01/19/common-performance-issues-on-asp-net-web-sites/

Jeśli aplikacja deserializuje cokolwiek z XML (i obejmuje to usługi sieci Web…), upewnij się, że SGEN jest uruchamiany na wszystkich plikach binarnych biorących udział w deserializacji i umieść powstałe biblioteki DLL w globalnej pamięci podręcznej zestawów (GAC). Powoduje to prekompilację wszystkich obiektów serializacji używanych przez zestawy, z którymi był uruchomiony SGEN, i buforowanie ich w wynikowej bibliotece DLL. Może to przynieść ogromne oszczędności czasu przy pierwszej deserializacji (ładowaniu) plików konfiguracyjnych z dysku i początkowych wywołań usług internetowych. http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx

Jeśli którykolwiek z serwerów IIS nie ma wychodzącego dostępu do Internetu, wyłącz sprawdzanie listy odwołanych certyfikatów (CRL) pod kątem plików binarnych Authenticode, dodając generatorenerPublisherEvidence = ”false” do pliku machine.config. W przeciwnym razie każdy proces roboczy może zawiesić się na ponad 20 sekund podczas uruchamiania, podczas gdy próba połączenia z Internetem w celu uzyskania listy CRL przekroczy limit czasu. http://blogs.msdn.com/amolravande/archive/2008/07/20/startup-performance-disable-the-generatepublisherevidence-property.aspx

http://msdn.microsoft.com/en-us/library/bb629393.aspx

Rozważ użycie NGEN we wszystkich zespołach. Jednak bez uważnego użycia nie daje to dużego wzrostu wydajności. Dzieje się tak, ponieważ adresy ładowania podstawowego wszystkich plików binarnych, które są ładowane przez każdy proces, muszą być starannie ustawione podczas kompilacji, aby nie nakładały się. Jeśli pliki binarne będą musiały być ponownie bazowane podczas ładowania z powodu konfliktów adresów, prawie cały wzrost wydajności wynikający z używania NGEN zostanie utracony. http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

nuzzolilo
źródło
0

Otrzymywałem stałe 15-sekundowe opóźnienie przy pierwszym żądaniu po 4 minutach braku aktywności. Mój problem polegał na tym, że moja aplikacja korzystała z uwierzytelniania zintegrowanego systemu Windows na serwerze SQL, a profil usługi znajdował się w innej domenie niż serwer. Spowodowało to uwierzytelnianie między domenami z usług IIS do SQL po zainicjowaniu aplikacji - i to było prawdziwe źródło mojego opóźnienia. Zmieniłem na używanie logowania SQL zamiast uwierzytelniania systemu Windows. Opóźnienie natychmiast minęło. Nadal mam wszystkie ustawienia inicjalizacji aplikacji, które pomagają poprawić wydajność, ale w moim przypadku mogły one wcale nie być potrzebne.

Droobie
źródło