Комментарии 20
Вторая особенность — иногда нужно выключать CLI opcache (у нас он включён на скриптовых машинах). Когда-то мы его не выключали и теряли 30% CPU на этом. После того как осознали свою ошибку, удивились, как много можно сэкономить одной настройкой.
У меня кстати тоже была идея попробовать opcache в памяти для CLI, но не было уверенности в том, не будет ли такой проблемы:
1) phprocksyd запустился — создался новый пустой кусок shared memory для opcache (допустим, мы выделили 2 Гб под opcache)
2) позапускались куча скриптов, наполнили opcache, и от этого инстанса phprocksyd остался один скрипт, который конвертирует видео (т.е. работает много часов), и который «держит» этот 2 Гб кусок
3) перезапустили phprocksyd, он создал новый кусок opcache
4) опять позапускалась куча скриптов, опять остался один «долгий» скрипт, который держит другой кусок тоже в 2 Гб
5) rinse and repeat
То есть в этом случае память может «утекать» с космической скоростью. Я не знаю, есть ли у вас такая проблема в продакшене и влияет ли тот факт, что phprocksyd делает execve() и сохраняет свой PID, чилдов и прочее при рестарте, и что будет, если вы поменяете эту схему на что-нибудь другое :).
Альтернатива opcache в памяти для CLI — файловый опкеш, хотя он был не идеален :).
В теории такая ситуация возможна, но рестарт у нас случается крайне редко, да и скриптов сильно долгих не так много, поэтому на практике с такими проблемами мы не сталкивались. На машинах всегда достаточно свободной памяти.
> рестарт у нас случается крайне редко
Если всё правильно работает, то он должен рестартовать после каждого деплоя и патча, потому что он в себя также загружает кусок фреймворка :).
Да, ты прав, оказывается, что он сейчас делает reload на каждый деплой патча. (хотя мог бы делать это только в случае изменения тех файлов, которые были загружены в родительском процессе до первого fork, в противном случае reload — лишний)
Но "рестартовать" — достаточно громкое название для этого процесса: там делается pcntl_exec(), который суть execve(), поэтому мы не сталкиваемся с теми проблемами, о которых ты говоришь.
Полноценный рестарт происходит крайне редко. Это нештатная ситуация.
Ну так PHP интерпретатор же инициализируется каждый раз заново, а значит вы полагаетесь на то, что шареная память остаётся той же самой? Если да, то ее неплохо бы сбрасывать иногда, поскольку PHP может её наполнить один раз и не сбросить сам, даже если постоянно идут промахи кеша (а также у него куча других ограничений, например можно максимум N файлов иметь в опкеше, после чего он перестает добавлять новые, даже если ещё есть свободная память). Из-за этих моментов у вас также должен быть скрипт, который сбрасывает опкеш для веба раз в сутки в минимум трафика, но я сомневаюсь, что он делает это для CLI :).
мне наоборот показалось, что в авито грамотные чуваки, которые не клюют на хайповые штуки.
да, пример с xdebug, конечно, ужасен.
но на самом деле, вероятность, что т.н. девосп накосячит, имхо еще выше. т.к. они зачастую не в курсе про такие штуки вообще. и могут стать лишь очередным административным барьером с аргументом — работает не трожь.
мне наоборот показалось, что в авито грамотные чуваки, которые не клюют на хайповые штуки.
От некоторых их статей и докладов ровно обратное вашему впечатление. От предпоследнего просмотренного публичного доклада, я первый раз пробил лоб рукой когда какой-то их тимлид заявил что Go не ООП потому что нет наследования, второй раз когда он сказал что в PHP им приходилось делать плохой нейминг(приложив эту пикчу), а в Go они называют вещи своими именами потому что там на первом месте работа с данными.
На этом, собственно, сделал выводы и просмотр прекратил.
Да даже в этой статье их абзац про микросервисы вызывает грусть(тот который якобы про успех).
p.s. Я за авторитет истины, а не истину авторитета…
А это не быстрее, чем php-fpm? Практикуется ли написание микросервисов на базе reactphp.org/http или любого другого асинхронного фреймворка?
В случае если узкое место приложения — CPU, асинхронные фреймворки ничем не выигрывают, а даже наоборот вредят (из-за издержек на асинхронность). При этом код и отладка с ними становятся сложнее.
Если у вас иная ситуация, например, ваше приложение бОльшую часть времени проводит в ожидании чего-либо (например, сетевого взаимодействия) и по каким-то причинам вас перестала устраивать синхронная модель (например, у вас одновременно открыто огромное количество постоянных соединений => уже поставили очередной десяток серверов из-за нехватки памяти и большого количества процессов, а CPU у всех простаивает), то возможно вам имеет смысл задуматься над асинхронными фреймворками.
У нас ситуация абсолютно противоположная, поэтому для нас это не имеет смысла.
В моей задаче было много простых запросов к API и использование reactphp.org/http дало эффект, imho, по двум причинам:
- нет накладных расходов на загрузку скрипта со всей инициализацией при каждом запросе;
- кеширование в локальных переменных (в частности, данных об авторизации).
А можете раскрыть немного подробностей?
- насколько много запросов
- были ли нюансы-грабли в продакшн запуске reactphp
- какой аптайм между перезапусками
- управление запуском: супервизор, контейнеры
С интересом много лет слежу за его развитием, но пока не использовал в проде и под нагрузкой, и мало встречается публикаций на тему подобного опыта.
- до 500 запросов в секунду
- никаких граблей не было
- работало месяцами
- супервизор
Спасибо!
Вот стоило посетовать на недостаток публикаций, как в ленте появилась расшифровка детального доклада на тему https://m.habr.com/ru/company/oleg-bunin/blog/487258/
Железо или оптимизация? Badoo, Авито и Мамба — о производительности PHP