Zalecenia dotyczące optymalizowania kodu i infrastruktury

Dotyczy tego zalecenia listy kontrolnej wydajności platformy Azure Well-Architected Framework:

PE:07 Optymalizowanie kodu i infrastruktury. Używaj kodu, który jest wydajny, i upewnij się, że odciąża obowiązki platformy. Używaj kodu i infrastruktury tylko do celów podstawowych i tylko wtedy, gdy jest to konieczne.

W tym przewodniku opisano zalecenia dotyczące optymalizacji wydajności kodu i infrastruktury. Aby zoptymalizować kod i infrastrukturę, należy używać składników tylko do ich podstawowego celu i tylko wtedy, gdy jest to konieczne. W przypadku nadmiernego użycia kodu i infrastruktury tworzy niepotrzebne zużycie zasobów, wąskie gardła i powolne odpowiedzi. Aby zrekompensować te nieefektywności, należy dodać więcej zasobów, aby wykonać te same zadania.

Definicje

Okres Definicja
Współbieżność Gdy wiele zadań lub procesów jest wykonywanych jednocześnie, ale niekoniecznie w tym samym czasie.
Architektura procesora Składniki i zasady wpływające na sposób działania komputera.
Kompresja danych Działanie zmniejszania rozmiaru plików przez zminimalizowanie nadmiarowych danych.
Sterta Obszar w pamięci używany do alokacji pamięci środowiska uruchomieniowego.
Przeciek pamięci Gdy obciążenie nie może zwolnić przydzielonej pamięci po tym, jak pamięć nie jest już potrzebna.
Równoległości prostych W przypadku wykonywania wielu zadań lub procesów w tym samym czasie.

Kluczowe strategie projektowania

Optymalizacja kodu i infrastruktury wiąże się z dostrajaniem kodu i pomocniczej infrastruktury w celu zwiększenia wydajności. Wymaga to wydajnego kodu, który szybko wykonuje zadania i nie traci zasobów. Wymaga dobrze zaprojektowanej infrastruktury, która została usprawniona, aby uniknąć niepotrzebnej złożoności. Obciążenie powinno korzystać z nieodłącznych możliwości platformy. Jest to podejście, które pomaga zapewnić, że zarówno kod, jak i infrastruktura są używane głównie do ich podstawowych celów i tylko wtedy, gdy jest to konieczne.

Optymalizowanie wydajności kodu

Aby zoptymalizować wydajność kodu, zmodyfikuj kod, aby zmniejszyć użycie zasobów, zminimalizować środowisko uruchomieniowe i zwiększyć wydajność. Możesz zmodyfikować kod, aby zwiększyć wydajność i szybkość programu programowego. Nie maskuj problemów z wydajnością ataków siłowych. Atak siłowy oznacza dodanie zasobów obliczeniowych w celu zrekompensowania wydajności kodu, takich jak dodanie dodatkowej pojemności zamiast adresowania źródła. Należy rozwiązać problemy z wydajnością związane z optymalizacją. Podczas optymalizacji wydajności kodu pomaga zmaksymalizować wykorzystanie zasobów systemowych, skraca czas odpowiedzi, zmniejsza opóźnienie i zwiększa środowisko użytkownika.

Instrumentacja kodu

Instrumentacja kodu odnosi się do praktyki dodawania fragmentów kodu lub bibliotek do kodu, które zbierają dane i monitorują wydajność kodu w czasie wykonywania. Instrumentacja kodu umożliwia deweloperom zbieranie informacji o kluczowych metrykach, takich jak użycie zasobów (procesor CPU, użycie pamięci) i czas wykonywania. Instrumentując kod, deweloperzy mogą uzyskać wgląd w gorące ścieżki kodu, zidentyfikować wąskie gardła wydajności i zoptymalizować kod w celu uzyskania lepszej wydajności.

