Pull to refresh

Comments 119

> Мы запускали PHP в php-fpm и на апаче, запускали Python через uWSGI, иногда жили с Apache, а если нам нужны были разные версии PHP — жили с зоопарком из FPM-ов

И, по-моему, вполне не плохая такая жизнь была. Лично я не страдал.
Я тоже не понял суть проблемы. Конфиги в разных файлах были или что?

Так они и щас будут в разных судя по всему. Тогда как Passenger умел единый конфиг с момента появления.

Я бы поспорил. Как раз сейчас тренд писать приложения на одном языке.
Документация ни к черту. Я например не могу найти где про «в рамках одного app-сервера можно держать разные версии PHP»
хмм, ну не знаю.
из того что мы видим в целом (не привязываясь только к веб-аппликейшнам) «продукт» становится очень разрозненным, причем это происходит по всем направлениям.
больше нет одного мониторинга для всего (смотрим за инфраструктрой в прометеусе, за приложением в ньюрелике, шлем логи в ELK итп), больше нет «одного приложения», есть несколько проектов с нодой и руби на фронте, с питоном в бэкэнде, делают это разные команды с разными компетенциями и так далее.
как раньше собирали софт и кубиков/библиотек, так теперь кубики это «компентенции» групп разработчиков — ктото специализируется на фронте и они же пишут часть бэкэнда на ноде, _очень_ часто при этом может быть вообще какой-то старый кусок на PHP, ну и так далее.
также с базами, при всей противоречивости монги, очень часто видим монгу на фронте, постгрес и кликхаус на аналитике.
да, это сложнее и я до конца это не одобряю, но такой мир (имхо, могу быть и не прав ;) )
отвечу вам, вы действительно не правы.
Каждому сервису свой конфиг и своя платформа… зоопарки обычно живут на стейджах, и дев серверах, когда тот жже кликхаус живет рядом с постгресом нодой и фпм… в большом энтерпрайзе много автоматики, много серверов и сервера распределяются по ролям…

Насколько я понимаю, фишка не в том, чтобы держать на одном сервере и руби, и питон, и пхп — для этого есть контейнеры, виртуалки и так далее. А в том, что одна и та же софтина используется как app server для всего зоопарка языков/сервисов. Чем меньше разного софта — тем легче всё это сопровождать, обновлять и чинить когда сломается.

У нас, к примеру, один проект нельзя перевести на php 7, поэтому он живет на 5.6. А рядом живет проект на php 7.

У более-менее крупных проектов все переписывается на микросервисы, а микросервисы могут быть на разных языках.
Я бы точнее сказал, что в контейнере у вас приложение на 5.6, а не микросервис.
Или вот чем отличается go application от просто binary application…
Для интеграции с go предоставляется замена стандартной net/http либе
Верно. Мы не проксируем на Go, мы заменяем его сетевую либу.
А где об этом почитать можно?

Пока что тут: http://unit.nginx.org/docs-installation.html#building-the-go-applications
Документация будет улучшаться. Это пока первые эскизы.


Если кратко, то вся модификация Go приложений для запуска в Unit сводится к добавлению модуля unit:


import {
    "fmt"
    "net/http"
    "unit"
}

и замене обработчика
http.ListenAndServe(":8080", nil)
на
unit.ListenAndServe(":8080", nil)
при этом заданный порт имеет значение только при запуске вне юнита, в этом случае происходит фоллбек в http.ListenAndServe(). Юнит указанный порт игнорирует, слушающий сокет уже конфигурируется в самом юните.

Не совсем понял как разрабатывать? Ведь на dev машине не будет пакета «unit».
Почему не будет? Кто помешает поставить его из репозитория, так же как и Go?

Как минимум, своеобразный import path: все известные мне тулзы, включая саму утилиту go, будут считать, что это пакет стандартной библиотеки. Если вы сделаете путь вроде github.com/nginx/go-unit, и положите пакет туда, вы избавите людей от большой головной боли.

Сейчас Go планируется ставить из пакета, версия которого будет всегда совпадать с версией юнита в репозитории. В случае github разработчик будет вынужден сам следить за тем, чтобы клонировался нужный бранч. Неужели так удобнее? Пакетный менеджер придумали специально чтобы этим не заниматься.

Почти все разработчики на языках, отличных от C и С++, не ставят библиотеки для этих языков yum'ом и apt'ом, а используют средства экосистемы языка: gem, pip, crate, etc. Пакетный менеджер системы придумали совсем не для них, и пользоваться им, чтобы ставить, например, gem'ы, дико неудобно.
В Go для этого используются go get и различные менеджеры зависимостей, которые постепенно вытесняются официальным экспериментом: https://github.com/golang/dep. Если у вас будут SemVer-теги для релизов, то будет ещё приятнее.
Отвечая на вопрос – да, пользоваться инструментом, привычным разработчику на языке, удобнее, чем инструментом, грубо говоря, системного администратора. Тут между вами, разработчиками unit'а, и разработчиками на Go пропасть, которую надо преодолеть.

К слову, разработчики на Go редко ставят Go из репозитория системы. Во-первых, он почти всегда там старый. Во-вторых, я ещё должен найти packager'а, которой понял концепцию GOPATH и GOROOT, и не применил какие-то патчи, которые, как ему кажется, делают что-то лучше и Fedora/Debian/Ubuntu-way, но всё ломают для разработчиков. Последний раз смотрел года два назад – было дно.

правильно я понимаю, что unit.ListenAndServe(":8080", nil) делает сокет для unit, а если его нет поднимает http на 8080?
Сокеты это лишние накладные расходы. Там все сложнее. Он общается с процессами юнита посредством нашего RPC, который построен на разделяемой памяти. Модуль как раз подсоединяет приложение на Go к этому RPC, когда запускается процессом юнита.
Спасибо, месяцами ранее рыл инет на тему подобного интеграции чтоб без накладных расходов проксирования, находил только какие-то недоделки, и вот оно!
Особенно учитывая вот эти тесты: https://gist.github.com/hgfischer/7965620 это может быть довольно насущно.
Вы уже сравнивали производительность?
На данный момент там много всякого дебага и часть кода написана в стиле «proof-of-concept». Сейчас сравнивать производительность бессмысленно. Но архитектура спроектирована так, чтобы добавлять минимум накладных расходов и выжать максимум из приложений. К моменту выпуска первой стабильной версии доведем до ума и можно будет тестировать.
Для интеграции с go предоставляется замена стандартной net/http либе
Под Java подразумевается весь JVM или только конкретно конкретно JAVA? То есть будет ли поддержка, языков на базе JVM?

Java — один из самых сложных стеков в плане интеграции. Пока только исследуем возможности. В начале скорее всего появится что-то из наиболее востребованных решений.

они же всё равно для запуска JVM используют — какая разница кто её запустит?

ASP.NET Core не планируется в виде нативного модуля?
Сегодня на конференции подходил человек из Microsoft, то же самое спрашивал. Возможно, надо смотреть.

Я не думаю что это слишком сложно, если забить на reload.

Аргументация у минусующего есть?
Я примерно представляю как это устроено, в ASP.NET Core 2.0 поддержку наследования доменных сокетов из родительского процесса (например для systemd activation) починил я например: #1922, #1930.

а почему все вешается на tcp сокеты? Как быть тем, кто очень хочет экономить и использовать unix сокеты?

Ни кто не мешает указать вместо ip-адреса unix-сокет. =)
UFO just landed and posted this here
Я может не понял сути.
А где этот unit возьмет какие нибудь специфические модули для того же php?
Или весь pecl будет поддерживаться?

Там же, где и php-fpm или mod_php. Мы собираем свой собственный SAPI модуль для php-интерпретатора и линкуемся с libphp.

Так php-fpm собираю я лично под свои задачи.
А unit собираете вы. Откуда вам знать что именно мне нужно?

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

Спасибо, стало понятнее.
Еще вопрос. Посмотрел пакет собранный под убунту. Там у php.unit.so зависимость libphp7.so.
А как происходит работа с php5?

Нужно собрать php5.unit.so с зависимостью от libphp5.so. Пакеты в наших репозиториях идут только с тем, что доступно в системных репозиториях.

Большое спасибо!

Я, например, вот так у себя в gentoo собираю три разных php-модуля для юнита:


$ ./configure php --module=php56 --config=/usr/lib64/php5.6/bin/php-config --lib-path=/usr/lib64/php5.6/lib64

$ ./configure php --module=php70 --config=/usr/lib64/php7.0/bin/php-config --lib-path=/usr/lib64/php7.0/lib64

$ ./configure php --module=php71 --config=/usr/lib64/php7.1/bin/php-config --lib-path=/usr/lib64/php7.1/lib64```
Хотя бы вот это бы в документацию. Потому что она не даёт «всей панорамы». А это вообще самое важное в документации

Под gentoo ручками что-то собирать?! o_O
Я удивлён.
Эххх, кто бы меня пнул в субботу/воскресенье — надо обязательно ебилд нарисовать, ибо хочется, однако! Благо есть куда запихать вместо всяких php-fpm-ов и прочих разных обёрток...

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

ebuild конечно хорошо было бы сделать и положить в репозиторий дженту.

Да я в своей практике частенько сталкивался с тем, что emerge <> быстре и дешевле обходились, нежели ручками собирать, особенно вот в таких хитрых конфигурациях, когда надо несколько вариантов собирать.
Ну и эксплуатация — профдеформация, однако! Низзя засорять систему! :)

> мы все задавались вопросом: когда же на nginx можно будет запускать приложения
Нет, не задавались. Наоборот, радовались, что Nginx такой клёвый и лёгкий и не берёт на себя все задачи в мире, в отличие от Apache.

А с появлением докера запуск разных версий пхп и смешивание технологий в одном проекте чрезвычайно упростились. Зачем это всё сейчас в Nginx — непонятно.
Nginx такой клёвый и лёгкий

Unit ещё более клёвый и лёгкий. ;)

Как я понимаю, ничего не мешает, так же продолжать пользоваться nginx. Unit это отдельный продукт.

Так оно и не в Nginx — по сути они сделали свой *-FPM и с Nginx у них общего только компания-разработчик. Даже конфиг в виде, не самого удобного для этого дела, JSON.
Я понимаю еслиб они это реализовали в виде динамических модулей к Nginx — подгрузил в конфиге и все работает, правда стабильность самого веб-сервера будет уже под вопросом… :)

Объясните простыми словами зачем это нужно и какие проблемы решает?

В статье же расписано. Упрощают работу с зоопарком языков )

Или зоопарком версий — кому что.

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

docker в продакшене не всегда удачный выбор. иногда слишком «дорого»

Хм… в чем именно дорого, не подскажите? Если использовать его без изоляции по сети и использовать только хостовые volume, то оверхед должен быть минимальный, если верить исследователям percona.


Если вы не про производительность, то тем более странно. Вряд ли удобнее будет через nginx хостить кучу разных версий python проектов, чем просто docker контейнеры.

гораздо удобнее и дешевле в плане обслуживания и администрирования вместо докер использовать виртуализацию VMWare и нарезать маленькие виртуалки в ней, а уже там обычный app и если раньше это были скрипты ansible по накатке nginx+uwsgi то скоро это будет обычный процесс установки Application сервера, накатывание готовой конфигурации с минимум динамичных параметров и деплой кодовой базы.
  1. Виртуализация VMWare как бы платная
  2. Виртуалки — это лишний оверхед. К тому же, очень большое количество используемых серверов уже виртуалки. Виртуалки в виртуалках — очень странно.
  3. Не понимаю, чем это будет отличатся от установки docker демона и накатывания готовой конфигурации? Проблема будет лишь в том, что, если вам нужно будет добавить какие-то дополнительные либы к python, то вы будете это делать собирая свой модуль к application серверу, если я правильно понял. Сейчас такой возможности нет.

Ну и + как вот тут отметили, реальная пользая такой штуки — систематизация. Как бы, через docker можно сделать так же, только вот плюшек больше. Включая запуск разных OS, окружений и прочего для проекта. Например, как при помощи nginx application можно будет запустить проекты, которые требует разные версии одной библиотеки?

Например, как при помощи nginx application можно будет запустить проекты, которые требует разные версии одной библиотеки?
В статье выше люди запускают две разных версии PHP, каждая использует свою собственную libphp.so (которые в свою очередь могли быть собраны со своими зависимостями). Я запускал одновременно приложения на 3-х разных версиях PHP, 2-х версиях Python и Go. Вообще это ни чем не ограничено.

Магия и секретные технологии. =)

Возможно я плохо читаю.
Подскажите, пожалуйста, как тогда указать разные версии интерпретаторов для python? Мне же их все равно нужно будет собирать и подсовывать application, или я не прав?


Так же, libphp.so это отлично, а подменить, скажем, системную библиотеку, как я понимаю, не получится. Хотя это уж совсем редкий случай.

Application на python — это собственно сам набор python скриптов, их собирать не надо, они компилируются в опкод самим cpython. Для запуска ваших .py скриптов с нужной версией cpython необходимы лишь соответствующие модули для юнита собранные с соответствующими версиями cpython. Пакеты с модулями юнита можно установить из репозитория, либо собрать самостоятельно.

Во многих дистрибутивах сейчас как минимум две версии cpython, ветки 2 и ветки 3. Соответственно и пакеты для них мы будем собирать сами, либо это будут делать майнтейнеры дистрибутива.

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

Простите, что вас отвлекаю, но вы немного не поняли мой вопрос. Как мне, например, использовать virtualenv в связке с nginx unit? Я просто просмотрел доку и не нашел ответа :(

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

*спасибо большое за ответ :)

  1. Есть почти бесплатный RHEV, есть бесплатный KVM и OpenNebula
  2. Какой оверхед? Где? Виртуалки в виртуалках? Я о таком не говорил.
  3. docker это отдельный контейнер со своими проблемами. Виртуалка более надежна. И как раз docker более похож на виртуалку в виртуалке, если виртуализация уже есть.
  1. Вот я не из большой компании, у меня почти все сервера vps. Какую технологию мне тут применить?
  2. Если вам не нравится docker, то почему бы не попробовать systemd-nspawn? Контейнеризация не виртуализация со своими проблемами, ну так их и в случае виртуалочек полно. Вот VMWare все еще не поддерживает нормально ядро Linux 4+ (по заверениям хостинга, с которым сотрудничают наши заказчики), как быть?
Я говорю с позиции построения больших, распределенных систем. В случае веб сервиса на 4 сервера — тут можно и без докеров вообще в продакшене, а вот тест организовать на докерах. Я боюсь переводить продакшен на докеры (60+ контейнеров) без отдельного штата администраторов и продуманного мониторинга. А еще лучше написать автоматизированного администратора (была на highload компания, которая написала свою тулзу для выполнения рутинных администраторских задач, monkey что-то там).
Я правильно понимаю, что это просто прослойка для нативного запуска разных интерпретаторов с плюшками в виде dynamic config и т.п.?
И основное назначение сия творения — различные сервера приложений (именно где много проектов) на хостингах/девелопер серверах. Проблему наличия зоопарка интерпретаторов оно не решает, но пытается систематизировать и сделать конфигурабельным. так?

Пример с битриксом. Статику отдает nginx, редиректы в nginx. unit заменил только fpm.
Есть какие-то плюсы на серваках под 1 проект с 1 языком? Тот же битрикс, чтоб его.

Приблизительно. Я лишь добавлю, что предполагается удобное и единообразное конфигурирование, так что будет проще использовать и без зоопарка, для своего личного блога, например.

Обучить статике и редиректам — вопрос времени.
Единственный момент, пакеты для CentOS 7 и Ubuntu 16.04 доступны в mainline репозиториях, а не stable.
uWSGI, просто к слову, умеет и Python, и PHP, и Ruby, и v8, и много чего ещё…
uWSGI, просто к слову, умеет и ...

И я об этом же подумал. uWSGI прекрасно справляется с зоопарком разных языков, virtualenv-ов, настроек и прочего. К тому же имеет кучу очень полезных фич, типа кеширование, роуты, emperor, webdav, cheaper_busyness, статистика, слежение за памятью воркеров, логирование куда угодно и в каком угодно виде и т.д. Надеюсь что в unit реализуют хоть часть всех этих вкусностей.
В любом случае, удачи проекту. Будем следить за его развитием.

Что-то не осознал, как компилируемые ЯП интегрируются. Связь через сокеты? Не вкомпиливается же оно в воркеры этого юнита.
UFO just landed and posted this here
Это не CGI запускалка. У нас собственный SAPI модуль для php по типу как php-fpm, так что потенциально всё должно работать, включая opcache и кэш соединений. Сейчас opcache уникален для каждого процесса, позже научим юнит разделяемому между процессами кэшу.

По поводу бенчмарков ответил выше.

Вроде, становится яснее: приложение общается с юнитом через память и сисколы для синхронизации. А как оно всё дальше большому энжинксу улетает, уже по сети? Если да, то правильно ли я понял, что nginx unit это php-fpm плюс systemd / inetd?

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

Поправьте, пожалуйста, конфигурацию пакетных репо. Вот правильные варианты:


CentOS 7:


[unit]
name=unit repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

Ubuntu 16.04:


deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx

Спасибо!

зоопарк версий на одной системе. Устали от многочисленных конфигураций и сборок fpm с разными версиями? Теперь это может быть запущено в пределах одного приложения.

Если вам нужно было три разные версии пхп, то их всё равно надо будет собирать три разные, только вместо fpm sapi какое-то другое. Если вам нужно было чтобы они были по-разному настроены — то опять же эти разные настройки никуда не денутся если заменить fpm на что-то другое. Ну а объединить старт/стоп нескольких демонов в один скрипт никогда никакой проблемы не представляло (если это нужно). Так что совсем непонятно, что именно тут записано в качестве преимущества.

Да, именно. Например, в CentOS мы используем репозиторий Remi, где есть возможность установить разные пакеты с префиксами php54, php56, php70, php71, например, в разные подкаталоги в /opt/remi. И, конечно, запустить их все сразу в виде fpm или как модули к разным апачам.
Никакой мороки, никакой усталости. Обновляется, работает почти само.
Здесь же пока выглядит просто страшновато, уж простите.

Очень интересно.
Сразу ловите feature request — возможность указать workers auto, по аналогии с nginx.
Я бы это даже по дефолту поставил.

Что должен делать auto в данном случае? Сколько процессов запускать?
UFO just landed and posted this here
Auto по умолчанию у нас для router worker threads.

Для приложений число процессов по числу ядер не лучший выбор, потому что приложения могут блокироваться в базе, memcache, и тому подобном. Для них нужно больше процессов. По умолчанию используется один процесс.
UFO just landed and posted this here
Ну это уже от языка/платформы зависит.
Именно. Значения по умолчанию должны быть или удобны для 99% случаев использования, или же неудобными, но безопасными. Если на машине 32 процессора, зачем запускать 32 приложения по умолчанию? Кроме того, некоторые приложения, например, на Go, могут конфликтовать, если запущенно более одной копии. Поэтому для числа рабочих процессов выбран безопасный вариант.
приложения могут блокироваться в базе, memcache, и тому подобном

Могут, а могут и не втыкать. Это уже другая часть работы по оптимизации.
Мне кажется, если база не справляется, снижать нагрузку на неё за счет обрезания ядер — плохая идея.
Если к приложению идет много запросов, нужно повышать мощности, а не сдерживать.


А так получится, что приложение (кроме блокировок в базе), тормозится ещё и на самом сервере.
Я очень часто наблюдал, как на 24-32-56 ядерном сервере на 100% загружены только часть ядер изза настроек воркеров uwsgi.


Простенький пример


Для них нужно больше процессов. По умолчанию используется один процесс.

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


  • приложение работает медленно.
  • повысьте workers.

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

Мне кажется, если база не справляется, снижать нагрузку на неё за счет обрезания ядер — плохая идея.
В том то и дело, что в этом случае число процессов должно быть больше ядер, потому что процессы будут висеть в ожидании ответа от базы.
UFO just landed and posted this here

Добавлю: в том же качестве, что Kotlin на андроиде ;)

не понятно как это поможет питону.
там проблемы обычно с окружением, и решаются они с помощью virtualenv. что может нам предложить unit в этом случае? разные версии питона — ок, а разные окружения на одной версии питона? или все зависимости складывать в одно место?

и, кстати, в случае uwsgi, кроме кучи остальных плюшек там присутствует ряд способов общения между воркерами средствами самого uwsgi без своих велосипедов. в unit это планируется?
Да, планируется поддержка расширение возможностей, как для самих запускаемых языков, так и обвязки в целом. Важность virtualenv прекрасно понимаю, всё будет.
Потестили с го, интересно ) для про не тянет, но для dev сервера вполне приживётся. Зоопарк надоел, а докер слишком тяжёлый
Было бы интересно увидеть на TechEmpower Web Framework Benchmarks.
А почему так долго шли к этому, если не секрет?
Как-то Ruby невзначай в конце добавляют :( Типа возможно и не будет поддерживать? Будет реально очень жаль.
UFO just landed and posted this here

Из описания не увидел — а как-то планируется лимитировать CPU и память на приложение? или они всей толпой будут налегать на всё предоставленное?

Конечно. Это вполне базовая функциональность сервера приложений, которая должна быть.

и как настроить? или это пока в разработке?

Пока никак. Планируется, приоритет высокий.
Я правильно понял или пока нет разделения на route? Т.е. проксируется от корня и все подряд? И Server_name пока нигде не фиксируется. Это будет в дальнейшем?

Понятно что будет работать связка nginx + unit. Но это лишний зоопарк программ
Я правильно понял или пока нет разделения на route? Т.е. проксируется от корня и все подряд? И Server_name пока нигде не фиксируется.
Да.
Это будет в дальнейшем?
Да.
Sign up to leave a comment.