Php Создан, Чтобы Умереть

Отказ от ответственности : За моим плечами более десяти лет разработки PHP. Я начал использовать его, когда PHP4 был еще младенцем, а PHP5 был всего лишь мечтой Zend. С его помощью я сделал многое, любил его, проклинал и не без стыда наблюдал, как он растет и развивается.

Я до сих пор использую его в некоторых устаревших проектах, но предпочитаю больше не использовать его.

Также хочу отметить, что я не сотрудничаю с создателями упомянутых в статье фреймворков или инструментов.

ТЛ;ДР (англ.

слишком долго; не читал.

Так, в частности, говорят, когда лень читать всю статью — прим.

пер.

): если ваш проект основан на функциях фоновых процессов (фоновых сервисов, демоны — ок.

пер.

), избегайте PHP. По моему мнению, в большинстве случаев ненавистники PHP упускают из виду один очень важный момент: PHP создан, чтобы умереть .

Это не означает, что достаточно функциональный (в некоторой степени) язык программирования растворится в воздухе; это просто означает, что ваш PHP-код не может работать вечно.

В настоящее время, 13 лет после первого официального релиза в 2000 году эта идея мне все еще кажется вполне разумной.



Умирающая программная модель

Ядро PHP следует простейшему рабочему процессу: получает входные данные, обрабатывает их, отображает выходные данные и умирает. Я думаю, такие сайты, как PHP-грусть , которые забавны и легко помогают выявить непоследовательность языка, лучше всего влияют на его архитектуру в целом.

Но наверняка были и другие попытки.

Вначале смерть не была большой проблемой для веб-сайтов.

Вы читаете что-то из базы данных, применяете логику или форматируете данные и выводите результат среди моря HTML-тегов.

PHP Это все еще трудно победить (это особенность его ядра), несмотря на весь ужас, который этот подход принес в мир программирования.

Хорошо, что все проблемы, которые можно было решить таким способом, уже решены, а оставшиеся решаются более умными и современными инструментами, ведь такой крохотный функционал обычно является малой частью в составе большого и сложного проекта.

Увы, PHP настаивает на смерти после выполнения .

А когда вы пытаетесь сделать обратное, происходят плохие вещи.



Больше не просто веб-сайт

Для PHP по-прежнему рекомендуется отправлять информацию из формы обратной связи по электронной почте.

В этом нет ничего плохого (ну, если я все еще буду делать это через десять лет, это может означать, что ранее я принял несколько действительно плохих решений).

Но это также пример того, что решалось миллион раз миллионом разных способов.

Практически любой другой веб-ориентированный язык или платформа тоже могут это сделать.

Давайте пропустим этот момент. Теперь мы пишем настоящее и сложное приложение.

Вместе со сложностью растет и количество программных кодов.

Допустим, вы довольно способный программист. Вы используете PHP 5.x и современные методы программирования.

В интерфейсах и классах всё предельно абстрактно.

Вы знаете, что делать с существующими библиотеками.

Теперь вы можете зависеть от своих собственных ORM, стороннего кода, разработанного интерфейса, возможно, функций вашего клиентского API для сторонних интерфейсов REST и т. д. Все написано на PHP. Вот здесь-то и начинается кошмар: вам неизбежно придется запускать код в фоновом режиме.

Ваше приложение достигло такого уровня сложности, что ожидания завершения HTTP-запроса уже недостаточно.

Причинами могут быть: вам необходимо обрабатывать очереди запросов или кэшировать информацию для ускорения HTTP-ответов; вам необходимо периодически проверять обязательные платежи и действовать в зависимости от результата или постоянно обновлять данные, полученные из внешних источников; вам также может потребоваться записать в базу данных целые пакеты данных, чтобы избежать потери производительности; Возможно, вам придется создать и поддерживать несколько сетевых подключений или выполнить серверную работу для приложения WebSocket. Это всего лишь примеры и их можно перечислять бесконечно, в зависимости от того, что вы разрабатываете.



Звоните интерактивно

Однако худшая реализация описанных выше вещей может показаться вполне знакомой: независимо от того, что требует PHP или выбранная вами платформа, ваш хостинг за 5 долларов в месяц, вероятно, не имеет доступа по SSH, утилиты cron или аналогичного инструмента.

Какое решение является самым простым? Конечно, перевести выполнение задач из фонового режима в интерактивный! Запускайте их случайным образом после каждого n-го посещения страницы (для 1/n-го посещения страницы — ориг.

).

Тогда случайный посетитель будет тратить время на ожидание завершения общесистемной фоновой задачи, и только после ее завершения будет обработан персональный запрос пользователя.

