Привет. Меня зовут Андрей, я студент-магистрант в одном из технических ВУЗов Москвы и по совместительству очень скромный начинающий предприниматель и разработчик. В этой статье я решил поделиться своим опытом перехода от PHP (который когда-то мне нравился из-за своей простоты, но со временем стал ненавидим мною — под катом объясняю почему) к NodeJS. Здесь могут приводиться очень банальные и кажущиеся элементарными задачи, которые, тем не менее, лично мне было любопытно решать в ходе моего знакомства с NodeJS и особенностями серверной разработки на JavaScript. Я попытаюсь объяснить и наглядно доказать, что PHP уже окончательно ушёл в закат и уступил своё место NodeJS. Возможно, кому-то даже будет полезно узнать некоторые особенности рендеринга HTML-страниц в Node, который изначально не приспособлен к этому от слова совсем.
Введение
Во время написания движка я использовал простейшие техники. Никаких менеджеров пакетов, никакого роутинга. Только хардкор — папки, чьё название соответствовало запрашиваемому маршруту, да index.php в каждой из них, настроенный PHP-FPM для поддержания пула процессов. Позднее возникла необходимость использовать Composer и Laravel, что и стало последней каплей для меня. Перед тем, как перейти к рассказу о том, зачем же я вообще взялся переписывать всё с PHP на NodeJS, расскажу немного о предыстории.
Менеджер пакетов
В конце 2018 года довелось работать с одним проектом, написанным на Laravel. Нужно было исправить несколько багов, внести правки в существующий функционал, добавить несколько новых кнопок в интерфейсе. Начался процесс с установки менеджера пакетов и зависимостей. В PHP для этого используется Composer. Тогда заказчик предоставил сервер с 1 ядром и 512 мегабайтами оперативной памяти и это был мой первый опыт работы с Composer. При установке зависимостей на виртуальном приватном сервере с 512 мегабайтами памяти процесс аварийно завершился из-за нехватки памяти.
Для меня, как человека знакомого с Linux и имеющего опыт работы с Debian и Ubuntu решение такой проблемы было очевидно — установка SWAP-файла (файл подкачки — для тех, кто не знаком с администрированием в Linux). Начинающий неопытный разработчик, установивший свой первый Laravel-дистрибутив на Digital Ocean, например, просто пойдёт в панель управления и будет поднимать тариф до тех пор, пока установка зависимостей не перестанет завершаться с ошибкой сегментации памяти. А как там обстоят дела с NodeJS?
А в NodeJS есть свой собственный менеджер пакетов — npm. Он значительно проще в использовании, компактнее, может работать даже в среде с минимальным количеством оперативной памяти. В целом, ругать Composer на фоне NPM особо не за что, однако в случае возникновения каких-то ошибок при установке пакетов Composer вылетит с ошибкой как обычное PHP-приложение и вы никогда не узнаете, какая часть пакета успела установиться и установилась ли она в конце-концов. И вообще, для администратора Linux вылетевшая установка = флэшбеки в Rescue Mode и dpkg --configure -a
. К тому времени, как меня настигли такие "сюрпризы", я уже недолюбливал PHP, но это уже были последние гвозди в крышку гроба моей некогда великой любви к PHP.
Long-term support и проблема версионирования
Помните, какой ажиотаж и изумление вызвал PHP7, когда разработчики впервые презентовали его? Увеличение производительности более чем в 2 раза, а в некоторых компонентах до 5 раз! А помните, когда появился на свет PHP седьмой версии? А как быстро-то заработал WordPress! Это был декабрь 2015 года. А знали ли вы, что PHP 7.0 уже сейчас считается устаревшей версией PHP и крайне рекомендуется обновить его… Нет, не до версии 7.1, а до версии 7.2. По утверждениям разработчиков, версия 7.1 уже лишена активной поддержки и получает лишь обновления безопасности. А через 8 месяцев прекратится и это. Прекратится, вместе с активной поддержкой и версии 7.2. Выходит, что к концу текущего года у PHP останется лишь одна актуальная версия — 7.3.
На самом деле, это не было бы придиркой и я бы не отнёс это к причинам моего ухода от PHP, если бы написанные мной проекты на PHP 7.0.* уже сейчас не вызывали deprecation warning при открытии. Вернёмся к тому проекту, где вылетала установка зависимостей. Это был проект, написанный в 2015 году на Laravel 4 с PHP 5.6. Казалось, прошло же всего 4 года, ан-нет — куча deprecation-предупреждений, устаревшие модули, невозможность нормально обновиться до Laravel 5 из-за кучи корневых обновлений движка.
И это касается не только самого Laravel. Попробуйте взять любое приложение на PHP, написанное во времена активной поддержки первых версий PHP 7.0 и будьте готовы потратить свой вечер на поиск решений проблем, возникших в устаревших модулях PHP. Напоследок интересный факт: поддержка PHP 7.0 была прекращена раньше, чем поддержка PHP 5.6. На секундочку.
А как дела с этим обстоят у NodeJS? Я бы не сказал, что здесь всё значительно лучше и что сроки поддержки у NodeJS кардинально отличаются от PHP. Нет, здесь всё примерно так же — каждая LTS-версия поддерживается в течение 3 лет. Вот только у NodeJS немного больше этих самых актуальных версий.
Если у вас возникнет необходимость развернуть приложение, написанное в 2016 году, то будьте уверены, что у вас не будет с этим совершенно никаких проблем. Кстати говоря, версия 6.* перестанет поддерживаться только в апреле этого года. А впереди ещё 8, 10, 11 и готовящаяся 12.
О трудностях и сюрпризах при переходе на NodeJS
Начну, пожалуй, с самого волнующего меня вопроса о том, как же всё-таки рендерить HTML-страницы в NodeJS. Но давайте для начала вспомним, как это делается в PHP:
- Встраивать HTML напрямую в PHP-код. Так делают все новички, кто ещё не добрался до MVC. И так сделано в WordPress, что категорически ужасающе.
- Использовать MVC, что как бы должно упростить взаимодействие разработчика и обеспечить какое-то разбиение проекта на части, но на деле этот подход лишь усложняет всё в разы.
- Использовать шаблонизатор. Наиболее удобный вариант, но не в PHP. Просто посмотрите синтаксис, предлагаемый в Twig или Blade с фигурными скобками и процентами.
Я являюсь ярым противником совмещения или слияния нескольких технологий воедино. HTML должен существовать отдельно, стили для него — отдельно, JavaScript-отдельно (в React это вообще выглядит чудовищно — HTML и JavaScript вперемешку). Именно поэтому идеальный вариант для разработчиков с предпочтениями как у меня — шаблонизатор. Искать его для веб-приложения на NodeJS долго не пришлось и я сделал выбор в пользу Jade (PugJS). Просто оцените простоту его синтаксиса:
div.row.links
div.col-lg-3.col-md-3.col-sm-4
h4.footer-heading Флот.ру
div.copyright
div.copy-text 2017 - #{current_year} Флот.ру
div.contact-link
span Контакты:
a(href='mailto:hello@flaut.ru') hello@flaut.ru
Здесь всё достаточно просто: написал шаблон, загрузил его в приложение, скомпилировал один раз и далее используешь в любом удобном месте в любое удобное время. По моим ощущениям, производительность PugJS примерно в 2 раза лучше, чем рендеринг с помощью внедрения HTML в PHP-код. Если раньше в PHP статическая страница генерировалась сервером примерно за 200-250 миллисекунд, то теперь это время составляет примерно 90-120 миллисекунд (речь идёт не о самом рендеринге в PugJS, а о времени, затраченном от запроса страницы до ответа сервера клиенту с готовым HTML). Так выглядит загрузка и компиляция шаблонов и их компонентов на стадии запуска приложения:
const pugs = {}
fs.readdirSync(__dirname + '/templates/').forEach(file => {
if(file.endsWith('.pug')) {
try {
var filepath = __dirname + '/templates/' + file
pugs[file.split('.pug')[0]] = pug.compile(fs.readFileSync(filepath, 'utf-8'), { filename: filepath })
} catch(e) {
console.error(e)
}
}
})
// и далее рендеринг уже скомпилированного шаблона
return pugs.tickets({ ...config })
Выглядит невероятно просто, но с Jade возникла небольшая сложность на этапе работы с уже скомпилированным HTML. Дело в том, что для внедрения скриптов на странице используется асинхронная функция, которая забирает все .js
файлы из директории и добавляет к каждому из них дату их последнего изменения. Функция имеет следующий вид:
for(let i = 0; i < files.length; i++) {
let period = files[i].lastIndexOf('.') // get last dot in filename
let filename = files[i].substring(0, period)
let extension = files[i].substring(period + 1)
if(extension === 'js') {
let fullFilename = filename + '.' + extension
if(env === 'production') {
scripts.push({ path: paths.production.web + fullFilename, mtime: await getMtime(paths.production.code + fullFilename)})
} else {
if(files[i].startsWith('common') || files[i].startsWith('search')) {
scripts.push({ path: paths.developer.scripts.web + fullFilename, mtime: await getMtime(paths.developer.scripts.code + fullFilename)})
} else {
scripts.push({ path: paths.developer.vendor.web + fullFilename, mtime: await getMtime(paths.developer.vendor.code + fullFilename)})
}
}
}
}
На выходе получаем массив объектов с двумя свойствами — путь к файлу и время его последнего редактирования в timestamp (для обновления клиентского кэша). Проблема в том, что ещё на этапе сбора файлов скриптов из директории они все загружаются в память строго по алфавиту (так они расположены в самой директории, а сбор файлов в ней осуществляется сверху вниз — от первого до последнего). Это приводило к тому, что сначала загружался файл app.js, а уже после него шёл файл core.min.js с полифиллами, и в самом конце — vendor.min.js. Решилась эта проблема достаточно просто — очень банальной сортировкой:
scripts.sort((a, b) => {
if(a.path.includes('core.min.js')) {
return -1
} else if(a.path.includes('vendor.min.js')) {
return 0
}
return 1
})
В PHP же это всё имело монструозный вид в виде заранее записанных в строку путей к JS-файлам. Просто, но непрактично.
NodeJS держит своё приложение в оперативной памяти
Это огромный плюс. У меня всё устроено так, что на сервере параллельно и независимо друг от друга существуют два отдельных сайта — версия для разработчика и production-версия. Представим, что я сделал какие-то изменения в PHP-файлы на сайте для разработки и мне нужно выкатить эти изменения на production. Для этого нужно останавливать сервер или ставить заглушку "извините, тех. работы" и в это время копировать файлы по отдельности из папки developer в папку production. Это вызывает какой-никакой простой и может вылиться в потерю конверсий. Преимущество in-memory application в NodeJS заключается для меня в том, что все изменения в файлы движка будут внесены только после его перезагрузки. Это очень удобно, поскольку можно скопировать все необходимые файлы с изменениями и только после этого перезагрузить сервер. Процесс занимает не более 1-2 секунд и не вызовет даунтайма.
Такой же подход используется в nginx, например. Вы сначала редактируете конфигурацию, проверяете её при помощи nginx -t
и только потом вносите изменения с service nginx reload
Кластеризация NodeJS-приложения
В NodeJS есть очень удобный инструмент — менеджер процессов pm2. Как мы обычно запускаем приложения в Node? Заходим в консоль и пишем node index.js
. Как только мы закрываем консоль — приложение закрывается. По крайней мере, так происходит на сервере с Ubuntu. Чтобы избежать этого и держать приложение запущенным всегда, достаточно добавить его в pm2 простой командой pm2 start index.js --name production
. Но это ещё не всё. Инструмент позволяет проводить мониторинг (pm2 monit
) и кластеризацию приложения.
Давайте вспомним о том, как организованы процессы в PHP. Допустим, у нас есть nginx, обслуживающий http-запросы и нам нужно передать запрос на PHP. Можно либо сделать это напрямую и тогда при каждом запросе будет спавниться новый процесс PHP, а при его завершении — убиваться. А можно использовать fastcgi-сервер. Думаю, все знают что это такое и нет необходимости вдаваться в подробности, но на всякий случай уточню, что в качестве fastcgi чаще всего используется PHP-FPM и его задача — заспавнить множество процессов PHP, которые в любой момент готовы принять и обработать новый запрос. В чём недостаток такого подхода?
Во-первых, в том, что вы никогда не знаете, сколько памяти будет потреблять ваше приложение. Во-вторых, вы всегда будете ограничены в максимальном количестве процессов, а соответственно, при резком скачке трафика ваше PHP-приложение либо использует всю доступную память и упадёт, либо упрётся в допустимый предел процессов и начнёт убивать старые. Это можно предотвратить, установив не-помню-какой-параметр в конфигурационном файле PHP-FPM в dynamic и тогда будет спавниться столько процессов, сколько необходимо в данное время. Но снова-таки, элементарная DDoS-атака выест всю оперативную память и положит ваш сервер. Или, например, багнутый скрипт съест всю оперативную память и сервер зависнет на какое-то время (были прецеденты в процессе разработки).
Кардинальное отличие в NodeJS заключается в том, что приложение не может потребить более чем 1,5 гигабайта оперативной памяти. Нет никаких ограничений по процессам, есть только ограничение по памяти. Это стимулирует писать максимально легковесные программы. К тому же очень просто рассчитать количество кластеров, которые мы можем себе позволить в зависимости от имеющегося ресурса CPU. Рекомендуется на каждое ядро "вешать" не более одного кластера (ровно как и в nginx — не более одного воркера на одно ядро CPU).
Преимущество такого подхода ещё и в том, что PM2 перезагружает все кластеры по очереди. Возвращаясь к предыдущему абзацу, в котором говорилось о 1-2 секундном даунтайме при перезагрузке. В Cluster-Mode при перезагрузке сервера ваше приложение не испытает ни миллисекунды даунтайма.
NodeJS — это хороший швейцарский нож
Ныне сложилась такая ситуация, когда PHP выступает в качестве языка для написания сайтов, а Python выступает в качестве инструмента для краулинга этих самых сайтов. NodeJS — это 2 в 1, с одной стороны вилка, с другой — ложка. Вы можете писать быстрые и производительные приложения и веб-краулеры на одном сервере в пределах одного приложения. Звучит заманчиво. Но как это может быть реализовано, спросите вы? Сама компания Google выкатила официальное API с Chromium — Puppeteer. Вы можете запускать Headless Chrome (браузер без интерфейса пользователя — "безголовый" Chrome) и получить максимально широкий доступ к API-браузера для обхода страниц. Максимально просто и доступно о работе Puppeteer.
Например, в нашей группе ВКонтакте происходит регулярный постинг скидок и специальных предложений на различные направления из городов СНГ. Мы генерируем изображения для постов в автоматическом режиме, а чтобы они были ещё и красивыми — нам нужны красивые картинки. Я не любитель подвязываться на различные API и заводить на десятках сайтов аккаунты, поэтому я написал простое приложение, имитирующее обычного пользователя с браузером Google Chrome, который ходит по сайту со стоковыми картинками и забирает случайным образом изображение, найденное по ключевому слову. Раньше для этого я использовал Python и BeautifulSoup, но теперь в этом отпала необходимость. А самая главная особенность и преимущество Puppeteer заключается в том, что вы можете с лёгкостью краулить даже SPA-сайты, ведь вы имеете в своём распоряжении полноценный браузер, понимающий и исполняющий JavaScript-код на сайтах. Это до боли просто:
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']})
const page = (await browser.pages())[0]
await page.goto(`https://pixabay.com/photos/search/${imageKeyword}/?cat=buildings&orientation=horizontal`, { waitUntil: 'networkidle0' })
Вот так в 3 строчки кода мы запустили браузер и открыли страницу сайта со стоковыми изображением. Теперь мы можем выбрать случайный блок с изображением на странице и добавить к нему класс, по которому в дальнейшем сможем точно так же обратиться и уже перейти на страницу непосредственно с самим изображением для его дальнейшей загрузки:
var imagesLength = await page.evaluate(() => {
var photos = document.querySelectorAll('.search_results > .item')
if(photos.length > 0) {
photos[Math.floor(Math.random() * photos.length)].className += ' --anomaly_selected'
}
return photos.length
})
Вспомните, сколько бы потребовалось кода, чтобы написать подобное на PhantomJS (который, кстати, закрылся и вступил в тесное сотрудничество с командой разработки Puppeteer). Разве наличие такого чудесного инструмента может остановить кого-нибудь от перехода к NodeJS?
В NodeJS заложена асинхронность на фундаментальном уровне
Это можно считать огромным преимуществом NodeJS и JavaScript, особенно с приходом async/await в ES2017. В отличии от PHP, где любой вызов выполняется синхронно. Приведу простой пример. Раньше у нас в поисковике страницы генерировались на сервере, но кое-что нужно было выводить на страницу уже в клиенте с помощью JavaScript, а на тот момент Яндекс ещё не умел в JavaScript на сайтах и специально для него пришлось реализовывать механизм снапшотов (снимков страниц) при помощи Prerender. Снапшоты хранились у нас на сервере и выдавались роботу при запросе. Дилемма заключалась в том, что эти снимки генерировались в течение 3-5 секунд, что совершенно недопустимо и может повлиять на ранжирование сайта в поисковой выдаче. Для решения этой задачи был придуман простой алгоритм: когда робот запрашивает какую-то страницу, снимок которой у нас уже есть, то мы просто отдаём ему уже имеющийся у нас снимок, после чего "в фоне" выполняем операцию по созданию нового снимка и заменяем им уже имеющийся. Как это было делано в PHP:
exec('/usr/bin/php ' . __DIR__ . '/snapshot.php -a ' . $affiliation_type . ' -l ' . urlencode($full_uri) . ' > /dev/null 2>/dev/null &');
Никогда так не делайте.
В NodeJS этого можно добиться вызовом асинхронной функции:
async function saveSnapshot() {
getSnapshot().then((res) => {
db.saveSnapshot().then((status) => {
if(status.err) console.error(err)
})
})
}
/**
* И вызываем функцию без await
* Т.е. не будем дожидаться resolve() от промиса
*/
saveSnapshot()
Вкратце, вы не пытаетесь обойти синхронность, а сами определяете, когда использовать синхронное выполнение кода, а когда асинхронное. И это действительно удобно. Особенно когда вы узнаете о возможностях Promise.all()
Сам движок поисковика авиабилетов устроен таким образом, что он отсылает запрос на второй сервер, собирающий и агрегирующий данные, и затем обращается к нему за уже готовыми к выдаче данными. Для привлечения трафика из органики используются страницы направлений.
Например, по запросу "Авиабилеты Москва Санкт-Петербург" будет выдана страница с адресом /tickets/moscow/saint-petersburg/, а на ней нужны данные:
- Цены авиабилетов по этому направлению на текущий месяц
- Цены авиабилетов по этому направлению на год вперёд (средняя цена по каждому месяцу для следующих 12 месяцев)
- Расписание авиарейсов по этому направлению
- Популярные направления из города отправки — из Москвы (для перелинковки)
- Популярные направления из города прибытия — из Санкт-Петербурга (для перелинковки)
В PHP все эти запросы выполнялись синхронно — один за другим. Среднее время ответа API по одному запросу — 150-200 миллисекунд. Умножаем 200 на 5 и получаем в среднем секунду только на выполнение запросов к серверу с данными. В NodeJS есть замечательная функция Promise.all, которая выполняет все запросы параллельно, но записывает результат поочерёдно. Например, так выглядел бы код выполнения всех пяти выше описанных запросов:
var [montlyPrices, yearlyPrices, flightsSchedule, originPopulars, destPopulars] = await Promise.all([
getMontlyPrices(),
getYearlyPrices(),
getFlightSchedule(),
getOriginPopulars(),
getDestPopulars()
])
И получаем все данные за 200-300 миллисекунд, сократив время генерации данных для страницы с 1-1,5 секунд до ~500 миллисекунд.
Заключение
Переход с PHP на NodeJS помог мне ближе познакомиться с асинхронным JavaScript, научиться работе с промисами и async/await. После того, как движок был переписан, скорость загрузки страниц была оптимизирована и отличалась разительно от результатов, которые показывал движок на PHP. В этой статье можно было бы ещё рассказать о том, насколько просто используются модули для работы с кэшем (Redis) и pg-promise (PostgreSQL) в NodeJS и устроить сравнение их с Memcached и php-pgsql, но эта статья итак получилась достаточно объёмной. А зная мой "талант" к писательству, она получилась ещё и плохо структурированной. Цель написания этой статьи — привлечь внимание разработчиков, которые до сих пор работают с PHP и не знают о прелестях NodeJS и разработки веб-ориентированных приложений на нём на примере реально существующего проекта, который когда-то был написан на PHP, но из-за предпочтений своего владельца ушёл на другую платформу.
Надеюсь, что мне удалось донести мои мысли и более-менее структурировано изложить их в этом материале. По крайней мере, я старался :)
Пишите любые комментарии — доброжелательные или гневные. Буду отвечать на любой конструктив.
Комментарии (88)
zzzmmtt
19.03.2019 15:57+2Статья и серии «Я не освоил PHP + CI/CD поэтому пересел на ноду».
Проблемы с даунтаймом при апргрейде сайта на php решаются парой строк sh-скрипта + git.
Есть сторонние инструменты, типа того же jenkins.
По поводу асинхронности, если не путаю, reactphp.
Композер да, иногда упирается в оперативу. Но никто не запрещает в тестовом окружении установить пакеты и зааплоадить вместе с автолоадером на сервак, хоть это и не очень правильно. Да и NPM не безгрешен.JamesJGoodwin Автор
19.03.2019 16:07-1Дело в том, что все вышеперечисленные проблемы в PHP так или иначе решаются с помощью различных надстроек, на изучение которых нужно тратить время. Лучше потратить это драгоценное время написание кода с использованием нативных инструментов.
TheYellingChives
19.03.2019 17:40+4Лучше потратить это драгоценное время написание кода с использованием нативных инструментов.
Знание о которых вы впитали в себя с молоком матери или что?
Драгоценное время вы потратили на написание этой статьи например…JamesJGoodwin Автор
19.03.2019 17:59-1Документация по нативным инструментам собрана в одном месте — на сайте NodeJS, где приведены исчерпывающие примеры. На PHP.net есть полным-полно примеров, которые заминусили и которые однозначно нельзя использовать в теперешнее время. Большинство проблем в PHP решается с помощью поиска ответов на StackOverflow, где тоже нужно вчитываться в текст и переводить его с английского, что, опять-таки, для меня совершенно не проблема, но для новичков без знания английского от этого станет больно.
Ashot
19.03.2019 19:12+4Большинство проблем в PHP решается с помощью поиска ответов на StackOverflow
Так решается большинство проблем независимо от ЯП – хоть PHP, хоть JS. И ничего плохого, в этом, кстати, нет. Вполне себе такой нормальный кейс: не знаешь/не понимаешь как решить проблему, гуглишь, и с большой долей вероятности попадаешь на stackoverflow с решением проблемы, PHP тут не при чём от слова совсем.
vladkorotnev
20.03.2019 11:35+2Причём в JS можно ещё и сократить зазор во времени между поломкой кода и поиском решения :-)
try {
myBusinessLogic();
} catch (e) {
window.open('https://stackoverflow.com/?q=[js] '+e.message);
}
zzzmmtt
19.03.2019 17:56+1С консолью линукса/юникса знакомы? Команда mv вам известна? А git pull? Эти сторонние инструменты вы в разработке не используете?
JamesJGoodwin Автор
19.03.2019 18:01-5С консольными инструментами не всегда удобно работать. Например, на 13-дюймовом ноутбуке. Для этого больше подходят решения с визуальным интерфейсом, например GitLab, который можно установить на свой виртуальный сервер и создать там закрытый репозиторий. Я бы так и сделал, но меня вполне устраивает текущий вариант деплоя. Учитывая, что я один единственный разработчик в этом проекте :)
zzzmmtt
19.03.2019 18:51Так в консоли то деплой можно заскриптовать на один алиас, что вам, как единственному разработчику на проекте сильно упростит жизнь)
Free_ze
19.03.2019 19:02+2С консольными инструментами не всегда удобно работать. Например, на 13-дюймовом ноутбуке.
Чем вам мешает небольшая диагональ? Это GUI обычно грешат тем, что кнопки то не вмещаются, то сжимаются так, что нажать невозможно. А текст — есть текст, CLI пришел к нам из тех времен, когда 13" с разрешением хотя бы в 1024х768 было мечтой. Лишь бы адекватная клавиатура была.
arkamax
19.03.2019 20:22С консольными инструментами не всегда удобно работать. Например, на 13-дюймовом ноутбуке.
Замечу, что консольные инструменты обычно намного проще и дешевле автоматизировать (и контролировать), что в продакшене дает экономию средств и ресурсов. Удобство деплоя через GUI очень быстро затирается неудобством поддержки и автоматизации дальнейшей эксплуатации (тестирования, обновлений, итп), и наоборот. А если вам неудобен 13-дюймовый экран (мне кстати тоже) — купите 15-дюймовый. В долгосрочном плане техника не должна быть основным критерием того, насколько эффективно вы будете решать проблемы клиентов / работодателя.
vladkorotnev
20.03.2019 11:3813" неудобно для консоли? Вы Gitkraken через elinks открыть пытаетесь что ли?
На печально известном 7-дюймовом EEE PC 701 как раз наоборот в чисто консольном режиме только и было можно работать, иначе слишком мало места получалось.
И причём тут гитлаб, который к командам консоли вообще никаким местом не связан?
roscomtheend
20.03.2019 12:20С консольными инструментами не всегда удобно работать. Например, на 13-дюймовом ноутбуке.
Удобная консоль с дозированным выводом менее удобна, чем визуальный интерфейс, где то разъезжается, то не влезает из-за размера? Вот это сюрприз.
Не удивительно что подобный разработчик не осили деплой в копию и переключение рабочего каталога сервера запуском одного скрипта (которое ещё и прозрачно для пользователя). Мышкой тыкать, конечно, удобнее (с возможностью что-то забыть или ошибиться).
SerafimArts
19.03.2019 17:46По поводу асинхронности, если не путаю, reactphp.
Лучше всё же AMP или Swoole.
NickyX3
19.03.2019 16:02Вернёмся к тому проекту, где вылетала установка зависимостей. Это был проект, написанный в 2015 году на Laravel 4 с PHP 5.6. Казалось, прошло же всего 4 года, ан-нет — куча deprecation-предупреждений, устаревшие модули, невозможность нормально обновиться до Laravel 5 из-за кучи корневых обновлений движка.
Вот поэтому я не люблю фреймворки и вот это все.
P.S> свой велосипед, написанный еще под 5.3 пережил переезд через 5.6 до 7.2 без deprecation/warningSerafimArts
19.03.2019 17:55+1Laravel 4 тоже полностью совместим с 7.0+. То, что автор поста нашёл какие-то проблемы — это результат создания этих проблем, либо самим автором, либо кем-либо ещё. Да и вообще я могу вспомнить только одну ошибку, связанную с OS библиотеками и версиями языка — это где-то в недрах доктрины switсh + continue использовался.
arkamax
19.03.2019 20:08свой велосипед, написанный еще под 5.3 пережил переезд через 5.6 до 7.2 без deprecation/warning
Так часто бывает, если велосипед писался с умом и пониманием. Вот только это не отменяет проблем, связанных с безопасностью, масштабируемостью, итп — на небольших проектах это не проблема, но как только проект растет, велосипеды начинают падать. Не все, но статистика не в их пользу. P.S. Говорю с позиции «опытного» велосипедиста.
fijj
19.03.2019 16:02Это огромный плюс. У меня всё устроено так, что на сервере параллельно и независимо друг от друга существуют два отдельных сайта — версия для разработчика и production-версия. Представим, что я сделал какие-то изменения в PHP-файлы на сайте для разработки и мне нужно выкатить эти изменения на production. Для этого нужно останавливать сервер или ставить заглушку «извините, тех. работы» и в это время копировать файлы по отдельности из папки developer в папку production. Это вызывает какой-никакой простой и может вылиться в потерю конверсий.
Я прям представил картину, как вы пишите код в «ide» хостинга:), потом руками переносите все измененные файлы на продакшен, предварительно записывая в блокноте измененные файлы, что бы ничего не забыть. Хотя раз вы от php плюетесь, git наверное вам не стоит предлагатьJamesJGoodwin Автор
19.03.2019 16:26Я прям представил картину, как вы пишите код в «ide» хостинга:), потом руками переносите все измененные файлы на продакшен
На самом деле, все примерно так и происходит :)
Я хотел использовать git, но так сложилось, что я немножечко параноик и опасаюсь загружать код в удалённый доступ. Смотрел в сторону GitLab, но он не понравился мне вот совсем. Да и держать 4 разных репозитория на двух машинах тоже может быть затратно.
zzzmmtt
19.03.2019 18:01+2Не гитхабом единым гит жив. Свой реп гита хранить можно где вам удобно, обвешать все шифрованием по желанию и не переживать, что кто-то увидит ваш код.
Zibx
20.03.2019 00:01Коллега! Тоже не люблю давать другим смотреть на свои тайные форичи и проверки на нулл!
edogs
19.03.2019 16:10+1Вы, возможно, правы, и возможно, NodeJS действительно круче.
Но Ваша аргументация против php имеет тот недостаток, что она основывается на поверхностном знании php.
Вы сами об этом пишите в началеВо время написания движка я использовал простейшие техники. Никаких менеджеров пакетов, никакого роутинга.
.
Дальше вот по этому поводу
На самом деле, это не было бы придиркой и я бы не отнёс это к причинам моего ухода от PHP, если бы написанные мной проекты на PHP 7.0.* уже сейчас не вызывали deprecation warning при открытии.
У нас некоторые проекты написанные на php 4.0 (на 4-ке, не на 5, не на 7) до сих пор работают без проблем. Многие (Не все) проблемы с совместимостью в php были вызваны использованием того, чего использовать не стоило. Самый простой пример с magic quotes и global variables — ах они стали deprecated, какой ужас. Но это проблема правильного программирования, а не языка пхп.
Попробуйте взять любое приложение на PHP, написанное во времена активной поддержки первых версий PHP 7.0 и будьте готовы потратить свой вечер на поиск решений проблем, возникших в устаревших модулях PHP
Как мы уже упомянули выше — крайне мало вещей стали deprecated из тех, которые был разумно использовать. Тем не менее для поиска остальных вещей и их исправления — много времени не потребуется, есть анализаторы php проектов указывающих на проблемы и их решения.
Дальше, шаблонизаторы. Не будем трогать аргументацию по поводу «нативный пхп ад», с которой мы не согласны. но это слишком холиварно. Ответим лишь на это
Использовать шаблонизатор. Наиболее удобный вариант, но не в PHP. Просто посмотрите синтаксис, предлагаемый в Twig или Blade с фигурными скобками и процентами.
Во-первых, для php есть смарти. Который до кучи компилирует шаблоны, из-за чего получается отличный симбиоз скорости и удобства (при правильном использовании). И при чем считается почти стандартом, как можно было о нем не знать?
Во-вторых, Вы пожаловавшись на «фигурные скобки и проценты», тут же приводите в качестве эталона пример шаблонизатора с «фигурными скобками и решеткой» #{current_year} — о_О?!
Дальше «NodeJS держит своё приложение в оперативной памяти» и особенно
Представим, что я сделал какие-то изменения в PHP-файлы на сайте для разработки и мне нужно выкатить эти изменения на production. Для этого нужно останавливать сервер или ставить заглушку «извините, тех. работы» и в это время копировать файлы по отдельности из папки developer в папку production
Тут Вы дважды не правы.
Во-первых, так как Вы выкатывали проекты проекты на пхп — так не делает вообще никто. никто не ставит заглушку и не копирует файлы по отдельности, Вы выбрали крайне кривой способ деплоя, а ругаете почему-то за это язык.
Во-вторых, на пхп тоже по сути возможно " in-memory application ", достаточно включить опкэш без проверки таймстампов файлов и вуаля — без принудительного рефреша будет работать тот пхп который закэшировался в памяти, при чем уже из скомпилированного байт-кода.
Дальше по поводу «Кластеризация NodeJS-приложения».
Во-первых в пхп есть варианты ограничений — Вы просто с ними не знакомы, т.е. опять же, проблема не в пхп, проблема в Вашем знании вопроса.
Во-вторых называть это ограничение NodeJS (если оно есть) преимуществом " приложение не может потребить более чем 1,5 гигабайта оперативной памяти. " это что-то из твиттерофилии с его 160 знаками. А если хочется обработать в памяти 2гб данных? Мы же не в нулевых, что бы «1.5гб достаточно для каждого».
В целом как итог.
Мы безусловно не спорим с тем, что NodeJS в чем-то лучше PHP.
Но Ваша критика на 80% проистекает из неглубокого знания пхп и практик работы с ними.
p.s.: Черт, пока писали телегу, сверху уже выразили то же самое, но намного короче «Статья и серии Я не освоил PHP + CI/CD поэтому пересел на ноду»© и «вы пересаживаетесь на новый ЯП не разобравшись с PHP»© Надо обновлять перед отправкой комментов:\JamesJGoodwin Автор
19.03.2019 17:50+1Дело в том, что PHP сам по себе — это не плохой инструмент. Он очень прост на этапе освоения. Его проблема заключается в том, что когда вы начинаете хоть сколь-нибудь углубляться в его познании, вам постоянно приходится устанавливать какие-то вспомогательные инструменты. В итоге проект становится сравним с панельной многоэтажкой с кучей пристроек и хаотично застеклённых/утеплённых балконов, разного цвета и формы кондиционеров и спутниковых тарелок".
анализаторы php проектов указывающих на проблемы и их решения
включить опкэш без проверки таймстампов файлов и вуаля
в пхп есть варианты ограничений — Вы просто с ними не знакомы
Вы просто не можете писать код, потому что будете заняты бесконечным чтением документации, вычитыванием форумов и StackOverflow. Чтобы заставить работать какую-то вещь, нужно сначала поковырять исходники, почитать кучу документации (читайте — перелопатить стог сена в поисках иглы).
В NodeJS вы просто садитесь писать код и пишете его без оглядки, исправляя выявленные проблемы уже на этапе тестирования. И решаете вы их быстро потому, что пишете код с использованием нативных инструментов, которые просто работают.
Но Ваша аргументация против php имеет тот недостаток, что она основывается на поверхностном знании php
Если подытожить, то, в моём случае, это незнание обусловлено не ленью (даже осознавая тот факт, что я ленивый), а нежеланием проводить целые вечера за чтением литературы и в попытках заставить работать то, что должно было бы работать «из коробки», вместо того, чтобы заниматься тем, что действительно интересно — писать код и реализовывать алгоритмы.TheYellingChives
19.03.2019 18:02чтобы заниматься тем, что действительно интересно — писать код и реализовывать алгоритмы.
Дело в том, что если говорить о «писать код и реализовывать алгоритмы», то никаких «надстроек» и «вспомогательных инструментов» для PHP не требуется.JamesJGoodwin Автор
19.03.2019 18:06Ну вы уж что-то совсем утрируете. При написании кода очень часто возникает необходимость что-то установить, но в NodeJS эта необходимость возникает значительно реже. И на PHP чаще всего вы не сможете решить проблему самостоятельно и будете именно вынуждены обратиться к вспомогательным инструментам.
TheYellingChives
19.03.2019 18:29-1При написании кода очень часто возникает необходимость что-то установить
Вы что-то делаете не так.
frostspb
19.03.2019 22:32+2видели ли вы когда-нить папку node_modules? её размер и кол-во файлов? Это вопрос к ТС
zzzmmtt
19.03.2019 18:10Извините, не буду приводить цитаты из вашего комментария, отвечу кратко. Вы IDE пользуетесь при разработке на ноде? Я вот пользуюсь phpstorm, и он из коробки поддерживает и базовый анализ кода, а если поставить плагин(из настроек самого шторма), так ещё и статанализ будет.
Опкеш — не сторонний инструмент, это часть пхп, при этом описана в документации.
Для беспроблемной разработки на php достаточно официальной документации и понимания основ ООП(да и то не обязательно, можно и в процедурном стиле шпарить).JamesJGoodwin Автор
19.03.2019 19:30Ну вот опять. Мне для работы с Node достаточно VS Code без каких-либо плагинов вообще. Для работы с PHP нужно ещё устанавливать целую IDE.
arkamax
19.03.2019 20:13VSCode в среднем не более и не менее IDE, чем PHPStorm. И вообще, не использовать IDE с мало-мальским анализом кода на данный момент (при ее наличии и доступности) в серьезной работе — ИМХО стоит где-то между чрезвычайной самоуверенностью и профессиональным саботажем. Мы не роботы, и делаем ошибки, которые машине легко подсветить, и в результате сделать наш продукт лучше.
zzzmmtt
19.03.2019 23:14Для работы с php не нужно устанавливать целую IDE. Есть же sublime, notepad++, far+colorer… Мой коллега вон пишет на пыхе в vim, при этом в макоси. Но мне лично комфортнее работать в IDE.
SerafimArts
22.03.2019 04:17Ну вот опять. Мне для работы с Node достаточно VS Code без каких-либо плагинов вообще. Для работы с PHP нужно ещё устанавливать целую IDE.
Это предложение звучит как: «Ну вот опять. Мне для написания HTML достаточно блокнота без каких-либо редакторов и интерпретаторов вообще. А для работы с нодой нужно устанавливать целую ноду и vs code».
На такой тезис можно ответить, либо грубо, вроде «вырастешь — поймёшь зачем нужны серверные ЯП (в вашем случае IDE)», либо пройти мимо, заметив, что «это всё не обязательно, только ничего кроме хоумпейджей на голом HTML не запилить».
SerafimArts
19.03.2019 18:21+2В NodeJS вы просто садитесь писать код и пишете его без оглядки, исправляя выявленные проблемы уже на этапе тестирования. И решаете вы их быстро потому, что пишете код с использованием нативных инструментов, которые просто работают.
Это даже не смешно. Нода — эта та платформа, где надо установить гигабайты всякого софта, чтобы просто начать работать, начиная с cygwin и конфигурирования mingw g++/gcc для компиляции какого-нибудь sass, заканчивая установкой тех же самых линтеров и какого-нибудь puppeteer для тестов, а потом резко влетаем в компиляцию ассетов и начинаются конфиги вебпака (потому что стандарт), скрещенные с ужом поверх гулпа (потому что тогда вебпака не было), с инклудами на бауере (ладно, тут я перегибаю, простите), которые через одно место собирают TypeScript (так сейчас модно), вмерживая туда Coffee (так было модно), и параллельно прогоняя остатки JS через babel со stage-0 (ну мы думали эти декораторы зарелизятся...).
Хм, кажется я перечислил дефолтный стек среднестатистического проекта на JS, да?
Нода — это чёртов хаос из конфигов и настроек. На ней невозможно просто так взять и начать писать. Да блин, тот же express поставить надо же… А там зависимости подсасываются, а там какой-нибудь, наверняка, задепрекейченный vanilla stream… И всё заново, начинается скачки по жёсткому захардкоживанию версий в package.json.Ashot
19.03.2019 19:23Ну вы уж совсем утрируете.
чтобы просто начать работать, начиная с cygwin и конфигурирования mingw g++/gcc
Издержки windows – на юникс системах просто ставишь nodeJS и уже можно работать.
Да и когда я в последний раз устанавливал ноду на win, то всё ограничилось запуском установщика.
влетаем в компиляцию ассетов и начинаются конфиги вебпака
А это уже скорее для фронта актуально, на сервере с этим много проще обстоят дела, как минимум можно обходиться без сборщиков и компиляций.
Нода — это чёртов хаос из конфигов и настроек
Но да,
npm install
очень частая команда, но это даже не необходимость а удобство – зачем изобретать велосипеды, если оно уже есть в npm?
В общем, если этим часто пользоваться и привыкнуть, то не так уж всё и плохо.
SerafimArts
19.03.2019 19:44Ну в общем-то да, я утрировал и довольно сильно. С другой стороны по сравнению с PHP, где ничего вообще делать не надо и даже сервер из коробки идёт — оно так и выглядит.
JamesJGoodwin Автор
19.03.2019 19:25Всё бы хорошо, но вы перечислили проблемы работы с frontend. А статья как раз о серверной разработке и никакие SASS и WebPack здесь совершенно ни при чём. Если говорить именно о сервере, то всё предельно просто —
npm i dependency --save
и работаете по документации.
Если говорить о frontend, то здесь уже проблема не самой Node, а того, во что превратили frontend-разработку. Препроцессоры, транспиляторы, сборщики и целая куча фреймворков — всё это напоминает ту самую панельку с кучей пристроек и хаотично утеплённых фасадов.SerafimArts
19.03.2019 19:46Всё бы хорошо, но вы перечислили проблемы работы с frontend. А статья как раз о серверной разработке и никакие SASS и WebPack здесь совершенно ни при чём. Если говорить именно о сервере, то всё предельно просто — npm i dependency --save и работаете по документации.
Согласен, да. Но с другой стороны — это на порядки проще `composer i dependency`?
staticlab
20.03.2019 12:25А статья как раз о серверной разработке и никакие SASS и WebPack здесь совершенно ни при чём
Компиляция шаблонов вполне ложится на сценарий работы WebPack. Вы, внезапно, вместо готового инструмента накостыляли собственный сборщик :)
trawl
20.03.2019 05:23Во-первых, для php есть смарти. Который до кучи компилирует шаблоны, из-за чего получается отличный симбиоз скорости и удобства (при правильном использовании).
Twig
иBlade
тоже компилируют шаблоны. Плюсом они умеют наследование шаблонов из коробки (не знаю, как вSmarty
с этим сейчас, но раньше реализовывалось только расширениями)
Ashot
19.03.2019 17:28+3PHP уже окончательно ушёл в закат и уступил своё место NodeJS
Да никуда PHP не ушёл и никому своё место не уступал – у каждого своя ниша. И долго ещё не уйдёт.
Как уже писали выше, вы не смогли в PHP, но вам зашёл nodeJS. Могу добавить ещё один стандартный комментарий к подобным постам: ЯП/фреймворк/платформа/etc – это инструмент, какие-то инструменты подходят лучше для одних задач, что-то лучше для других задач. В этом свете слова "окончательно ушёл в закат" звучат несколько громко.
А в NodeJS есть свой собственный менеджер пакетов — npm
npm такой же собственный для nodeJS, как и composer для PHP. Оба просто стали стандартным пакетным менеджером для своего языка. npm просто устанавливается сразу с nodeJS.
iiifx
19.03.2019 17:50+3Автор, я даже немножко рад, что вы ушли с PHP. Заранее приготовьте ЯП, в который вы пойдете после очередного разочарования. И да, хреновый с вас программист, вы уж простите за прямоту.
JamesJGoodwin Автор
19.03.2019 17:53-3Я уже присматриваю себе Go :) Возможно, через несколько лет Google приведёт его в порядок (что очень вероятно) и если я поборю нетерпимость к ООП (что находится за рамками возможного) — уйду в Golang.
MikhailMKZ
19.03.2019 18:38если я поборю нетерпимость к ООП
В Go нет ООП в классическом понимании (с наследованием через классы). Там нет классов, только структуры и интерфейсы. Почитайте про подход Favor composition over inheritance, он в JS очень популярен. Ну и хорошее видео для понимания www.youtube.com/watch?v=wfMtDGfHWpA
iiifx
19.03.2019 19:36Я вам настоятельно рекомендую изучить ООП и все современные практики, которые используют его. В нем заключается колоссальная гибкость. Жаль, что вы опубликовали эту статью так и не разобравшись в языке и теперь она будет сбивать с толку других новичков.
arkamax
19.03.2019 20:16+2поборю нетерпимость к ООП
ИМХО стоило бы очень серьезно попробовать. Профессионалу не стоит так резко отзываться о том, что подтвердило свою работоспособность для массы людей и миллиардов кейсов. Неприятие инструмента (даже если не единственного) попросту лишает вас еще одного способа решения клиентских задач, вот и все.
zzzmmtt
19.03.2019 23:15+1Вот тут вы мне сломали мозг. У вас нетерпимость к ООП, но вы пересели на ноду, в которой почти всё — объект, то бишь там волей-неволей будешь применять какие-нибудь ОО паттерны. Немного иначе чем в других ОО-ЯП, но всё же.
JC_IIB
19.03.2019 18:16возможно, через несколько лет Google приведёт его в порядок
А что, по-Вашему, не в порядке с go?JamesJGoodwin Автор
19.03.2019 18:59Очень часто встречаю от Golang программистов возмущения в адрес управления зависимостями. Нет конструкторов, неудобное управление ошибками. Это только то, что смог вспомнить.
andreybotanic
19.03.2019 18:16+2и я сделал выбор в пользу Jade (PugJS). Просто оцените простоту его синтаксиса
Может это со мной что-то не так, но приведенный после этих слов фрагмент кода у меня вызывает отвращение. Это уже не верстка, но еще и не код. Это что-то иное. И даже на таком маленьком фрагменте это выглядит совершенно запутанно.
При этом, столь ненавистный вам Twig довольно гармонично вписывается в HTML, не портя при этом его собственной структурыJamesJGoodwin Автор
19.03.2019 19:13Ну это дело вкуса. Мне нравится, что нет необходимости открытия и закрытия тегов (это решено с помощью табуляции). Классы и идентификаторы как в CSS, а атрибуты указываются в скобках. Это очень минималистичный язык и это его основное преимущество.
marsdenden
20.03.2019 05:13Простота не всегда хорошо. Может наступить момент (и он наступит), когда эта простота не даст реализовать нечто очень нужное. И что тогда — очередной вопль "jade sucks!"?
А вообще — во всем проглядывает юношеский максимализм. Осталось набраться опыта и прийти к пониманию, что и php хорош и нода хороша. Просто для кручения гаек отвертка плохо приспособлена, хотя зачастую и лежит рядом с гаечным ключом. Каждому инструменту свое применение.
ligor
19.03.2019 19:19Зато шаринг хостинги кругом с PHP, а вот с Node нет (хотя может и есть, специально не искал).
marsdenden
20.03.2019 05:16Дык кому охота заморачиваться? Это ж головняки какие будут у саппорта) Я бы не рискнул "даже за сто тыщ мильенов" (с) )))
vasiljok
19.03.2019 20:06Ждем статью — «Как я переписывал поисковик авиабилетов с NodeJS на Python» и конечно потом будет
«Как я переписывал поисковик авиабилетов с Python на GoLang» и на последок
«Как я переписывал поисковик авиабилетов с GoLang на Rust» ))))
AlexTest
19.03.2019 20:53+3В конце 2018 года… заказчик предоставил сервер с 1 ядром и 512 мегабайтами оперативной памяти
Ну я бы с таким «щедрым» заказчиком работать не стал, если ему жалко пару копеек на нормальное железо, на секундочку, аж под целый «поисковик авиабилетов», то вполне логично, что его жаба давила и по оплате работы. В итоге был нанят студент. Так что тут проблема скорее всего в заказчике, а не в авторе статьи, хотя и автору все-таки стоило бы быть немного скромнее, чтобы не демонстрировать публично свою некомпетентность.
Psih
19.03.2019 21:53+2Я конечно извиняюсь, но я могу написать такую статью про любой язык программирования потратив день на его изучение и потом переключившись на любой другой язык — само собой оба языка должны подходить под задачу в целом.
Вы бы хоть кому-то опытному на обзор дали бы прочитать прежде чем публиковать — в данной статье «прекрасно» всё — отсуствие опыта, отсуствие желания учится и разбираться, отсуствие оценки рисков и следование хайпу, самоуверенность, которой даже я позавидую со своими 14 годами в PHP разработке.
zhulan0v
19.03.2019 22:22+3У вас подход какой-то дилетантский, не программисткий. По вашей статье видно, что вы не разобрались с элементарными вещами не только в PHP, но и в разработке в целом. Статья однозначно вредная, особенно для новичков. Пример того, как не нужно делать.
Borro
19.03.2019 22:37+3NPM и Composer.
NPM много крови может попить, когда будет тянуть бинарные пакеты, а ещё может и начать собирать их у вас на виртуалочке.
LTS
Вы правильно написали, что и то и то поддерживается по 3 года и, если заметите, то LTS релизов ровно столько же, сколько у PHP, не LTS версии не используют в более-менее нормальных продашенах, они лишь для того чтобы посмотреть на функционал, пощупать его перед тем как выпустят нормальную LTS.
Шаблонизатор
Нравится вам лаконичный стиль, поискали бы на https://packagist.org/ нужный вам шаблонизатор. Вот 2, которые 1 в 1 как ваш Jade:
"По моим ощущениям" — один из ужасных аргументов на хабре. Далее вы описываете всё время загрузки страницы, вместо сравнения шаблонизаторов.
Вот как выглядит компиляция шаблонов в Twig:
$loader = new \Twig\Loader\FilesystemLoader('/path/to/templates'); $twig = new \Twig\Environment($loader, [ 'cache' => '/path/to/compilation_cache', ]);
Не сложнее чем ваше.
Про подключение JS я так и не понял, но это в вашем проекте всё просто и надо всего 2 файла загрузить сначала. Такую же функцию грабера всех JS файлов и функцию сортировки можно на любом ЯП сделать. Но вообще в фреймворках были средства, которые позволяют правильно подключать JS/CSS файлы.
Деплой
Про деплой — вы всё распаковываете в соседнюю директорию с вашим проектом, меняете конфиг в nginx и делаете его reload. Это один из способов, вообще есть и более правильные, но это тема отдельных статей, и вроде бы, когда-то давно на хабре проскакивали такие.
Оперативная память
С PHP-FPM всё так же просто. Вы ведите сколько памяти занимает 1 PHP-FPM (после нескольких заходов на разные страницы сайта), делите память, которую вам не жалко, на то, сколько занимает 1 процесс и получаете max_children, выше которого процессы размножаться не будут. Кстати, memory_limit и max_execution_time в PHP вам помогут не положить сервер, если вы накосячите в коде с временем выполнения и памятью.
Швейцарский нож
Я пишу разные консольные утилиты на PHP, писал грабберы, которые тоже в несколько потоков могут грабить сайты, асинхронно работать. Хотите Headless Chrome, его тоже можно запустить и управлять через PHP, слава богу API едино и слабо меняется от одного ЯП к другому. Вот вам и nesk/puphpeteer
Асинхронность
Тут, действительно, на JS изначально пишут асинхронно, поэтому у него больше пакетов. Но на PHP, так же есть возможность писать асинхронно. Вот хорошая подборка: https://github.com/elazar/asynchronous-php
Пожелания
Хотите что-то сравнить, разберитесь в каждом инструменте, либо найдите хорошего оппонента, который сможет на ваши выпады найти аргументы. Node.JS не плохой и не хороший, он просто другой с другой парадигмой. А вам желаю не терять огонь, с которым вы берётесь за работу, и больше углубляться в инструменты, которые помогут вам в будущем стать хорошим разработчиком. Читайте больше, ведь написание кода — это меньшая часть времени. Большая часть — это его отладка, изучение новых знаний, освоение новых инструментов и подходов.
zhulan0v
20.03.2019 06:37Про деплой — вы всё распаковываете в соседнюю директорию с вашим проектом, меняете конфиг в nginx и делаете его reload. Это один из способов, вообще есть и более правильные, но это тема отдельных статей, и вроде бы, когда-то давно на хабре проскакивали такие.
Zero downtime deployment:
1. Делаете директорию release-v1, в ней текущий релиз
2. Делаете симлинк current на директорию release-v1
3. Нужно выкатить новый релиз? Ок, делаете директорию release-v2
4. Меняете симлинк current на release-v2
5. Вуаля! Новый релиз задеплоился без остановки работы и троганья nginx.
В случае проблем можно очень легко откатиться на предыдущую версию — просто обновить симлинк =)Borro
20.03.2019 09:32Тогда ещё не забыть почистить opcache. Про него хорошая статья была https://habr.com/ru/company/mailru/blog/310054/
Djeux
20.03.2019 10:21И если используется nginx, то не лишним будет использовать realpath_root, дабы избежать проблем с opcache.
Dromok
20.03.2019 12:22Разберитесь сначала с PHP, а потом уже пишите обличительные статьи. Абсолютно всё что написано в статье связано только с тем, что вы не разобрались «как его готовить». А уж не использовать систему управления версий (кстати, не обязательно git, хотя это и мейнстрим) скатывает вас на уровень самого начинающего джуниора, который только делает первые шаги в программировании.
staticlab
20.03.2019 12:27+1Для ТС просто git == github.
И вообще, некогда изучать готовые инструменты и хорошие практики, нужно говнокодить, да побыстрее!
de1vin
20.03.2019 13:31О том, что от не знания одного языка программирования переходите на другой уже много написали.
Без контроля версий, настроенного деплоя, линтера, фиксера и анализатора могут быть проблемы в не зависимости от языка.
А так же из-за того, что вы никому не показываете свой код. Ревью — такой же инструмент для написания хорошего кода.
evgwed
20.03.2019 13:34Казалось, прошло же всего 4 года, ан-нет — куча deprecation-предупреждений, устаревшие модули, невозможность нормально обновиться до Laravel 5 из-за кучи корневых обновлений движка.
Вы серьезно? Посмотрите в ту же nodeJS, там все еще быстрее устаревает.
Для PHP это большой плюс, что язык обновляется при этом, стараясь не ломать обратную совместимость.SerafimArts
20.03.2019 15:05Вы серьезно? Посмотрите в ту же nodeJS, там все еще быстрее устаревает.
Самое весёлое — это когда ~год назад поломали синтаксис
class A { *async a() { yield x; } }
Заменив его на
class A { async *a() { yield x; } }
У меня тогда пол кода отвалилась после апдейта ноды. И при этом и в документации пустота, и гугл девственно чист.
MeGaPk
Зачем вы пересаживаетесь на новый ЯП не разобравшись с PHP? И после этого пишете статью диплом (с литром воды). Такое ощущение возникло, когда решение проблемы нагугливается легко. Хоть я и любитель в пхп программировании и новичок в JS, но:
php.net/curl_multi_init
callbackhell.com
smarthomeblog
лечится промисами
t_kanstantsin
А ещё есть Promise hell :)
smarthomeblog
Я подозреваю, что количество hell-ов в PHP просто может зашкаливать ;)
Djeux
Потому что php модно закидывать говном ;)
Carduelis
Ну про callbackhell модно было говорить лет 5 назад. Это подмножество лапшевидного кода, который может состоять из простых и вложненных условий `if {} else {}`, которые присущи любому языку. Как и в случае с вложенными условными операторами, callbackhell можно упрощать.
В целом, от статьи действительно сложилось впечатление: не разобрался с ЯП1 перехожу на ЯП2, всем советую.
Но человек учится, делится опытом, комментарии появляются, энтропия растет. Всем хорошо.
JamesJGoodwin Автор
Похоже, что вы совсем не знакомы с async/await :)
Сами http-запросы можно выполнить параллельно, но с данными все равно придётся работать поочерёдно. В Node с помощью Promise.all() можно вызывать асинхронные функции, которые обратятся к кэшу, при необходимости сделают запрос и вернут уже готовый результат целого ряда действий, а не просто массив данных с ответом от удалённого сервера.
akeinhell
похоже вы не знакомы с отладкой и трейсами которые он порождает :-)
Я сам все пишу уже на async/await, но на бою осознать где именно упало не всегда является тривиальной задачей
JamesJGoodwin Автор
Обычно же достаточно завернуть потенциально опасный блок в try catch и в catch сделать console.trace()
jhonyxakep
Особенно когда падает неизвестно где
Suvitruf
Занятно, что вы набросились на человека за то, что он «пересаживается на новый ЯП не разобравшись с PHP», при этом пишете про callbackhell, которого уже много лет как нет в ноде.