W idealnym środowisku należy przeprowadzić analizę kodu na wczesnym etapie cyklu życia tworzenia oprogramowania. Wcześniej przechwycenie problemu z kodem jest tańsze, aby go rozwiązać. Chcesz zautomatyzować jak najwięcej tej analizy kodu. Użyj narzędzi do analizy kodu dynamicznego i statycznego, aby zmniejszyć nakład pracy ręcznej. Należy jednak pamiętać, że testowanie to nadal jest symulacją produkcji. Środowisko produkcyjne zapewnia najczystszą wiedzę na temat optymalizacji kodu.

Kompromis: narzędzia do monitorowania kodu mogą zwiększyć koszty.

Identyfikowanie ścieżek gorących

Instrumentując kod, można mierzyć zużycie zasobów dla różnych ścieżek kodu. Te pomiary ułatwiają identyfikowanie ścieżek gorących. Ścieżki aktywne mają znaczący wpływ na wydajność i użycie zasobów. Są to krytyczne lub często wykonywane sekcje programu, które wymagają wysokiej wydajności i małych opóźnień. Aby zidentyfikować gorące ścieżki kodu, należy wziąć pod uwagę następujące kroki:

  • Analizowanie danych środowiska uruchomieniowego: zbierz dane środowiska uruchomieniowego i przeanalizuj je, aby zidentyfikować obszary kodu, które zużywają znaczne zasoby, takie jak procesor CPU, pamięć lub operacje we/wy. Poszukaj wzorców lub sekcji kodu, które są często wykonywane lub trwają długo.

  • Mierzenie wydajności: użyj narzędzi profilowania lub struktur testowania wydajności, aby zmierzyć czas wykonywania i zużycie zasobów w różnych ścieżkach kodu. Pomaga zidentyfikować wąskie gardła i obszary na potrzeby poprawy.

  • Rozważmy logikę biznesową i efekt użytkownika: oceń znaczenie różnych ścieżek kodu w zależności od ich istotności dla funkcjonalności aplikacji lub krytycznych operacji biznesowych. Określ, które ścieżki kodu mają kluczowe znaczenie dla dostarczania wartości użytkownikom lub spełnienia wymagań dotyczących wydajności.

Optymalizowanie logiki kodu

