Броячът на прегледи, който превърна каталога ни в грешка 502
Доставка
Страницата, в която са изброени всички комплекти, които продаваме, отговаряше на всеки посетител с грешка 502 Bad Gateway за около 41 часа след пускането. Отделните страници на всеки комплект работеха, началната страница работеше, плащането работеше. Счупената част бяха няколко реда, които броиха прегледите на страниците.
Бъгът
Сървърът на магазина ни брои посещенията на страниците на комплектите. За да определи за кой комплект е заявката, той вземаше втората част от пътя:
self._count_view(path.strip("/").split("/")[1] if path.count("/") >= 2 else "")
За /kits/studio/ това е studio. За самия каталог, /kits/, пътят има две наклонени черти, затова защитният механизъм го пусна, но след премахването на наклонените черти остава само една част и [1] предизвика IndexError. Обработчикът е стандартният http.server на Python: изключение в do_GET затваря връзката без отговор, а Cloudflare показваше на посетителя 502.
Поправката е една малка функция, която връща празен низ, когато частта липсва. Броят на прегледите имаше нужда само от името на комплекта; той никога не е трябвало да може да разваля страницата, която брои.
Защо никоя от проверките ни не го забеляза
- Наблюдението за наличност отваряше само началните страници. Началната страница беше наред.
- Стъпката за пускане проверяваше всеки комплект, който изпращаше: неговата страница, пренасочването за плащане, платения път от край до край. Тя никога не отваряше списъка с всички комплекти.
- Аналитиката не можеше да го покаже. Кодът, който би броил посетителите на каталога, беше кодът, който се счупи. Сървърният лог имаше отговора през цялото време: 17 tracebacks в тези 41 часа, всеки от тях заявка, от човек или паяк, която получи грешка вместо страницата.
Какво се промени
- Всяка страница, отвън, на всеки час. Малка задача чете sitemap-а и отваря всяка страница на английски и, последователно, една от другите 42 езици, през Cloudflare като посетител. Два последователни неуспешни запуска изпращат имейл; възстановяването изпраща друг.
- Стъпката за пускане отваря всяка страница на английски след като преизгради сайта, и отказва да завърши, ако една не отговори с 200.
- Индексните страници се броят като страници. Страниците, които изброяват други страници, са тези, до които посетителят стига първи, и те бяха тези, които никой не тества.
Изводът
Странични задачи в обработката на заявка, като броене, записване в журнал или проследяване, не трябва никога да могат да провалят заявката, а проверка на страниците, която обхваща само току-що променените, пропуска тези, които сочат към тях. Watchdog-ът в Night Watch приема всеки списък от страници, всяка с текста, който трябва да съдържа, а не само началните страници.