Apache досягає MaxClients та блокує сервер


9

На даний момент у мене працює сервер Apache2 з VV OpenVZ mpm-preforkі mod_phpна ньому 512М реальної / 1024М оперативної пам'яті (без підкачки). Провівши кілька тестів, я виявив, що максимальний розмір процесу, який отримує Apache, становить 23 М, тому я встановив MaxClients25 (23М х 25 = 575 Мб, нормально для мене). Я вирішив запустити кілька тестів на завантаження на своєму сервері, і результати залишили мене спантеличеними.

Я використовую abна своєму робочому столі запит на головну сторінку з блогу wordpress.

Коли я працюю abз 24 одночасними з'єднаннями, все здається нормальним. Звичайно, процесор піднімається, вільна оперативна пам'ять знижується, а результат - приблизно 2-3 секунди часу відповіді на запит.

Але якщо я працюю abз 25 одночасними з'єднаннями (ліміт мого сервера), Apache просто зависає через пару секунд. Він починає обробляти запити, потім перестає відповідати, процесор повертається до 100% простою та abвичерпується. Журнал Apache говорить, що він досяг MaxClients.

Коли це трапляється, Apache залишається заблокованим з 25 запущеними процесами (всі вони знаходяться в "W", якщо я перевіряю стан сервера), і лише після TimeOutвстановлення процесів починають вмирати, і сервер знову починає реагувати (у моєму випадку це встановлено до 45).

Моє запитання: це очікувана поведінка? Чому Apache просто вмирає, коли дістається MaxClients? Якщо він працює з 24 підключеннями, чи не повинен він працювати з 25, просто знадобиться, можливо, більше часу, щоб відповісти на кожен запит і скласти черги на решту?

Мені щось дивно звучить, що будь-яка дитина, яка працює, abможе самостійно вбити веб-сервер, встановивши паралельні з'єднання з серверами MaxClients.

Відповіді:


17

ХА! Нарешті я сам знайшов проблему. Це більше пов’язано з програмуванням, ніж адміністратором сервера, але я вирішив все-таки поставити відповідь, тому що пошуком google я виявив, що я не єдиний з такою проблемою (а оскільки Apache висить, перша здогадка - це проблема з сервером).

Проблема не в Apache, а в моєму Wordpress. Більш конкретно з моєю темою. Я використовую тему під назвою Lightworld, і вона підтримує додавання зображення до заголовка блогу. Щоб дозволити це, він перевіряє розмір зображення за допомогою функції PHP getimagesize(). Оскільки ця функція відкривала ще одне http-з'єднання до сервера для отримання зображення, кожен запит abстворював ще один запит внутрішньо з PHP. Оскільки я використовував усі доступні мої серверні слоти, ці PHP-запити були поставлені у чергу, але Apache ніколи не міг дістатись до них, оскільки всі його процеси були заблоковані оригінальним запитом, що очікує на слот для завершення внутрішнього запиту PHP.

Фактично, PHP ставив мій сервер у глухий стан, і Apache почне працювати нормально лише після того, як ці з’єднання вичерпали очікування свого "дочірнього" запиту.

Після того як я видалив цю функцію зі своєї теми, тепер я можу на abсвоєму сервері мати стільки одночасних з'єднань, скільки я хочу, і Apache ставить їх у чергу, як очікувалося.


Дякую за те, що ви розмістили це тут, я намагався вирішити проблему з точно такими ж симптомами вже зараз, коли зараз страждають - подумайте, у нас теж є тупик!
Джеймс Йейл

як ви це визначили, мене насамперед цікавлять журнали та інструменти, які ви використовували для визначення вторинного вихідного запиту.
Аніруд Гоель

2

Тут відбувається те, що у вас є 25 потоків, здатних приймати з'єднання, і ви надсилаєте 26 одночасних запитів. Цей останній запит знаходиться в черзі сокетів, залежно від розміру вашого відсталого.

Друга проблема полягає в тому, що все, що ви працюєте, займає 2-3 секунди, займає достатньо часу, щоб відповісти, що 25 одночасних з'єднань сповільнюють його. сон (1) може спрацювати, але, якщо ви робите блокування файлів або блокування таблиці з mysql, кожен паралельний запит може чекати на попереднє завершення, поки вони не потраплять на 45 секунд таймаут.

23mb звучить мало для процесу apache з модулем mod_php та будь-якими завантаженими модулями, тож, я підозрюю, що ви, можливо, бачите ці процеси apache, які займають трохи більше оперативної пам’яті під час роботи програми. Ви дійсно не можете займатися математикою з MaxClients та такою пам'яттю ... це буде дещо близько, але, ніколи не знаєте.

www-data  1495  0.1  0.9  56288 19996 ?        S    15:48   0:01 /usr/sbin/apache2 -k start
www-data  1500  0.0  0.5  49684 12436 ?        D    15:48   0:00 /usr/sbin/apache2 -k start

Є одна машина, 56М і 49М процесів.

інша машина:

www-data  7767  0.1  0.1 213732 14840 ?        S    14:55   0:08 /usr/sbin/apache2 -k start
www-data  8020  0.2  0.1 212424 13660 ?        S    14:57   0:08 /usr/sbin/apache2 -k start

інша машина:

www-data 28509  0.8  0.1 161720 10068 ?        S    14:39   0:43 /usr/sbin/apache2 -k start
www-data 28511  0.8  0.1 161932 10344 ?        S    14:39   0:43 /usr/sbin/apache2 -k start

Отже, використання пам'яті дуже залежить від завдання, які модулі завантажуються тощо. На останніх двох, я вважаю, ми відключили pdo & pdo_mysql, оскільки ця програма їх не використовує.

Справжнє питання: що ти робиш, що займає 3 секунди? У сучасному світі це вічність і вважається додатком "блокуючим". Apache зазвичай не загине, але залишить ці теми у черзі відставання, поки він не зможе їх обслуговувати або очікує час очікування. Я вважаю, що ваша програма, ймовірно, спричиняє тайм-аут apache. Спробуйте його на сторінці, що містить просто phpinfo (); і подивіться, чи результати однакові.


Дякую за всі поради! Я усвідомлюю, що мені ще потрібно оптимізувати багато речей (я тільки почав налаштовувати сервер пару днів тому, і це мій перший досвід роботи з VPS), але проблема була глибшою за це ... Я опублікував відповідь на питання, що пояснює, у чому проблема в моєму конкретному випадку.
Родріго Сієро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.