Optymalizacja logiki kodu polega na udoskonalaniu struktury i projektowania kodu w celu wykonywania zadań z mniejszą liczbą zasobów. Ulepszona logika zmniejsza niepotrzebne operacje. Tworzy szybsze wykonywanie z mniejszym zużyciem zasobów. Należy usunąć wszystkie niepotrzebne operacje w ścieżce kodu, które mogą mieć wpływ na wydajność. Określ priorytety optymalizacji ścieżek gorących, aby zobaczyć największe wzrosty wydajności. Aby zoptymalizować logikę kodu, rozważ następujące strategie:

  • Usuń niepotrzebne wywołania funkcji: przejrzyj kod i zidentyfikuj wszystkie funkcje, które nie są niezbędne dla żądanej funkcjonalności i mogą negatywnie wpłynąć na wydajność. Jeśli na przykład wywołanie funkcji wykonuje walidację ukończoną wcześniej w kodzie, możesz usunąć niepotrzebne wywołanie funkcji sprawdzania poprawności.

  • Minimalizuj operacje rejestrowania: rejestrowanie może być przydatne do debugowania i analizy, ale nadmierne rejestrowanie może mieć wpływ na wydajność. Oceń konieczność każdej operacji rejestrowania i usuń wszelkie niepotrzebne wywołania rejestrowania, które nie są krytyczne dla analizy wydajności.

  • Optymalizowanie pętli i warunkowych: analizowanie pętli i warunkowych w kodzie oraz identyfikowanie niepotrzebnych iteracji lub warunków, które można wyeliminować. Upraszczanie i optymalizowanie tych struktur może poprawić wydajność kodu. Zminimalizuj wywołania funkcji w pętlach i eliminuj nadmiarowe obliczenia. Rozważ przeniesienie obliczeń poza pętlę lub użycie wyrejestrowywania pętli.

  • Zmniejsz niepotrzebne przetwarzanie danych: przejrzyj kod pod kątem wszelkich niepotrzebnych operacji przetwarzania danych, takich jak nadmiarowe obliczenia lub przekształcenia. Wyeliminuj te niepotrzebne operacje, aby zwiększyć wydajność kodu.

  • Optymalizowanie struktur danych. Aby efektywnie przechowywać i pobierać dane, wybierz odpowiednie struktury danych, takie jak tablice, listy połączone, drzewa i tabele skrótów. Wybierz najlepszą strukturę danych dla konkretnego problemu. Odpowiednia struktura danych zwiększa wydajność aplikacji.

  • Minimalizuj żądania sieciowe: jeśli kod obejmuje wykonywanie żądań sieciowych, zminimalizuj liczbę żądań i zoptymalizuj ich użycie. Żądania wsadowe, jeśli to możliwe, i unikaj niepotrzebnych rund w celu zwiększenia wydajności.

  • Minimalizuj alokacje: Zidentyfikuj obszary, w których występuje nadmierna alokacja pamięci. Zoptymalizuj kod, zmniejszając niepotrzebne alokacje i ponownie używając istniejących zasobów, gdy jest to możliwe. Minimalizując alokacje, można zwiększyć wydajność pamięci i ogólną wydajność. Użyj odpowiednich strategii zarządzania pamięcią i odzyskiwania pamięci dla języka programowania.

  • Zmniejsz rozmiar struktury danych: oceń rozmiar struktur danych, takich jak klasy, i zidentyfikuj obszary, w których jest to możliwe. Przejrzyj wymagania dotyczące danych i wyeliminuj niepotrzebne pola lub właściwości. Zoptymalizuj użycie pamięci, wybierając odpowiednie typy danych i wydajnie pakując dane.

  • Używanie zestawów SDK i bibliotek zoptymalizowanych pod kątem wydajności. Użyj natywnych zestawów SDK lub bibliotek zoptymalizowanych pod kątem wydajności. Natywne zestawy SDK są przeznaczone do interakcji z usługami i zasobami na platformie lub w ramach platformy. Na przykład zestawy SDK natywne dla chmury działają lepiej z płaszczyznami danych usług w chmurze niż z niestandardowym dostępem do interfejsu API. Zestawy SDK są excel w obsłudze żądań sieciowych i optymalizowaniu interakcji. Biblioteki zoptymalizowane pod kątem wydajności, takie jak Math.NET, zawierają funkcje zoptymalizowane pod kątem wydajności. Po odpowiednim zastosowaniu funkcji można poprawić wydajność obciążenia.

  • Implementacja krzyżowa: należy wziąć pod uwagę skutki implementacji krzyżowych, takich jak oprogramowanie pośredniczące lub testy tokenów, i ocenić, czy negatywnie wpływają na wydajność.

Zapoznaj się z zaleceniami dotyczącymi wydajności specyficznymi dla języka programowania, z którym pracujesz. Oceń kod pod kątem tych zaleceń, aby zidentyfikować obszary pod kątem ulepszeń.

Kompromisy:

  • Optymalizacja kodu i ścieżek gorących wymaga wiedzy deweloperów w zakresie identyfikowania nieefektywności kodu jest subiektywna i może być wysoce wykwalifikowanych osób wymaganych do innych zadań.
  • Zestawy SDK zapewniają wygodę i eliminują złożoność interakcji z interfejsami API. Jednak zestawy SDK mogą ograniczać opcje kontroli i dostosowywania kodu niestandardowego.

Optymalizowanie zarządzania pamięcią

Optymalizacja zarządzania pamięcią polega na uściśliniu sposobu, w jaki obciążenie używa, przydziela i zwalnia zasoby pamięci w celu zwiększenia wydajności. Właściwe zarządzanie pamięcią poprawia wydajność kodu, ponieważ zmniejsza obciążenie operacji pamięci. Wydajne użycie pamięci zmniejsza opóźnienie, zapobiega spowolnieniu lub awariom systemu i maksymalizuje przepływność zadań obliczeniowych. Rozważ następujące strategie, aby zoptymalizować zarządzanie pamięcią.