Становится тревожно думать, что во многие «серьёзные» и «развитые» фреймворки такая функция встроена с самого начала.

, потому что довольно сложно не только найти участки кода, отвечающие за этот процесс, но и понять их переплетение.

Так в чем проблема? Во-первых, нет необходимости задавать специальные параметры доступа к серверу; Достаточно старого доброго FTP. Во-вторых, все работает по запросу клиента, и небольшая задержка для него незаметна.

Именно поэтому провал гарантирован: при тестировании все работает отлично, на этапе реализации тоже хорошо, но под реальной нагрузкой ужасно.

Вы самонадеянно думаете, что посещений будет примерно столько, сколько вам нужно для запуска задач с интервалом в несколько минут. Но псевдослучайность на выборке из n сотен не сравнится с тысячами запросов в минуту.

.

Задачи, которые должны выполняться через определенное время, на самом деле обрабатываются несколько раз в мгновение ока.

Начинают происходить забавные вещи: например, одна и та же задача запускается и завершается одновременно, возникают ошибки, когда несколько процессов пытаются получить доступ к общим ресурсам с помощью механизма блокировки и т. д. Имейте в виду, что сбой процессов также приводит к тому, что запрошенная страница становится недоступной.

невозможно загрузить, потому что, как известно, умирает PHP, а за ним и все остальное, включая запрос пользователя.

В данном случае смерть не является гарантией успеха.

Если вы достаточно предприимчивы, вы можете переместить фоновые процессы в список задач обработчика cron. Так лучше: это работает до тех пор, пока есть достаточно времени, потому что.

в этом случае у нас есть только одна управляющая переменная.

В случае рекурсивных задач ( рекурсия вот суть ядра демона crond) вы всегда предполагаете, что одна задача завершится, прежде чем та же задача будет вызвана снова.

В большинстве случаев это может быть правдой, но с другой стороны, вам, возможно, придется корректировать интервалы планировщика, если нагрузка на сервер увеличивается, или надеяться, что один из них проработает достаточно долго, что может быть безопасно, но вредно для скорость ваших приложений.

В масштабе системы этот метод может быть очень и очень сложным.

К этому времени вы, возможно, уже подумываете о разбиении общесистемных задач на отдельные пакеты.

Но кто-то должен это посмотреть, кто-то, кто не умрет.

Призвать демонов

Настоящий кошмар начинается тогда, когда создание демонов или более устойчивых процессов кажется правильным решением.

Это можно доказать путем установления и поддержания связей.

Вебсокет или создание компонентов Производитель-потребитель .

Но PHP вас подведет. Есть несколько задач, для которых PHP не подходит. Помните, что PHP умирает, как бы вы ни старались его остановить.

Во-первых, существует проблема утечки памяти.

PHP никогда не заботится об его освобождении, если он больше не используется, потому что в конце концов все будет освобождено - после смерти .

В непрерывно текущих процессах выделено память (которая на самом деле пуста) будет накапливаться до тех пор, пока не будет достигнуто пороговое значение предел_памяти .

После этого ваш процесс будет прекращен без предупреждения.

Проблема здесь не в вас, если только вы не ожидаете, что процесс будет жить вечно.

При реальной нагрузке замените "медленные" процессы на " достаточно быстро ".

Конечно, были улучшения в аспекте «не тратить память», но их было недостаточно.

Как только увеличивается сложность или увеличивается нагрузка, всё ломается.

Рассмотрим следующий фрагмент кода:

  
   

class FOO { public $f; } class BAR { public $f; } while(1) { $a = new FOO(); $b = new BAR(); $a->f = $b; $b->f = $a; print "Memory usage: " .

number_format(memory_get_usage(true)) .

" bytes\n"; unset($a); unset($b); }

Вот так называемые циклические ссылки , объекты, которые ссылаются на другой объект, который, в свою очередь, ссылается на исходный.

Когда вы запускаете этот скрипт, в зависимости от версии PHP он будет постепенно потреблять все больше и больше памяти, потому что во время выполнения проверка того, что все циклические ссылки больше не используются, не будет выполнена, даже если вы явно попытаетесь освободить их с помощью команда сбросить() .

Это довольно распространенный пример.

Вы можете найти больше примеров того, что происходит, когда программа становится сложнее, чем приведенный выше сценарий.

Мы можем спорить о том, хорошо или плохо использование циклических ссылок, но есть одно место, где их можно найти в изобилии: ОРМ .

По некоторым веским причинам объект, представляющий запись в базе данных, тот же объект в памяти и при необходимости он ссылается на все другие объекты на основе ограничений внешнего ключа.

