1. Безопасность. Другой процесс может незаметно начать слушать на этом же порту и получать часть соединений.
2. Потеря соединений при изменении числа рабочих процессов.
Вы смешали действие директив proxy_ignore_headers и proxy_hide_header. Директива proxy_ignore_headers не уберет заголовок из ответа клиенту, а лишь предотвратит его влияние на кэшируемость ответа.
Если вы хотити чтобы заголовок не передавался клиенту, то необходимо использовать директиву proxy_hide_header.
Установка соединения (SYN->ACK->ACK) с передачей cookies для каждого запроса дает лишнюю нагрузку на сервер и на канал. Для одного клиента она не существенна, но когда клиентов тысячи, она внезапно начинает играть свою роль. А если мы вспомним, что внутри у нас plain text, то становится еще грустнее.
Нагрузка от TCP хэндшейка просто смешная по сравнению с дополнительной нагрузкой, которую дает реализация ещё одного пакетного слоя для мультиплексирования и ещё одного flow control внутри соединения. Для работы HTTP/2 требуется больше накладных расходов и больше пересылать TCP-пакетов, а также расходуется больше памяти и больше процессорных ресурсов. А внутри по сути такой же plain text, который также нужно парсить.
Безусловно. Только сами cookies появилсь, чтобы сервер мог хоть как-то хранить на клиенской машине информацию и различать сессии между собой. Исторически, это был именно костыль.
А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?
Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.
Наверное такие решения должны прорабатываться, обсуждаться и приниматься с особой осторожностью, чтобы не сломать то, что работает годами, не сделать хуже. А сейчас мы видим то, что большие корпорации проталкивают свои протоколы в своих корыстных целях, при этом заставляя всех остальных страдать. Как в своё время было с Microsoft и IE, сейчас то же самое происходит, только в руках одной мегакорпорации оказались, как самые популярные браузеры так и самые посещаемые веб-ресурсы, а потому они в результате затачивают веб под себя, наплевав на остальных. Имея при этом большие маркетинговые ресурсы, они всё это подают под соусом улучшений и инноваций, легко одурачивая основную массу, которая плохо себе представляет работу сетевых протоколов и повторяет из статьи в статью одни и те же заблуждения касательно HTTP/1 vs 2.
Учитывая, что все дистрибутивы потихоньку переползают на вейленд — странно писать о том, что он не взлетел.
Не стоит путать легаси с надежным, проверенным временем решением. Должна происходить постепенная эволюция, а не революции с майданами. Когда горячие головы, терзаемые NIH-синдромом без десятков лет опыта за плечами, приходят с лозунгами: «а давайте всё перепишем!» — ничего хорошего на выходе не получается.
Однако, одно соединение на один запрос довольно избыточно.
В чем заключается избыточность?
В чем, по вашему, правильность данного метода?
В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение. Это правильно, это позволяет применять flow control на уровне каждого потока, а также роутить эти запросы независимо друг от друга. Они могут обрабатываться разными серверами, они могут идти разными маршрутами. Всё это позволяет лучше масштабировать нагрузку и лучше справляться с ошибками.
Даже для реализации «сессии» пришлось придумывать костыли.
В чем заключаются костыли? HTTP — это stateless протокол, благодаря этому он очень хорошо масштабируется, с помощью него можно реализовать удобный и красивые RESTfull интерфейсы. Не будь он stateless, костыли бы пришлость расставлять повсюду.
Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
Смешались в кучу кони, люди, мухи, котлеты… Каждый второй сайт уведомляет об использовании cookies согласно новому закону евросоюза. Это не имеет никакого отношения к протоколам, а является законодательным актом.
Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.
Работу с сессиями вероятно можно было бы улучшить, но это никак не связано с количеством TCP соединений, и ни HTTP/2, ни SPDY — вообще ничего в этом отношении не улучшают.
HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса
И это правильно, так и должно быть. А от того ужаса, который вышел в виде SPDY и HTTP/2 ещё долго придется плеваться. И да, в результате в SPDY и HTTP/2 гораздо больше накладных расходов.
Это неправда — Perl отлично умеет обрабатывать ошибки, просто некоторые привыкли писать как модули так и приложения где предпочитают завершать процесс в случае ошибок (djb style).
Я имел в виду как раз ошибки выделения памяти.
Но если уж дошло до нехватки памяти, то вполне логично убить весь процесс — ибо ситуация уже нестабильна, и скорее всего любое другое действие тоже приведет к проблемам (или будет периодически приводить пока система балансирует на границе голодания).
Это логично в рамках одноразового скрипта, но абсолютно неприемлемо для веб-сервера в высоконагруженных системах. В nginx для корректной и максимально гладкой обработки ошибок выделения памяти проделано много работы. Под пиковыми нагрузками система может упереться во что угодно, в том числе в нехватку памяти, дескрипторов, места на жестком диске и при этом сервер должен продолжать держать нагрузку, завершая с ошибкой лишь часть запросов, которые превышают возможности системы. Падение в такие момент недопустимо.
Более того, ошибка выделения памяти может быть связана не с нехваткой памяти, а с ошибкой в коде или недостаточно качественной фильтрацией данных от пользователя. Как результат какой-то HTTP-запрос может приводить к попытке выделить гигантский объем памяти и это не должно ронять целиком сервер, а завершать ошибкой только один конкретный запрос.
В конфигурации nginx все переменные работают и устанавливаются в рамках обработки запроса, а не при чтении конфигурации. Переменных на уровне конфигурации нет, она читается единожды на старте. И в этом смысле вообще никакой «асинхронный процессинг конфига» не требуется.
Я вовсе не противник njs, но пока что он не предоставляет принципиальных преимуществ перед perl-модулем.
Принципиальное приемущество в том, что njs — это решение пригодное для использования в продакшене под высокой нагрузкой, а Perl — нет. Когда интерпретатор Perl-а не может выделить себе память, он убивает весь nginx, поэтому использовать его можно только на свой страх и риск, в надежде, что памяти всегда хватит, особенно под высокой нагрузкой.
Работа с файлами, базами, сетью на уровне конфига не предполагается.
Это не так. Работа с файлами уже возможна, а с сетью возможна через подзапросы, но в дальнейшем планируются и другие возможности.
Но мой комментарий про неполноценность встраиваемости перла относился скорее к тому, что Perl не умеет нормально обрабатывать ошибки и при любом удобном случае просто завершает весь процесс, что неприемлемо в рамках асинхронного сервера, обрабатывающего тысячи запросов.
Perl невозможно было полноценно встроить, поэтому он всегда был в состоянии экспериментального и не развивался. С JS-модулем совсем другая история, это уже полноценный скриптиг с растущими от релиза к релизу возможностями.
Довольно странное решение, учитывая, что autoindex в nginx может выдавать данные в формате JSON или XML. Чтобы затем получить из этого красивую страничку, нужен либо xslt на стороне сервера, либо тот же JavaScript на стороне клиента.
По умолчанию он был выключен только относительно недавно, в последних версиях. До этого был по умолчанию включен. А ещё многие начитавшись всяких статеек любили добавлять accept_mutex on.
Собственно одной из причин его выключить было, что нам надоели горе-бенчмаркеры, которые запускают nginx и после запуска, без нагрузки рабочие процессы отключают нотификацию о новых соединениях и уходят спать на accept_mutex_delay. После чего бенчмаркер запускает свой славный микробенчмарк и все соединения ловятся одним рабочим процессом, поскольку другие отключили нотификацию.
Почему один процесс NGINX берёт на себя всю работу?
Потому что accept_mutex включен. Выключите и будет счастье.
В случае epoll-and-accept алгоритм другой: Linux, кажется, выбирает процесс, который был добавлен в очередь ожидания новых соединений последним, т.е. LIFO.
AFAIK, с флагом EPOLLEXCLUSIVE это не так и ждуны добавляются в конец очереди.
2. Потеря соединений при изменении числа рабочих процессов.
proxy_ignore_headersиproxy_hide_header. Директиваproxy_ignore_headersне уберет заголовок из ответа клиенту, а лишь предотвратит его влияние на кэшируемость ответа.Если вы хотити чтобы заголовок не передавался клиенту, то необходимо использовать директиву
proxy_hide_header.А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?
Наверное такие решения должны прорабатываться, обсуждаться и приниматься с особой осторожностью, чтобы не сломать то, что работает годами, не сделать хуже. А сейчас мы видим то, что большие корпорации проталкивают свои протоколы в своих корыстных целях, при этом заставляя всех остальных страдать. Как в своё время было с Microsoft и IE, сейчас то же самое происходит, только в руках одной мегакорпорации оказались, как самые популярные браузеры так и самые посещаемые веб-ресурсы, а потому они в результате затачивают веб под себя, наплевав на остальных. Имея при этом большие маркетинговые ресурсы, они всё это подают под соусом улучшений и инноваций, легко одурачивая основную массу, которая плохо себе представляет работу сетевых протоколов и повторяет из статьи в статью одни и те же заблуждения касательно HTTP/1 vs 2.
Не стоит путать легаси с надежным, проверенным временем решением. Должна происходить постепенная эволюция, а не революции с майданами. Когда горячие головы, терзаемые NIH-синдромом без десятков лет опыта за плечами, приходят с лозунгами: «а давайте всё перепишем!» — ничего хорошего на выходе не получается.
Достаточно коротко и ясно происходящее описал легендарный Poul-Henning Kamp в своей заметке: queue.acm.org/detail.cfm?id=2716278
В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение. Это правильно, это позволяет применять flow control на уровне каждого потока, а также роутить эти запросы независимо друг от друга. Они могут обрабатываться разными серверами, они могут идти разными маршрутами. Всё это позволяет лучше масштабировать нагрузку и лучше справляться с ошибками.
В чем заключаются костыли? HTTP — это stateless протокол, благодаря этому он очень хорошо масштабируется, с помощью него можно реализовать удобный и красивые RESTfull интерфейсы. Не будь он stateless, костыли бы пришлость расставлять повсюду.
Смешались в кучу кони, люди, мухи, котлеты… Каждый второй сайт уведомляет об использовании cookies согласно новому закону евросоюза. Это не имеет никакого отношения к протоколам, а является законодательным актом.
Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.
Работу с сессиями вероятно можно было бы улучшить, но это никак не связано с количеством TCP соединений, и ни HTTP/2, ни SPDY — вообще ничего в этом отношении не улучшают.
Это логично в рамках одноразового скрипта, но абсолютно неприемлемо для веб-сервера в высоконагруженных системах. В nginx для корректной и максимально гладкой обработки ошибок выделения памяти проделано много работы. Под пиковыми нагрузками система может упереться во что угодно, в том числе в нехватку памяти, дескрипторов, места на жестком диске и при этом сервер должен продолжать держать нагрузку, завершая с ошибкой лишь часть запросов, которые превышают возможности системы. Падение в такие момент недопустимо.
Более того, ошибка выделения памяти может быть связана не с нехваткой памяти, а с ошибкой в коде или недостаточно качественной фильтрацией данных от пользователя. Как результат какой-то HTTP-запрос может приводить к попытке выделить гигантский объем памяти и это не должно ронять целиком сервер, а завершать ошибкой только один конкретный запрос.
Принципиальное приемущество в том, что njs — это решение пригодное для использования в продакшене под высокой нагрузкой, а Perl — нет. Когда интерпретатор Perl-а не может выделить себе память, он убивает весь nginx, поэтому использовать его можно только на свой страх и риск, в надежде, что памяти всегда хватит, особенно под высокой нагрузкой.
Это не так. Работа с файлами уже возможна, а с сетью возможна через подзапросы, но в дальнейшем планируются и другие возможности.
Но мой комментарий про неполноценность встраиваемости перла относился скорее к тому, что Perl не умеет нормально обрабатывать ошибки и при любом удобном случае просто завершает весь процесс, что неприемлемо в рамках асинхронного сервера, обрабатывающего тысячи запросов.
Да.
По умолчанию он был выключен только относительно недавно, в последних версиях. До этого был по умолчанию включен. А ещё многие начитавшись всяких статеек любили добавлять
accept_mutex on.Собственно одной из причин его выключить было, что нам надоели горе-бенчмаркеры, которые запускают nginx и после запуска, без нагрузки рабочие процессы отключают нотификацию о новых соединениях и уходят спать на
accept_mutex_delay. После чего бенчмаркер запускает свой славный микробенчмарк и все соединения ловятся одним рабочим процессом, поскольку другие отключили нотификацию.AFAIK, с флагом EPOLLEXCLUSIVE это не так и ждуны добавляются в конец очереди.