Debugowanie problemów z pamięcią. Zrzuty pamięci to migawki pamięci aplikacji. Przechwytują stan pamięci aplikacji w określonym punkcie w czasie. Zrzuty pamięci umożliwiają retrospektywną analizę problemów związanych z pamięcią. Wybierz odpowiedni typ zrzutu pamięci na podstawie charakteru problemu, który próbujesz zdiagnozować, i dostępnych zasobów. Należy użyć miniaturowych zrzutów do rutynowego debugowania i pełnych zrzutów w przypadku złożonych, krytycznych problemów. Ta strategia zapewnia równowagę między użyciem zasobów a możliwościami diagnostycznymi. Wiele usług hostingu kodu obsługuje debugowanie pamięci. Wolisz usługi, które obsługują analizę pamięci w przypadku tych usług, które nie są obsługiwane. Poniżej przedstawiono podstawowe kroki debugowania problemów z pamięcią:

  1. Przechwyć zrzuty pamięci: zacznij od skonfigurowania mechanizmu przechwytywania zrzutów pamięci podczas wykonywania aplikacji. Przechwytywanie można wyzwalać ręcznie, automatycznie lub po spełnieniu określonych warunków (takich jak nadmierne zużycie pamięci). Niektóre usługi w chmurze mogą już oferować ten proces.

  2. Analizowanie zrzutów pamięci: po zebraniu zrzutów pamięci przeanalizuj je. Wiele narzędzi może pomóc w inspekcji tych zrzutów, takich jak WinDbg dla aplikacji systemu Windows lub GDB dla systemów opartych na systemie Unix.

  3. Identyfikowanie przecieków pamięci: skoncentruj się na identyfikowaniu przecieków pamięci podczas analizy. Przecieki pamięci pojawiają się, gdy aplikacja przydziela pamięć, ale nie może jej zwolnić, gdy pamięć nie jest już wymagana. Wyszukaj obiekty lub struktury danych, które pozostają w pamięci nawet wtedy, gdy mają zostać cofnięty przydział.

  4. Naprawianie i testowanie: po zidentyfikowaniu problematycznego kodu skoncentruj się na rozwiązywaniu problemów z pamięcią. Rozwiązania mogą obejmować prawidłowe zwalnianie pamięci, optymalizowanie struktur danych lub ponowne ocenianie praktyk zarządzania pamięcią. Upewnij się, że twoje rozwiązania są poddawane rygorystycznym testom w celu zapewnienia ich skuteczności.

  5. Iterowanie i monitorowanie: Zarządzanie pamięcią jest procesem ciągłym. Rutynowo monitoruj użycie pamięci aplikacji i utrwalone w zbieraniu zrzutów pamięci w środowisku produkcyjnym. Regularnie wracaj do etapów analizy i optymalizacji, aby upewnić się, że problemy z pamięcią nie pojawiają się ponownie wraz z kolejnymi modyfikacjami kodu.

Dzięki włączeniu analizy zrzutu pamięci do cyklu życia tworzenia oprogramowania można zwiększyć niezawodność i wydajność aplikacji. Pomaga zmniejszyć prawdopodobieństwo problemów związanych z pamięcią w środowisku produkcyjnym.

Zmniejszanie alokacji pamięci. Zminimalizuj alokacje pamięci, aby zmniejszyć całkowity rozmiar pamięci kodu. Obciążenie może efektywnie korzystać z dostępnej pamięci. Moduł zbierający elementy bezużyteczne musi odzyskiwać nieużywaną pamięć i zmniejsza częstotliwość i czas trwania cykli odzyskiwania pamięci. Alokacje pamięci mogą być kosztowne, zwłaszcza jeśli są one często wykonywane. Zminimalizuj alokacje pamięci, aby kod mógł działać szybko i wydajnie.

Pamięci podręczne przechowują często używane dane w pobliżu procesora, co zwiększa wydajność. W przypadku zminimalizowania alokacji pamięci jest mniej rywalizacji o miejsce w pamięci podręcznej, dzięki czemu można efektywnie korzystać z pamięci podręcznej. Duża liczba alokacji pamięci może obniżyć wydajność aplikacji i wygenerować błędy. Inne sposoby minimalizowania alokacji pamięci obejmują:

  • Zmienne lokalne: użyj zmiennych lokalnych zamiast zmiennych globalnych, aby zminimalizować zużycie pamięci.

  • Inicjowanie z opóźnieniem: zaimplementuj inicjowanie z opóźnieniem, aby odroczyć tworzenie obiektów lub zasobów, dopóki nie będą potrzebne.

  • Bufory: efektywnie zarządzaj buforami, aby uniknąć przydzielania dużych buforów pamięci.

  • Buforowanie obiektów: rozważ buforowanie obiektów w celu ponownego użycia dużych obiektów zamiast przydzielania i cofania ich przydziału.

Aby uzyskać więcej informacji, zobacz Zmniejszanie alokacji pamięci i Sterty dużych obiektów w systemach Windows.

Używanie współbieżności i równoległości

Korzystanie ze współbieżności i równoległości polega na wykonywaniu wielu zadań lub procesów jednocześnie lub w sposób nakładający się, aby efektywnie korzystać z zasobów obliczeniowych. Te techniki zwiększają ogólną przepływność i liczbę zadań, które może przetwarzać obciążenie. W przypadku równoczesnego lub równoległego uruchamiania zadań zmniejsza to środowisko uruchomieniowe aplikacji i zmniejsza opóźnienie i zwiększa czas odpowiedzi. Współbieżność i równoległość umożliwiają wydajne wykorzystanie zasobów obliczeniowych, takich jak rdzenie procesora CPU lub systemy rozproszone. Współbieżność i równoległość skutecznie dystrybuują obciążenie między zasoby obliczeniowe.

Użyj równoległości. Równoległość to zdolność systemu do jednoczesnego wyzwalania wielu zadań lub procesów na wielu zasobach obliczeniowych. Równoległość dzieli obciążenie na mniejsze zadania, które są uruchamiane równolegle. Równoległość można osiągnąć przy użyciu technik, takich jak przetwarzanie wieloprocesowe lub rozproszone. Dystrybuuj zadania między procesorami wielordzeniowymi, aby zoptymalizować zarządzanie obciążeniami. Zoptymalizuj kod, aby korzystać z architektury procesora CPU, modeli wątków i procesorów wielordzeniowych. Po równoległym uruchomieniu kodu wydajność zwiększa się, ponieważ obciążenie jest dystrybuowane na wiele rdzeni.

Użyj współbieżności. Współbieżność to zdolność systemu do uruchamiania wielu zadań lub procesów. Współbieżność umożliwia niezależne wykonywanie postępów w różnych częściach programu, co może poprawić ogólną wydajność. Współbieżność można zaimplementować za pomocą technik, takich jak wielowątkowość, w której wiele wątków jest uruchamianych współbieżnie w ramach jednego procesu. Możesz również użyć programowania asynchronicznego, w którym zadania są wyzwalane współbieżnie.

  • Programowanie asynchroniczne: Programowanie asynchroniczne to podejście do wyzwalania zadań bez blokowania głównego wątku. Programowanie asynchroniczne umożliwia programowi wyzwalanie zadań podczas oczekiwania na zakończenie długotrwałych operacji. Dzięki programowi asynchronicznemu program może zainicjować wiele zadań i poczekać na ich asynchronicznie ukończenie. Program nie musi czekać na zakończenie każdego zadania przed przejściem do następnego.

    Istnieje wiele asynchronicznych technik programowania i wzorców, w zależności od języka programowania i platformy. Jednym z typowych podejść jest użycie asynchronicznych słów kluczowych i konstrukcji, takich jak i await, w językach takich jak async C#. Za pomocą tych słów kluczowych można zdefiniować metody asynchroniczne. W przypadku ruchu HTTP rozważ użycie wzorca Request-Reply asynchronicznego.

    Wiele struktur i bibliotek zapewnia wbudowaną obsługę programowania asynchronicznego. Na przykład na platformie .NET można zaimplementować operacje asynchroniczne przy użyciu wzorców, takich jak wzorzec asynchroniczny oparty na zadaniach i wzorzec asynchroniczny oparty na zdarzeniach. Konkretna implementacja programowania asynchronicznego różni się w zależności od języka programowania, platformy i wymagań aplikacji.

  • Kolejki: kolejka jest buforem magazynu znajdującym się między składnikiem żądającym (producentem) a składnikiem przetwarzania (konsumentem) obciążenia. Może istnieć wiele odbiorców dla jednej kolejki. W miarę zwiększania się zadań należy skalować odbiorców, aby zaspokoić zapotrzebowanie. Producent umieszcza zadania w kolejce. Kolejka przechowuje zadania, dopóki użytkownik nie będzie miał pojemności. Kolejka jest często najlepszym sposobem przekazania pracy do usługi przetwarzania, która doświadcza szczytowego zapotrzebowania. Aby uzyskać więcej informacji, zobacz Wzorzec bilansowania obciążenia opartego na kolejce oraz Kolejki magazynu i Kolejki usługi Service Bus.

