Żądania HTTP mogą być blokowane, nawet jeśli procesor, pamięć RAM i przepustowość wydają się otwarte, ponieważ niewidoczne limity, filtry i kolejki działają w całym łańcuchu. Wyjaśniam, gdzie Granice jak działają i jakie ustawienia ustawić, aby żądania znów działały płynnie.
Punkty centralne
Zanim przejdę do szczegółów, podsumuję najważniejsze przyczyny i wymienię, na co zwracam uwagę w pierwszej kolejności. Punkty te obejmują typowe wąskie gardła, które prowadzą do zatorów pomimo wolnych zasobów. Celowo utrzymałem listę w zwartej formie, aby można było natychmiast sprawdzić punkty początkowe. Kluczową kwestią jest to, że każda warstwa ma swoje własne zasady, które obowiązują niezależnie od procesora i pamięci RAM. Jeśli znasz te zasady, możesz szybko rozwiązać wiele „niewytłumaczalnych“ czasów oczekiwania.
- Limity pracownikówZbyt mała liczba procesów/wątków blokuje nowe połączenia pomimo wolnego CPU.
- Warstwa zabezpieczeńWAF/filtry internetowe blokują wzorce, metody lub klientów, często bez dużego obciążenia.
- WspółbieżnośćPHP-FPM, baza danych i serwery proxy ograniczają jednoczesne sesje.
- Keep-Alive/TimeoutsDługie połączenia blokują sloty, żądania trafiają do kolejek.
- Filtr klientaRozszerzenia przeglądarki zatrzymują żądania zanim dotrą one do serwera.
Te kluczowe punkty często wystarczają do sprawdzenia zachowania w ukierunkowany sposób. W dalszej części pokażę, w jaki sposób wyprowadzam z tego konkretne środki i Blokady czysto.
Dlaczego żądania HTTP blokują się pomimo wolnych zasobów
Żądanie przechodzi przez kilka warstw: Klienta, sieć, filtr, serwer WWW, środowisko uruchomieniowe i bazę danych. Każda warstwa ma swój własny Ograniczenia które działają niezależnie od procesora, pamięci RAM lub przepustowości. Jeśli gniazda robocze są zajęte lub reguły są aktywne, żądanie czeka w kolejce lub jest natychmiast anulowane. Ten czas oczekiwania często nie pojawia się w ogóle na klasycznych diagramach zasobów. To właśnie prowadzi do błędnego przekonania, że serwer jest „pusty“, mimo że żądania nie są odbierane.
Warstwa bezpieczeństwa: WAF, filtry i reguły dostawcy
Wiele blokad występuje jeszcze przed uruchomieniem aplikacji. Zapory sieciowe, IDS/IPS i filtry po stronie dostawcy rozpoznają wzorce i spowalniają je lub blokują [1][5][9]. Podejrzane parametry, stare protokoły lub kombinacje metod wystarczą, aby spowodować blokadę aplikacji. Blokada do zapłonu. Z punktu widzenia operatora wygląda to na błąd serwera, ale decyzja jest podejmowana „na wyższym szczeblu“. Dlatego sprawdzam dzienniki WAF i odnotowuję identyfikator żądania, adres IP, czas i kod stanu. Dzięki tym danym regułę można zidentyfikować i dostosować w ukierunkowany sposób bez narażania bezpieczeństwa.
Po stronie klienta: rozszerzenia przeglądarki i lokalne blokery
Nie każde żądanie dociera do serwera. Adblockery, menedżery haseł i blokery skryptów już zatrzymują adresy URL w przeglądarce; DevTools pokazuje wtedy „Żądania do serwera zostały zablokowane przez rozszerzenie“ [3][7]. Testuję w prywatnym oknie, dezaktywuję rozszerzenia i sprawdzam czy Żądanie został w ogóle wysłany. Pomaga to również kontrolować priorytety we front-endzie, na przykład z czystym Priorytetyzacja żądań dla krytycznych zasobów. Zapobiega to opóźnianiu ważnych tras przez niekrytyczne połączenia z osobami trzecimi.
Zrozumienie metody i routingu: 405, 403, 429
Komunikat 405 „Metoda niedozwolona“ wyraźnie wskazuje, że serwer rozpoznaje zasób, ale nie zezwala na zastosowaną metodę [5]. Podobnie, 403 wskazuje filtry lub uprawnienia, a 429 aktywne ograniczenie szybkości. W dziennikach mogę szybko rozpoznać, czy globalna reguła zezwala na metody takie jak PUT lub DELETE lub czy punkt końcowy nigdy nie został wdrożony. Następnie dostosowuję routing, kontroler lub regułę WAF. W ten sposób rzekome „blokowanie“ zamienia się w czystą korektę metod i ścieżek.
Architektura serwera WWW i limity pracowników
Apache, NGINX, LiteSpeed i OpenLiteSpeed obsługują połączenia w różny sposób [4]. Decydującymi czynnikami są liczba procesów roboczych, wątków i sposób, w jaki gniazda keep-alive zajmują sloty. Jeśli wszystkie procesy robocze są zajęte przez długie połączenia, nowe żądania są przenoszone do Kolejka, mimo że procesor i pamięć RAM wydają się wolne. Dlatego analizuję stany połączeń i dostosowuję pracowników, zaległości i czasy oczekiwania. Podstawowa wiedza na temat kolejek pomaga, na przykład w temacie Kolejkowanie serwerów i opóźnienia.
| warstwa | Odpowiedni limit | Typowy objaw | Uwaga diagnostyczna |
|---|---|---|---|
| Serwer sieciowy | Liczba pracowników/wątków | Kolejki, 503 pod obciążeniem | Moduły stanu, sprawdzanie stanu połączenia |
| PHP-FPM/FastCGI | max_children / pm | Zawieszające się żądania, długi czas do pierwszego bajtu | Dzienniki FPM, powolny dziennik, liczba procesów |
| Baza danych | max_connections | Błąd „Zbyt wiele połączeń“ | SHOW PROCESSLIST, szczyty połączeń |
| WAF/Filtr | Podpisy, metody | 403/405, niedziałające formularze postów | Dzienniki WAF, identyfikatory trafień reguł |
| Load Balancer | Per-Backend-Conn-Limit | Niespójne czasy reakcji | LB-Stats, Backend-Health |
Współbieżność w PHP-FPM, baza danych i proxy
Przetwarzanie współbieżne często pęka jako pierwsze w środowisku uruchomieniowym. Jeśli wszyscy pracownicy PHP FPM są zajęci, nie ma dostępnego miejsca na nowe skrypty; żądania czekają, nawet jeśli CPU prawie nie działa. Sytuacja wygląda podobnie w przypadku baz danych z max_connections lub serwerów proxy z limitami połączeń na backend. Przed zwiększeniem limitów najpierw optymalizuję czas trwania poszczególnych żądań. W ten sposób skracam czas dokumentu na slot i zmniejszam prawdopodobieństwo wzrostu kolejek.
Powolne backendy i blokowanie sesji PHP
Długie zapytania do bazy danych, zewnętrzne interfejsy API lub wejścia/wyjścia plików znacznie wydłużają czas pracy pracowników. Blokowanie sesji może również spowolnić całe łańcuchy, takie jak logowanie do WordPressa lub koszyki zakupowe. Sprawdzam, czy równoległe żądania do tego samego identyfikatora sesji działają kolejno zamiast jednocześnie. Jeśli tak, polegam na ukierunkowanym odblokowywaniu, ograniczam krytyczne dostępy do zapisu i postępuję zgodnie z wypróbowanymi i przetestowanymi instrukcjami na stronie Blokowanie sesji PHP. Pozwala mi to na szybsze zwolnienie slotów i zmniejszenie Czas oczekiwania zauważalne.
Limity czasu, keep-alive i strategie połączeń
Zbyt długie czasy keep-alive wiążą zasoby, podczas gdy zbyt krótkie generują handshake i opóźnienia. Wybieram wartości, które pasują do profilu ruchu i ustawiam limity limitów czasu nagłówka, treści i backendu. Ważne jest, aby ustawić limity czasu nie tylko na poziomie Serwer sieciowy ale ustandaryzowane w całym łańcuchu: proxy, aplikacja, baza danych. Ponadto zapobiegam bezczynnemu blokowaniu poprzez dokładniejsze ustawienia HTTP/2/HTTP/3 i priorytetyzację. Utrzymuje to dostępność slotów bez konieczności ciągłego ponownego łączenia się klientów.
Modele hostingu: współdzielony, VPS, dedykowany
Hosting współdzielony ustawia wczesne filtry i twarde limity, aby platforma pozostała sprawiedliwa [1]. W przypadku VPS, dostawcy izolują CPU i RAM, ale utrzymują limity dla I/O, sieci lub bezpieczeństwa; różnice w wydajności i monitorowaniu są wyraźne [10]. Na serwerach dedykowanych ponoszę pełną odpowiedzialność za konfigurację serwera WWW, bazy danych i WAF. Porównania pokazują, że nowoczesne stosy z HTTP/3, NVMe i ochroną DDoS oferują wyraźne korzyści [2][6][11][8]. Ci, którzy potrzebują wysokiej równoległości, korzystają z jasno udokumentowanych Granice i wsparcie, które pomaga w jednostkach reguł.
Analiza systematyczna: krok po kroku
Zaczynam od źródła: czy DevTools naprawdę wysyła żądanie, czy też rozszerzenie [3][7] je blokuje? Następnie patrzę na kody statusu: 403/405/429/503 dają silne wskazówki dotyczące filtrów, metod lub przepustowości [5]. Jednocześnie sprawdzam logi z serwera WWW, aplikacji i WAF, aby znaleźć wzorce i powtarzające się sygnatury [1][9]. Następnie sprawdzam liczbę pracowników, parametry FPM, połączenia keep-alive i bazy danych oraz zwiększam limity na podstawie testów z punktami pomiarowymi przed i po. Na koniec symuluję obciążenie, obserwuję wąskie gardła w czasie rzeczywistym i sprawdzam, czy Kolejki skurcz.
Najlepsze praktyki przeciwko blokadom
Formułuję cele współbieżności dla każdej warstwy i ustawiam limity tak, aby szczyty obciążenia były amortyzowane. Serwer WWW musi pasować do wzorca ruchu; benchmarki pomagają w wyborze i konfiguracji [4]. Najpierw optymalizuję backend logicznie: szybsze zapytania, krótsze transakcje, mniej sekcji seryjnych. Utrzymuję wystarczająco surowe zasady bezpieczeństwa przed atakami, ale z wyjątkami dla legalnych ataków Próbka. Monitorowanie nie kończy się na CPU/RAM: przyglądam się połączeniom, kolejkom, czasom odpowiedzi i kodom błędów, aby wąskie gardła pozostały widoczne [6][11].
Uwagi praktyczne: hosting blokujący żądania
W środowiskach współdzielonych blokady często kończą się przed rzeczywistą przestrzenią sieciową; obsługa potrzebuje wtedy konkretnych danych żądania, aby dostosować reguły [1]. Na VPS skaluję stopniowo: więcej pracowników, bardziej odpowiednie wartości keep-alive i dokładniejsze monitorowanie bazy danych [10]. Na własnym sprzęcie decyduję o równoważeniu obciążenia, regułach WAF i limitach na backend. Projekty z wysoce równoległym dostępem korzystają z czystej konfiguracji HTTP/2/HTTP/3 i jasnych rezerw dla Wskazówki. Jeśli spodziewasz się wzrostu, zaplanuj przejście na mocniejsze taryfy na wczesnym etapie i zaoszczędź wiele wysiłku związanego z dostrajaniem później [2][6][10][11].
Limity sieci i jądra: zaległości, porty i deskryptory
Oprócz serwera WWW i aplikacji, jądro ogranicza liczbę połączeń, które mogą być nawiązywane i zarządzane w tym samym czasie. Najpierw sprawdzam Lista zaległościNawet jeśli serwer WWW ma wielu pracowników, kolejka akceptacji może być krótka. Interakcja między aplikacją (listen backlog), jądrem (somaxconn) i SYN backlog (tcp_max_syn_backlog) określa, czy połączenia pozostają w kolejce, czy są odrzucane. Objawy to rosnące czasy połączeń i retransmisji - przy niskim wykorzystaniu procesora. Porównuję wartości i mierzę rzeczywiste wykorzystanie kolejek, aby uniknąć spadków.
Kolejnym klasykiem jest tabela połączeń dla konfiguracji NAT/firewall. Jeśli jest pełny, połączenia znikają „bez śladu“; aplikacja nigdy nie widzi żądania. Rozpoznaję to po komunikatach w dzienniku systemowym i nagłych limitach czasu podczas szczytowego obciążenia. Środki zaradcze to: odpowiedni rozmiar tabeli, realistyczne czasy bezczynności dla protokołów, mniej niepotrzebnych ścieżek NAT i wydajne keep-alives, które rozsądnie wykorzystują połączenia.
Sprawdzam również liczbę otwartych Deskryptory plików (ulimit -n). Jeśli wiele jednoczesnych gniazd i plików osiągnie restrykcyjne limity, Accept nie powiedzie się („zbyt wiele otwartych plików“), a nowe żądania piętrzą się przed nim. Rozwiązanie jest zwykle trywialne: ustaw limity nofile dla serwera WWW, serwera proxy i bazy danych na zdrowym poziomie - stale, a nie tylko interaktywnie.
W silnie równoległych konfiguracjach obserwuję Efemeryczny zakres portów oraz TIME_WAIT-stany. Zwłaszcza za bramkami NAT dostępne porty źródłowe są wyczerpywane, gdy masowo nawiązywane są krótkie połączenia. Dlatego polegam na ponownym wykorzystaniu połączeń (keep-alive, HTTP/2/3), redukuję niepotrzebne krótkotrwałe połączenia i starannie dostrajam obsługę TIME_WAIT bez ryzykowania stabilności. Rezultat: mniejsze wyczerpanie portów i bardziej stabilne czasy połączeń pod obciążeniem.
Na karcie sieciowej sprawdzam długości kolejek, ustawienia odciążania i dystrybucję IRQ. Nierównomiernie rozłożone przerwania lub przeciążone kolejki generują szczyty opóźnień, które nie są zauważalne w dziennikach aplikacji. Przy zrównoważonym balansie IRQ i rozsądnych ustawieniach Qdisc (słowo kluczowe Bufferbloat) Zmniejszam opóźnienia bez ograniczania przepustowości.
HTTP/2 i HTTP/3: prawidłowe korzystanie z multipleksowania
Multipleksowanie rozwiązuje wiele problemów, ale wprowadza nowe ograniczenia: Maksymalna liczba strumieni, Okno kontroli przepływu i limit czasu bezczynności mają zastosowanie do każdego połączenia. Jeśli wartość dla jednoczesnych strumieni jest zbyt niska, nowe żądania „zawieszają się“, nawet jeśli połączenie TCP lub QUIC zostało nawiązane. Dlatego sprawdzam, ile krytycznych zasobów musi być ładowanych równolegle i ostrożnie dostosowuję limity strumieni. Jednocześnie zwracam uwagę na rozsądne Kontrola przepływu-aby duże odpowiedzi nie były dławione.
Multiplekser HTTP/2 przez TCP może cierpieć z powodu blokowania nagłówka linii w przypadku utraty pakietów; HTTP/3 na QUIC pozwala tego uniknąć, ale wymaga czystych ustawień TLS/ALPN i stabilnych reguł obsługi ścieżek. Testuję obie ścieżki i wybieram protokoły, które pasują do profilu ruchu. Ważne: Nie należy ślepo ufać priorytetyzacji - przeglądarki i serwery interpretują ją inaczej. Skupiam się na krytycznych trasach i sprawdzam, czy priorytety faktycznie działają, a sloty nie są zajmowane przez długo działające strumienie drugorzędne.
CORS, loty wstępne i limity nagłówka/nadwozia
Nie każdy błąd 4xx pochodzi z serwera. Przestępstwa CORS występują w przeglądarce i pojawiają się w konsoli, a nie w dzienniku dostępu. Sprawdzam, czy żądania preflight (OPTIONS) są poprawnie odbierane i czy WAF/proxy zezwalają na tę metodę. Jeśli brakuje nagłówków takich jak Access-Control-Allow-Methods/-Headers, przeglądarka „blokuje“ odpowiedź - bez żadnego obciążenia serwera.
Kolejne wąskie gardło: Rozmiary nagłówków i plików cookie. Przerośnięte pliki cookie, wiele nagłówków Vary lub duże linie referer prowadzą do błędów 431 lub cichych spadków z powodu limitów bufora. Ograniczam balast plików cookie, konsoliduję nagłówki i ustawiam rozmiary buforów konsekwentnie wzdłuż łańcucha. W przypadku przesyłania zwracam uwagę na limity treści, obsługę 100-continue i spójne Kodowanie zbiorcze-Wsparcie dla wszystkich serwerów proxy. Jeśli limity treści i wysyłania nie są zgodne, klienci czekają na zwolnienie, które nigdy nie nadchodzi - żądania wydają się „zawieszać“.
DNS i TLS: Uściski dłoni jako ukryte opóźnienie
Rozpoznawanie DNS i negocjacje TLS są częstymi martwymi punktami. Wiele łańcuchów CNAME, powolne resolvery lub niedopasowanie IPv6/IPv4 wydłużają czas startu bez użycia CPU. Ograniczam niepotrzebne skoki DNS, ustawiam rozsądne TTL i zapewniam szybkie ścieżki resolverów. Po stronie TLS sprawdzam łańcuchy certyfikatów, aktywowane zestawy szyfrów, zszywanie OCSP i wznawianie sesji. Czysty uścisk dłoni ALPN zapobiega obniżeniu do HTTP/1.1, co powoduje większe obciążenie slotów keep-alive. Rezultat: krótszy czas do pierwszego bajtu i bardziej stabilna równoległość, zwłaszcza w sieciach mobilnych.
CDN/Edge: Buforowanie, limity prędkości i reputacja IP
Pomiędzy klientem a źródłem, sieci CDN, odwrotne serwery proxy i systemy ochrony przed atakami DDoS decydują o Przepust i throttle. Sprawdzam, czy krytyczne trasy są poprawnie buforowane (stale-while-revalidate, stale-if-error) i czy ujemne pamięci podręczne przechowują błędy dłużej niż to konieczne. Limity szybkości, zarządzanie botami i reputacja IP mogą tłumić legalny ruch, zwłaszcza w przypadku współdzielonych sieci lub intensywnego dostępu do API. Segmentuję ruch (np. API vs. zasoby), definiuję klucze wyczyszczenia pamięci podręcznej i wyłączam reguły selektywnie dla zaufanych klientów. Odciąża to Origin i zapobiega wzrostowi kolejek CDN, podczas gdy serwer wygląda na „niewykorzystany“.
Kontenery i orkiestracja: cgroups, Ingress i conntrack
W pojemnikach stosować limity cgroup dla CPU, RAM, pids i plików. Zbyt niski limit CPU prowadzi do dławienia: procesy czekają na czas procesora, mimo że host jest wolny. Sprawdzam limity i upewniam się, że kapsuły ingress/proxy mają wystarczającą liczbę deskryptorów plików i buforów. W Kubernetes sprawdzam timeouty ingressu, sondy readiness/liveness i implementacje usług (IPVS), ponieważ wadliwe sondy lub timeouty generują zygzakowate opóźnienia i niepotrzebne restarty.
Często pomijanym wąskim gardłem jest Przepustowość NAT/ścieżki na węzeł. Wiele krótkotrwałych połączeń (np. wychodzących do zewnętrznych interfejsów API) wypełnia tabelę conntrack, a następnie żądania „znikają“ w sieci. Skaluję tabelę, ustawiam realistyczne limity czasu i łączę połączenia zewnętrzne, aby tworzyć mniej nowych połączeń. Planuję PodDisruptionBudgets, aktualizacje kroczące i skalowanie HPA w taki sposób, aby nie odejmować przepustowości od harmonogramu w godzinach szczytu - w przeciwnym razie tworzą się kolejki, mimo że aplikacja jest w pełni skalowalna. teoretycznie miałaby wystarczającą liczbę pracowników.
Obserwowalność: korelacja, śledzenie i znaczące metryki
Aby szybko znaleźć blokady, potrzebuję Korelacja ciągła. Przypisuję identyfikatory żądań (np. traceparent) do krawędzi, serwera WWW, aplikacji i bazy danych i zapisuję je w dziennikach. Dzięki temu mogę sprawdzić, czy żądanie nie powiodło się w WAF, czeka na serwerze WWW, utknęło w kolejce FPM lub jest zablokowane w bazie danych. Pracuję z Histogramy zamiast czystych wartości średnich i monitorować opóźnienia P95/P99, otwarte połączenia, kolejkę akceptacji, długość kolejki FPM, aktywne sesje DB i kody błędów backendu. Używam również kontroli syntetycznych, aby wyraźnie oddzielić efekty po stronie klienta od efektów po stronie serwera.
Dla anomalii używam Drilldown-Procedura: najpierw logi edge/WAF, następnie load balancer, następnie dostęp do serwera WWW/błąd, następnie logi aplikacji i FPM, a na końcu logi DB i systemowe. Ta ścieżka pokazuje mi dokładnie, gdzie tracony jest czas i na którym limicie zatrzymuje się żądanie. Dzięki ukierunkowanym metrykom na warstwę unikam przeczuć i drastycznie skracam czas do głównej przyczyny.
Podręcznik strojenia i lista kontrolna
W praktyce mam kompaktowy playbook, który dostosowuję do otoczenia:
- PowtarzalnośćOkreśl scenariusz (trasa, metoda, rozmiar, klient), znacznik czasu dziennika i identyfikatory.
- Sprawdzanie warstwa po warstwieBrowser/Extensions, CORS/Preflight, WAF-Hits, LB-Stats, Webserver-Status, FPM-Queue, DB-Active/Locks.
- Spraw, by kolejki były widoczneAccept/SYN backlog, FPM listen queue, proxy backlog, DB connection pool.
- Synchronizacja limitówWorker/threads, somaxconn, nofile, max_connections, limity strumieni dla H2/H3, limity body/header, timeouts.
- Skrócenie czasu zajętościPrzyspiesz zapytania, unikaj blokad sesji, zmniejsz liczbę operacji we/wy, kompresuj odpowiedzi i rozsądnie je buforuj.
- Harmonizacja strategiiCzas trwania Keep-Alive, parametryzacja HTTP/2/3, priorytetyzacja krytycznych tras.
- Dostosuj zabezpieczeniaUkierunkowane wykluczanie reguł WAF zamiast globalnego osłabiania; rejestrowanie z identyfikatorami trafień.
- SkalowanieZdefiniuj współbieżność na zmianę, przeprowadzaj testy obciążenia, mierz rezerwy, zwiększaj limity tylko po optymalizacji.
- FallbackiWyłącznik dla powolnych backendów, polityka ponawiania prób z jitterem, „stale-jeśli-błąd“ dla krytycznych zasobów.
Krótkie podsumowanie
Zablokowane żądania z wolnym procesorem i pamięcią RAM są zwykle spowodowane limitami, filtrami i strategiami połączeń - a nie brakiem wydajności. Najpierw sprawdzam, gdzie zatrzymuje się żądanie: przeglądarka, WAF, serwer WWW, środowisko wykonawcze lub baza danych. Następnie minimalizuję czasy zajętości na slot, usuwam niepotrzebne Zamki i ustawiam realistyczne limity czasu. Utrzymuję wysoki poziom bezpieczeństwa, dostosowuję reguły do fałszywych alarmów i zbieram dowody w dziennikach. Dzięki takiemu podejściu żądania HTTP pozostają niezawodnie dostępne - nawet gdy ruch rośnie i liczy się każda sekunda.


