Rozdiel nebol v stránke. Spôsoboval ho jeden nenápadný znak v adrese, s ktorou prichádzali niektorí návštevníci, a predvolené nastavenie cache, ktoré z neho vytvorilo slučku.
Čo sa stalo?
Uprostred spustenia produktu prišlo hlásenie: nová stránka časti návštevníkov zobrazovala ERR_TOO_MANY_REDIRECTS. Situácia bola vážna a problém sme navyše nevedeli zopakovať. Nám sa stránka načítala zakaždým.
Obrátili sme sa preto priamo na origin server a obišli všetky vrstvy pred ním:
curl -I --resolve client.com:443:<origin-ip> https://client.com/en/page/
HTTP/2 200
Čistá odpoveď 200. Vyskúšali sme verziu s www, bez koncového lomítka, cez obyčajné HTTP aj množstvo prehliadačov a zariadení. Vždy 200. Súhlasil aj prístupový log servera: od zverejnenia stránky vracal pre túto URL iba odpovede 200. Nevydal jediné presmerovanie.
Stránka sa teda niektorým návštevníkom zacyklila, hoci server ju nikdy nepresmeroval. Odkiaľ presmerovanie prichádzalo?
Čo sme našli
Odpoveď bola o vrstvu vyššie, v CDN Cloudflare. Príčinou bolo jedno nadbytočné lomítko.
Malá časť požiadaviek prichádzala s dvojitým lomítkom za jazykovým prefixom:
/en/page/ <- what everyone types
/en//page/ <- what some links and tools were generating
Cloudflare štandardne pred hľadaním v cache uprace dvojité lomítka. Obe adresy preto smerujú na rovnakú položku cache. Origin serveru však odošle pôvodnú neupravenú adresu. Riadi sa to dvoma nastaveniami: Normalize incoming URLs je predvolene zapnuté, Normalize URLs to origin vypnuté.
WordPress uvidí /en//page/, určí správnu adresu /en/page/ a odpovie presmerovaním. Samo osebe je to neškodné. Problém bol v rozdiele medzi odpoveďou presmerovania a skutočnej stránky:
# the doubled-slash request - a REDIRECT, and cacheable for an hour
GET /en//page/
HTTP/2 301
location: https://client.com/en/page/
cache-control: max-age=3600
cf-edge-cache: cache
# the real page - a 200 that is never cached
GET /en/page/
HTTP/2 200
cache-control: no-store, no-cache, must-revalidate
Cloudflare uložil odpoveď 301 do cache. Keďže pre kľúč cache už odstránil dvojité lomítko, presmerovanie uložil pod čistú adresu. Potom nasledovalo:
- Návštevník požiada o bežnú adresu /en/page/.
- Cloudflare vráti uložené presmerovanie 301 na /en/page/.
- Prehliadač ho nasleduje späť na rovnaké uložené presmerovanie na tej istej adrese.
- Vznikne slučka.
Preto sa chyba javila ako náhodná. Cache Cloudflare je rozdelená podľa regiónu a zariadenia, takže zasiahla iba návštevníkov smerovaných cez „otrávené“ miesto. Každá položka po hodine vypršala a pri ďalšej požiadavke s dvojitým lomítkom sa znova pokazila. Problém sa sám opravoval aj vracal — presne také správanie sa opakovaným obnovovaním stránky hľadá najťažšie.
Navyše nešlo iba o jednu stránku. V prístupových logoch sme našli 540 požiadaviek s dvojitým lomítkom na 199 rôznych URL vrátane jazykových homepage. Každá sa mohla nenápadne zacykliť.
Riešenie
Cloudflare nemožno prikázať, aby prestal zlučovať lomítka v kľúči cache. Môžeme však zapnúť úpravu adresy aj cestou k serveru:
Rules → Settings → Normalization → Normalize URLs to origin: On
Server potom dostane /en/page/ aj vtedy, keď návštevník poslal /en//page/. Vráti bežnú odpoveď 200, nevytvorí kanonické presmerovanie a cache už nemá čím kontaminovať. Overili sme to označenou požiadavkou s dvojitým lomítkom a kontrolou toho, čo server skutočne prijal:
sent to Cloudflare: /en//page/?check=1
arrived at server: GET /en/page/?check=1 -> 200
Jedno lomítko, odpoveď 200, žiadne presmerovanie. Potom sme vyčistili štyri už kontaminované URL pri spustení, jednu pre každý jazyk, a overili návrat skutočnej stránky:
| Jazyk | Pred opravou | Po oprave |
|---|---|---|
| EN | Slučka presmerovaní | 200 (cache HIT) |
| ES | Slučka presmerovaní | 200 (cache HIT) |
| IT | Slučka presmerovaní | 200 (cache HIT) |
| BR | Slučka presmerovaní | 200 (cache HIT) |
Dve veci nás stáli čas. Takto sa im vyhnete:
- Najprv opravte príčinu, až potom čistite cache. Vyčistenie kontaminovanej URL pomôže približne na štyri minúty, kým ďalšia požiadavka s dvojitým lomítkom slučku neobnoví. Najprv zapnite normalizáciu, potom vymažte cache. Inak uvidíte, ako oprava chvíľu „funguje“ a vzápätí opäť zlyhá.
- Cache CDN netestujte tvrdým obnovením stránky. Vynútené obnovenie, cache: "reload" alebo hlavička Cache-Control: no-cache prikáže Cloudflare obísť vlastnú cache a načítať čerstvú odpoveď zo servera. V skutočnosti tak meriate origin, vidíte funkčný web a môžete nesprávne uzavrieť, že problém neexistuje. Obsah cache zistíte normálnou požiadavkou:
// "opaqueredirect" here means a redirect really is sitting in the cache
fetch(url, { redirect: "manual" })
Toto nás nechalo skúmať nesprávnu vrstvu dlhšie, než by sme chceli.
Prečo si občasné problémy zaslúžia pozornosť
Opakované obnovovanie by túto chybu nenašlo. Bola medzi návštevníkom a serverom, vo vrstve, ktorá pri priamom dopyte zakaždým odpovedala správne. „Mne to funguje“ neznamenalo nesprávne hlásenie. Bola to najdôležitejšia stopa, kde problém hľadať.
Museli sme preskúmať prehliadač, CDN a server samostatne a zistiť, čo skutočne robí každá vrstva. Keď sme porovnali odpoveď servera — čistú 200 — s presmerovaním, ktoré dostávali návštevníci, príčina sa ukázala.
Odhaľujte problémy včas a opravujte ich rýchlo. Najmä tie, ktoré vidí iba časť návštevníkov — tie zostávajú nenahlásené najdlhšie.
Riešite problém, ktorý zažíva iba časť návštevníkov? Ozvite sa nám.