Это позволяет избежать многих проблем, таких как каскадное обновление записей по связанным ссылкам модели.

Теперь взгляните на схему вашей базы данных и посчитайте, сколько у вас внешних ключей.

посмотрите, сколько у вас циклических ссылок.

Может быть быть в запущенных процессах? PHP не сможет определить, какие из них используются, а какие нет, но рано или поздно свободная память закончится, независимо от того, используется она или нет, и PHP умрет. Важнее, чем тот факт, что Поддержание работоспособности вашей программы никогда не было приоритетом для PHP. Вопрос в том, почему такими проблемами (одна из которых описана выше) никогда серьезно не занимались.

Механизм вывоз мусора (Сборка мусора — ориг.

) впервые была представлена в PHP 5.3 как функция плагина.

Правильно: язык просит тебя «Пожалуйста, вы можете предотвратить утечку памятиЭ» .

Это была середина 2009 года, изменения относительно недавние.

Что произошло до этого? Абсолютно ничего .

Никого не волновало, предотвращает ли PHP утечку памяти или нет, потому что его заставили умереть , как только оно будет выполнено.

С точки зрения PHP утечки памяти — это нормально.



Дело не только в памяти

Более того.

Если вы довольно часто использовали PHP, вы, вероятно, знакомы с это проблема :

Fatal error: Exception thrown without a stack frame in Unknown on line 0

Что это значит? Честно не знаю.

Я не могу найти строку номер 0 в неизвестном файле PHP. Кажется, есть такие же невежественные люди, как я.

.

Некоторые говорят, что это связано с обработка ошибок и исключений в PHP. Никто точно не знает, но я могу говорить только об условиях, предшествовавших этой ошибке: постоянно запущенные процессы, работающие с гигабайтными базами данных, работающие под высокой нагрузкой в реальных условиях.

В действительности вы вряд ли обнаружите такие ошибки на своем локальном сервере.

У меня также иногда случалось внезапное завершение процесса, которое невозможно было отследить.

Они просто умерли.

PHP полон загадочных, труднообнаружимых или невоспроизводимых ошибок.

Просто взгляни на это .



Использование неправильных инструментов

Вы видите последовательность? У меня есть старые проекты, где PHP использовался в фоновых процессах или других местах, а не на обычных сайтах (здесь в скобках автор пишет «да, я Гиперклавиатура - прим.

пер.

) - но у каждого из них была одна и та же проблема.

Неважно, насколько хорошо ваша идея выглядит на бумаге; если вы хотите, чтобы процессы выполнялись постоянно, то знайте, что по тем или иным причинам они завершат работу, причем быстрее всего под нагрузкой .

Вы ничего не можете контролировать, потому что PHP создан для того, чтобы умереть.

Главной особенностью ядра этого языка является то, что все должно самоуничтожиться , и не важно, что это будет. Для нового проекта я использую Питон виртуальное окружение Колба , Руководитель И Единорог .

Я поражен тем, насколько хорошо все это работает, насколько продуман каждый из компонентов — а некоторые из них находятся в стадии бета-тестирования.

Но что еще более важно, они фактически поддерживают фоновые процессы.

Вы спросите: как они это делают? Они ничего не делают, Питон просто не кончает жизнь самоубийством.

Всё, это часть архитектуры ядра.

Я не хочу сказать, что это лекарство от всех бед. Возможно, я потратил слишком много времени на программирование на PHP и у меня сложилось такое впечатление.



Заключение

Конечно, всегда можно найти обходной путь.

Например, можно до смешного увеличить значение Memory_limit и немного увеличить время выполнения процессов.

Вы также можете поиграться с утилитой cron, сценариями оболочки и другими инструментами UNIX. Вы можете использовать PHP для создания веб-сайтов и другие языки для фоновых процессов.

Но имейте в виду, что здесь мы говорим о среднем и высоком уровнях сложности, а не только о самом языке, но также о библиотеках и инструментах, которые вы используете, поэтому, используя второй язык вместо того, который потерпел неудачу, вы можете оказаться неудачником.

тривиальная задача.

Это касается и тех инструментов, для которых 30-секундная задержка может привести к плачевным результатам.

Могут быть люди, которые думают, что более сервис-ориентированная архитектура поможет преодолеть ограничения PHP. Возможно, найдутся те, кто докажет, что PHP 5.4 и PHP 5.5 намного лучше и что язык постепенно улучшается.

К счастью, я уже пошел дальше.

Обсуждение HN И Реддит .

Продолжение Здесь Теги: #php #значение #die #php

Вместе с данным постом часто просматривают: