Як правильно Досить wordpress - форум успішних вебмайстрів

Як правильно Досить wordpress

Відразу обмовлюся, текст нижче не порушує правил форуму і таке формулювання назви топіка створена лише для залучення уваги спільноти, яке до сих пір чомусь продовжує використовувати Wordpress без відповідних захистів, незважаючи на мої багаторазові попередження за останні 3-4 роки

Нижче описана небезпека експлуатації WP, до якої схильні 99,99% сайтів. Причому, їй може скористатися будь-який новачок. Що найцікавіше, це не діра, що не баг, не якась доп.настройка або плагін. це документована фіча ядра вордпресс!

Я з нею працював кілька років. маю на увазі, допрацьовував вордпресс так, щоб ця фіча перестала бути настільки вразливою, якою вона є в дистрибутиві за замовчуванням. Зараз вирішив поділитися досвідом з публікою, а вона допоможе "поширити" цю інформацію до власників сайтів

DoS (Denial Of Service) = "відмова в обслуговуванні". тобто це ряд заходів над сервером або сайтом, а в нашому випадку - над Вордпресс, метою яких є доставлення проблеми з працездатністю веб-ресурсу.

DDoS - те ж саме, тільки дії спрямовані не з одного джерела, а з безлічі. Саме D DoS окремо розглядати не будемо, тому що для захистів від розподілених атак потрібно:
1) зрозуміти алгоритм або характер DoS-а
2) відфільтрувати погані джерела запитів. Якщо ддос не такий сильний, то, можливо, допоможе цей топік.

До речі кажучи, поняття тестування навантаження і стрес-тестування мають спільне з DoS, а саме: їх мета - протестувати систему (в тому числі) на протистояння DoS- і DDos-атакам. Тому, можна сказати, нижче описаний спосіб стрес-тестування вашого сайту на Wordpress

Опис методу. Теорія.

Мій метод тестування (або доса, як вам зручніше) заснований на вбудованої можливості вордпресс сортувати об'єкти (пости, тайтли, теги - все що завгодно) в довільному порядку, тобто за допомогою random. Сама фіча описана на сайті вордпресс тут. Здавалося б, це зручно додавати до будь-якого URL вордпресс orderby = rand і вміст списку (наприклад, списку постів) видається кожен раз у випадковому порядку. Теж саме стосується і розробки плагінів, в класах вордпресс є схожі механізми отримання рандомізованого списку будь-яких об'єктів, що теж здається зручним на перший погляд і школярі з задоволенням це використовують в своїх плагінах, багато з яких знаходяться в топах на сайті wordpress.org

Але ж кожен програміст, який має досвід програмування (а не колупання пальцем в сраці), знає, що рандом - це іноді погано, а чим ближче розподіл ймовірності випадкової величини до нормального ( "ідеальний рандом"), тим ще гірше і складніше. Архітектори нашого "улюбленого" вордпресс, чомусь вирішили, що пости потрібно сортувати саме методом, близьким до ідеального, тобто використовуючи функцію rand (), яка присутня в мовах програмування або sql.

А тепер подумаємо, що таке сортування в порядку безладу? це ж не просто взяли перші-ліпші елементи і видали як є. Потрібно взяти елементи і примусово їх все розкласти в довільному порядку, згідно згенерувала випадкових чисел. Під час сортування ми завжди будемо отримувати найгірші розклади. тобто складність буде прагне до O (x * x), що дуже накладно по використанню ресурсів. Висновок: сортування даних в довільному порядку - це дуже витратна операція, яку потрібно уникати як вогню. І, коли потрібно, досвідчені програмісти це уникають, про що діляться своїми рішеннями: раз. два. три. чотири, п'ять шукайте в гуглі. Але в разі доса або стрес-тестування сайту така сортування дуже добре підходить!

Те, що процесор буде чогось робити з даними під час нескінченних порівнювання - це зрозуміло, але як у нас йдуть справи з пам'яттю? Тут багато чого буде залежати від кількості сортируемих даних: якщо їх багато, значить і пам'яті потрібно багато, якщо мало - то мало, але будь-якому випадку (увага.) Ми ніяк не можемо закеширувати дані, кеш безсилий, тому що безглуздо кешувати нескінченно випадкові набори даних .

Повертаючись до механізмів оперування даних саме в вордпресс, дізнаємося, що random-сортування там робиться через (my) SQL-запит за допомогою конструкції ORDER BY RAND (). Тому далі заглиблюємося в технічні особливості MySQL:

1) щоб в mysql впорядкувати вибрані select-му дані, необхідно оперувати відразу усіма даними, навіть якщо з них потрібна тільки мала частина. Наприклад, якщо в БД 1000 постів і потрібно на головній показати рандомно перші 10, mysql все одно вибере, потім відсортує всі 1000 постів і лише потім відсіче потрібні 10 елементів. Тому відбувається оперування всіма даними одночасно (!)

2) в mysql є опція в налаштуваннях (my.cnf), яка визначає розмір тимчасових таблиць в пам'яті, перевищуючи який, тимчасова таблиця переміщується на диск. Про існування цієї змінної початківці адміни або власники сайтів можуть і не знати, і, швидше за все, там встановлено якесь стандартне значення.
А тепер уявіть, що і без того не швидке сортування переміщається з пам'яті на диск - це погано, дуже. Тимчасові витрати по залізним причин автоматично зростають на 1-2 порядки. Виходить, щоб створити таку ситуацію, потрібно сортувати багато даних, щоб вони не вмістилися в пам'яті в тимчасовій таблиці і весь процес пішов в диск.

3) повертаємося до вибірці з 1000 постів. в mysql є така неприємна особливість. яка полягає в тому, що чим ближче до кінця потрібні дані з вибірки, тим довше потрібно чекати відповіді від БД, тобто запит перших 10 постів з 1000 (LIMIT 0,10) буде набагато швидше і легше, ніж останні 10 (LIMIT 990,10)

4) ну і наостанок сама вибірка може бути з умовами, при яких, наприклад ускладнюється робіт індексів або взагалі вони відсутні. Наприклад, це вибірка функції пошуку на сайті, тому що в mysql вона буде представлятися як-то так WHERE. LIKE '% key%'. а щоб в її результаті було побільше об'єктів, шукати слід те, що зустрічається в кожному об'єкті / пості, наприклад: точку "." - WHERE. LIKE '%.%'

Висновок: потрібно вибирати останні елементи з великої вибірки, заснованої на результаті пошуку, відсортованому Рандома.

У мене в блозі записів мало, тому в диск процес не йде, але все одно результат неможливо кешувати, тому алгоритм відпрацьовує ВІД і ДО. Найбільший ефект вийде на вордпресс-сайтах з великою кількістю постів.

Тут все просто. Знадобиться будь-який інструмент, що настроюється відсилання http-запитів в багато потоків, наприклад, wget, curl, ваш улюблений парсер або навіть програма на дельфи (хоча, сподіваюся, ці мамонти померли). Тестери використовують такі інструменти, з яких багатьом знайомий ab, а мені подобається httperf. Але тут на форумі я покажу приклад bash-команди на wget:

пояснення:
- timeout = 0.5 - потрібно підібрати дослідним шляхом, щоб wget встиг отресолвіть сервер і послати http запит, а потім коннект повинен обрубати на півслові, тому що чекати його відповіді сенсу немає, краще за цей час ще послати десяток інший запитів
- цей приклад НЕ використовує особливість з п.3. Для неї необхідно предваріельно обчислювати число доступних сторінок результату.
- метод POST і вказаний юзерагент використані, щоб не сильно смітити в логах

Способи вирішення проблеми:

1) основний спосіб вирішення проблеми - це не використовувати Wordpress, тому що я поки мовчу про інші його архітектурних проблемах, які також зручні у використанні для подібного тестування, а хтось напевно вже використовує В якості альтернативи пропоную використовувати, наприклад, Drupal 1. Drupal 2 або якісь інші платформи, створені розробниками, які хоча б закінчили школу.

2) Якщо від вордпресс позбутися не можна, то проблему потрібно вирішувати або повним видаленням можливостей використання, або модифікацією функції сортування, сенс якої полягає в тому, щоб а) піти від стандартного якісного рандома до якогось сильно спрощеним псевдо-Ранд, б) або кешування результатів сортування (рандом вибірка завжди буде складатися з одного і того ж набору даних) в) або скороченням розмірів вибірок.

Свої послуги по оптимізації і порятунок вордпресс не пропоную, тому що для мене це пройдений етап. По грошах зазвичай коштувало $ 100-300.

3) Також можна намагатися ловити і фільтрувати такі підозрілі запити, але їх структура може змінюватися і в ці періоди сервер буде спати, що неприємно.