Użycie buforowania połączeń

Buforowanie połączeń to praktyka ponownego korzystania z ustanowionych Połączenia z bazą danych zamiast tworzenia nowego połączenia dla każdego żądania. Nawiązanie połączenia z bazą danych może być kosztowne. Musisz utworzyć uwierzytelnione połączenie sieciowe z zdalnym serwerem bazy danych. Połączenia z bazą danych są szczególnie kosztowne w przypadku aplikacji, które często otwierają nowe połączenia. Buforowanie połączeń ponownie używa istniejących połączeń i eliminuje koszty otwierania nowego połączenia dla każdego żądania. Buforowanie połączeń zmniejsza opóźnienie połączenia i umożliwia wysoką przepływność bazy danych (transakcje na sekundę) na serwerze. Należy wybrać rozmiar puli, który może obsługiwać więcej połączeń niż obecnie. Celem jest szybkie obsługiwanie nowych żądań przychodzących przez pulę połączeń.

Omówienie limitów puli połączeń. Niektóre usługi ograniczają liczbę połączeń sieciowych. Po przekroczeniu tego limitu połączenia mogą spowolnić lub zakończyć działanie. Możesz użyć puli połączeń, aby ustanowić stały zestaw połączeń w czasie uruchamiania, a następnie zachować te połączenia. W wielu przypadkach domyślny rozmiar puli może składać się tylko z kilku połączeń, które działają szybko w podstawowych scenariuszach testowych. Aplikacja może wyczerpać domyślny rozmiar puli w skali i utworzyć wąskie gardło. Należy ustanowić rozmiar puli, który mapuje na liczbę współbieżnych transakcji obsługiwanych w każdym wystąpieniu aplikacji.

Przetestuj pulę połączeń. Każda platforma baz danych i aplikacji ma nieco inne wymagania dotyczące konfigurowania i używania puli. Przetestuj pulę połączeń, aby upewnić się, że działa wydajnie pod obciążeniem.

Ryzyko: buforowanie połączeń może tworzyć fragmentację puli i obniżyć wydajność.

Optymalizowanie zadań w tle

Wiele aplikacji wymaga zadań w tle, które są uruchamiane niezależnie od interfejsu użytkownika. Aplikacja może uruchomić zadanie i kontynuować przetwarzanie interakcyjnych żądań od użytkowników. Przykłady zadań w tle obejmują zadania wsadowe, zadania intensywnie korzystające z procesora i długotrwałe procesy, takie jak przepływy pracy. Zadania w tle nie powinny blokować aplikacji ani powodować niespójności z powodu opóźnionej operacji, gdy system jest pod obciążeniem. Aby zwiększyć wydajność, można skalować wystąpienia obliczeniowe hostujące zadania w tle. Aby uzyskać więcej informacji, zobacz Zadania w tlei Zagadnienia dotyczące skalowania i wydajności.

Optymalizowanie wydajności infrastruktury

