- PVSM.RU - https://www.pvsm.ru -
njs — это JavaScript-интерпретатор в легковесном веб-сервере, с помощью которого можно создавать новые nginx-переменные и обработчики стадий запроса. Чем njs хорош? Чего не умеет? И зачем вообще его сделали? На эти и другие вопросы ответит Дмитрий Волынцев (xeioex [1]), разработчик nginx и основной разработчик интерпретатора njs.
— Первая причина — директива if
. Люди, которые первый раз ее увидели, думают, что можно использовать ее императивно. На самом деле это не так — конфигурация nginx является декларативной. В примере ниже можно подумать, что в ответе будут два header: X-First и X-Second. Но в ответ попадет только второй header, потому что так устроен nginx: если мы напишем две if-директивы, то выберется самая последняя.
location /only-one-if {
set $true 1;
if ($true) {
add_header X-First 1;
}
if ($true) {
add_header X-Second 2;
}
Вторая причина — то, к чему nginx пришел сейчас. Раньше он использовался для кэширования статики и запросов, а также балансировки нагрузки — классический набор прокси. Распространение микросервисов размыло сферу применения nginx. Если раньше настройка конфигураций заканчивалась на паре location на нескольких бэкендах на каких-то языках, то с микросервисной архитектурой у нас появляется больше движущихся частей. Бэкенд превратился в кучу маленьких компонентов. Логику авторизации, например, необходимо дублировать на каждом микросервисе или выносить ее, скажем, на фронтенд. Чтобы реализовать продвинутую авторизацию, встроенных механизмов решения в nginx хватает не всегда.
В-третьих, в nginx многие директивы принимают динамически вычисляемые выражения, например:
proxy cache bypass $cookie_nocache $arg_nocache;
Вы можете сделать конкатенацию переменных друг с другом или с литеральными строками. Но этого недостаточно, и хотелось бы иметь более мощные инструменты, например, для вычисления хэша, для работы с числовыми данными, для приведения к верхнему и нижнему регистру.
Чтобы расширить все узкие места в nginx, нужно либо разработать свой синтаксис, либо использовать что-то готовое. Мы пришли к выводу, что лучше всего взять уже имеющийся скриптовой язык программирования. Таким образом, разработчикам не нужно учить новый язык, что также сэкономит время и понизит порог входа. Мы выбрали JavaScript.
— Мы выбрали JavaScript по нескольким причинам:
— Уже существует готовый сторонний проект OpenResty. Если не вдаваться в подробности, то это, по сути, nginx + Lua, но он имеет архитектуру, которая идет вразрез с nginx. Мы хотели избежать пересечений с этой экосистемой. Кроме того, есть еще несколько причин:
— Мы оценили njs в сравнении с известными движками — V8 и SpiderMonkey. Они неэффективны для задач внутри nginx, потому что заточены под браузеры и очень тяжеловесны, а nginx необходима высокая скорость работы. Кроме того, оба этих движка быстро эволюционируют, их API нестабилен. Наконец, njs может более эффективно встраиваться в nginx:
Количество контекстов, создаваемых в секунду
— На данный момент реализованы практически все основные элементы спецификации ECMAScript 5.1 с некоторым вкраплением элементов спецификаций 6 и 7. То есть стандартные объекты типа Object, Array, String, Number, Date, RegExp, JSON. Полноценно поддерживаются замыкания, анонимные функции, работа с исключениями.
Мы не ставим своей первоочередной целью полное соответствие спецификации языка. Так что на данный момент отсутствует поддержка eval(), и пока что добавлять ее мы не планируем. Зато планируем добавить поддержку ключевых слов const и let, а также стрелочных функций.
Что умеет и чего не умеет njs на данный момент
Важно упомянуть еще кое-что: отсутствие сборки мусора. Большинство современных языков самостоятельно следят за временем жизни объектов. Если объект больше не используется, то он автоматически удаляется. Без этого механизма нельзя обойтись, но обычно для него приходится чем-то жертвовать — работа программы замедляется или вообще приостанавливается. В njs память не освобождается до тех пор, пока объект запроса не будет освобожден.
У этого подхода есть свои плюсы и минусы. Основной недостаток в том, что он не позволяет эффективно работать с длительными запросами. Поэтому в будущем мы планируем добавить сборку мусора как опцию, чтобы включать ее по мере необходимости.
— Перед тем как ответить на этот вопрос, хотел бы еще раз повторить, что основная задача njs — это расширение возможностей по гибкому конфигурированию nginx и решению задач на стороне прокси.
Теперь непосредственно сам вопрос. Что стоит заранее учитывать?
Также мы приглашаем всех профи к подаче своих докладов на ноябрьскую конференцию HighLoad++ 2018 [2], которая пройдет в Сколково 8 и 9 ноября. Если у вас есть уникальный и интересный опыт и вы готовы им поделиться — до 1 сентября регистрируйтесь и заполняйте форму [3].
Если боитесь выступать публично — у нас есть так называемая школа докладчиков [4], где мы бесплатно помогаем прокачивать эти скилы.
Автор: Олег Бунин
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/289773
Ссылки в тексте:
[1] xeioex: https://habr.com/users/xeioex/
[2] HighLoad++ 2018: http://www.highload.ru/moscow/2018
[3] форму: https://conf.ontico.ru/lectures/propose/?conference=hl2018
[4] школа докладчиков: https://habr.com/company/oleg-bunin/blog/345698/
[5] Источник: https://habr.com/post/420465/?utm_source=habrahabr&utm_medium=rss&utm_campaign=420465
Нажмите здесь для печати.