Optymalizacja wydajności infrastruktury oznacza zwiększenie i dostosowanie elementów infrastruktury w celu zapewnienia szczytowej operacji i najlepszego wykorzystania zasobów dla obciążenia. Dzięki dostrajaniu infrastruktury można zminimalizować straty, zmniejszyć opóźnienia i osiągnąć więcej dzięki dostępnym zasobom. Dzięki temu obciążenia działają niezawodnie i szybko, co prowadzi do poprawy środowiska użytkownika i oszczędności kosztów. Aby zoptymalizować wydajność infrastruktury, rozważ następujące strategie:

Dodaj limity użycia. Limity użycia można zaimplementować w niektórych składnikach obciążenia. Aby na przykład usunąć niestabilne zasobniki, można zdefiniować limity procesora i pamięci zasobnika w usłudze Azure Kubernetes Service (AKS). Aby zoptymalizować wydajność, można zdefiniować limity pamięci na maszynach wirtualnych Java.

Usprawnij infrastrukturę. Uprość obciążenie, aby zmniejszyć potencjał interakcji, zależności i zgodności. W przypadku uproszczenia obciążenia optymalizujesz wykorzystanie zasobów pamięci, mocy obliczeniowej i magazynu.

Zmniejsz obciążenie. Aby zmniejszyć obciążenie obciążenia, należy zminimalizować zapotrzebowanie na aplikację i umożliwić zasobom wykonywanie podstawowych zadań. Na przykład powszechną praktyką jest unikanie uruchamiania rozwiązań zabezpieczeń w kodzie lub w poszczególnych wystąpieniach obliczeniowych. Zamiast tego serwery internetowe powinny obsługiwać żądania HTTP. Zapory aplikacji internetowej i zasoby bramy mogą obsługiwać kontrole zabezpieczeń. Poniższe strategie pomagają zmniejszyć obciążenie obciążenia obciążenia:

  • Spójność ostateczna: przyjęcie modelu spójności ostatecznej w celu zwiększenia wydajności dzięki umożliwieniu nieco datowania danych. Spójność ostateczna zmniejsza natychmiastowe zapotrzebowanie na cykle procesora CPU i przepustowość sieci na potrzeby stałych aktualizacji danych.

  • Delegowanie zadań: delegowanie zadań serwera do klientów lub pośredników, takich jak indeksy wyszukiwania i pamięci podręczne. Deleguj zadania, takie jak sortowanie danych, filtrowanie danych lub widoki renderowania. Podczas odciążania tych zadań zmniejszasz obciążenie serwerów i zwiększasz wydajność.

Zoptymalizuj sieć. Aby zoptymalizować sieć obciążeń pod kątem wydajności, skonfiguruj i dostosuj infrastrukturę sieciową. Upewnij się, że obciążenie może działać na najwyższym poziomie wydajności.

  • Protokoły sieciowe: uaktualnij do nowoczesnych protokołów, takich jak HTTP/2, co umożliwia wysyłanie wielu żądań za pośrednictwem jednego połączenia. Nowoczesne protokoły zmniejszają obciążenie związane z nawiązywaniem nowych połączeń.

    Kompromis: Nowoczesne protokoły mogą wykluczać starszych klientów.

  • Czattiness sieci: żądania sieciowe wsadowe w celu zmniejszenia liczby żądań. Zamiast wykonywać wiele małych żądań, połącz je w większe żądania, aby zmniejszyć obciążenie sieci.

  • Zapytania bazy danych: upewnij się, że zapytania bazy danych pobierają tylko niezbędne informacje. Unikaj pobierania dużych ilości niepotrzebnych danych, co może prowadzić do zwiększenia ruchu sieciowego i spowolnienia wydajności.

  • Dane statyczne: użyj sieci dostarczania zawartości do pamięci podręcznej często używanej zawartości statycznej, która jest blisko użytkowników. W przypadku buforowania danych nie trzeba podróżować na długich odległościach. Buforowanie poprawia czas odpowiedzi i zmniejsza ruch sieciowy.

  • Zbieranie dzienników: zbieranie i zachowywanie tylko danych dziennika, które są niezbędne do obsługi wymagań. Skonfiguruj reguły zbierania danych i zaimplementuj zagadnienia dotyczące projektowania, aby zoptymalizować koszty usługi Log Analytics.

  • Kompresja danych: kompresuj i pakuj zawartość HTTP i dane plików , aby umożliwić szybką transmisję między klientami i serwerami. Kompresja zmniejsza dane zwracane przez stronę lub interfejs API i wysyła je z powrotem do przeglądarki lub aplikacji klienckiej. Kompresja optymalizuje ruch sieciowy, który może przyspieszyć komunikację aplikacji.

    Kompromis: Kompresja dodaje przetwarzanie po stronie serwera i po stronie klienta. Aplikacja musi kompresować, wysyłać i dekompresować dane. Komunikacja multiemisji lub komunikacja z wieloma odbiorcami może tworzyć obciążenie dekompresyjne. Należy przetestować i zmierzyć odmiany wydajności przed wdrożeniem kompresji danych i po jej zaimplementowaniu, aby ustalić, czy jest to dobre rozwiązanie dla obciążenia. Aby uzyskać więcej informacji, zobacz Kompresja odpowiedzi w ASP.NET Core.

Ułatwienia platformy Azure

Kod instrumentacji: usługa Azure Monitor Application Insights obsługuje automatyczne instrumentację (autoinstrumentację) i instrumentację ręczną kodu aplikacji. Autoinstrumentacja umożliwia zbieranie danych telemetrycznych bez dotykania kodu aplikacji. Instrumentacja ręczna wymaga zmian kodu w celu zaimplementowania interfejsu API usługi Application Insights lub OpenTelemetry. Możesz użyć profilera usługi Application Insights , aby ułatwić optymalizację ścieżek gorących.

Optymalizacja logiki kodu: platforma Azure oferuje zestawy SDK i biblioteki dla różnych języków programowania w celu interakcji z usługami platformy Azure. Użyj zestawów SDK, aby uprościć interakcje między aplikacjami i zasobami platformy Azure. Zestawy SDK zapewniają optymalną interakcję z usługami platformy Azure, co zmniejsza opóźnienie i zwiększa wydajność.

Optymalizacja zarządzania pamięcią: użyj funkcji wykrywania inteligentnego usługi Application Insights , aby analizować zużycie pamięci i pomagać w identyfikowaniu wycieków pamięci i rozwiązywaniu ich problemów.

Azure App Service ma funkcję zbierania i analizy zrzutu pamięci profilera i pamięci. Funkcja automatycznego skalowania App Service może automatycznie pobrać zrzuty pamięci i ślady profilów aplikacji .NET i Java.

Korzystanie z współbieżności i równoległości: różne usługi platformy Azure zapewniają unikatową obsługę współbieżności, takiej jak Azure Cosmos DB, Azure Functions i Blob Storage. W przypadku równoległości usługa AKS obsługuje wdrażanie konteneryzowanych aplikacji, co poprawia przetwarzanie równoległe.

Azure Batch to oparta na chmurze usługa planowania zadań, której można użyć do włączania przetwarzania równoległego i obliczeń o wysokiej wydajności bez konieczności konfigurowania infrastruktury. Aby uzyskać więcej informacji, zobacz Zadania w tle.

Optymalizacja wydajności infrastruktury: zaimplementujszablony usługi Azure Resource Manager w celu definiowania i wdrażania infrastruktury przy użyciu kodu. Użyj tych szablonów, aby zaimplementować wydajne, powtarzalne i spójne wdrożenia zasobów. Azure Policy zapewnia możliwości zapewniania ładu, aby zapewnić, że wdrożenia zasobów są zgodne z najlepszymi rozwiązaniami i standardami organizacji.

W przypadku programowania asynchronicznego użyj skalowalnych usług kolejkowania, takich jak Azure Queue Storage i Azure Service Bus, aby ułatwić programowanie asynchroniczne. Zadania można kolejkować i przetwarzać niezależnie. Aby obsługiwać operacje asynchroniczne, Azure Marketplace oferuje kolejki i narzędzia innych firm, które można zintegrować z usługami platformy Azure.

Lista kontrolna dotycząca wydajności

Zapoznaj się z pełnym zestawem zaleceń.