Назар Мокринский: На хосте у меня nginx может и не на 80-м порте висеть. Это вообще не принципиально. Хорошо, пусть 80-й порт контейнера будет привязан к 8001-му порту хоста.
С вашей конфигурацией X-Forwarded-For у меня выглядит так:
"X-Forwarded-For = {реальный ip}, 172.17.0.1"
Есть ли возможность сделать так, чтобы туда не попадал 172.17.0.1?
Хорошо, чтобы никого не смущать, пусть у меня запросы проксируются на 127.0.0.1:80 (хотя, и с 0.0.0.0:80 все работает - попробуйте).
Да, есть машина-хост (VPS), на ней стоит nginx. Для этого nginx существует конфигурация для домена (назовем его example.com). В этой конфигурации есть строчка "proxy_pass http://127.0.0.1:80" (также, есть строки "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for" и "proxy_set_header X-Real-IP $remote_addr"). Также, на VPS есть docker-контейнер, внутри которого тоже стоит nginx с простейшей конфигурацией, описанной в данном вопросе, и слушает на 80-м порту. 80-й порт хоста (VPS) привязан к 80-му порту контейнера.
Когда пользователь открывает в браузере адрес "example.com", то nginx, который находится внутри docker-контейнера, видит не реальный ip пользователя, а все время "172.17.0.1".
Так я же написал что , _запрос делает клиент_ :) То есть, запрос делается из браузера к VPS, внутри которой крутится Docker. То есть: "клиент в браузере делает запрос" -> "nginx внутри VPS проксирует запрос на порт 0.0.0.0:80 (который, как видно, привязан к 80-му порту контейнера)" -> "nginx внутри контейнера обрабатывает запрос и выдает ответ, указанный в описании".
Подскажите, а что именно при передаче полного конфига затруднит написание unit-тестов и чтение кода? В unit-тестах я очень легко могу мокнуть Config, оставив там только нужные параметры.
samizdam: Дело обстоит не так, что код пишут джуниоры, и он не должен никогда попадать в основную ветку без ревью. Цель - делиться опытом и указывать друг другу на недочеты, если такие будут замечены.
zooks: Честно говоря, не понимаю, про какое (и с какой целью) удаление буковок вы говорите. Основным и единственным "зеркалом" будет https-вариант. Http/2 обратно совместим с http/1.1 - если браузер поддерживает http/2, тогда он использует этот протокол, если не поддерживает - используется http/1.1.
zooks: А чем помешает его включение? Все, что его не поддерживает, будет использовать обычный http, зато нормальные браузеры будут использовать все преимущества.
Илья Ерохин: >> 1) установить таймер - выполнить - посмотреть
>> таймер - подождать или нет - переустановить
>> таймер - выполнить ....
>> 2) все то же самое, только без таймера и
>> ДЛЯ КАЖДОГО ЮЗЕРА ОТДЕЛЬНО. Вы хотя бы начальное
>> представление имеете, как такое делается?
Во-первых, мне кажется, что вы действительно невнимательно читаете документацию к модулю. Потому что в первых же строках там сказано, что ограничение идет не по всем запросам, а в разрезе заданного ключа (IP-адреса, как частный случай). То есть, фактически, ограничение и в варианте №1 может происходить "ДЛЯ КАЖДОГО ЮЗЕРА ОТДЕЛЬНО".
Во-вторых, под логикой я не имею в виду низкоуровневую работу внутри модуля. Я имею в виду общую логику. В обоих случаях второй запрос будет поставлен в очередь, пока исполняется первый. Так? Так. В обоих случаях исполнение второго запроса начнется после того как завершится первый (если первый не длится больше секунды, что вряд ли). Так? Так.
>> Суть в том, что вы пытаетесь нарушить саму
>> асинхронную сущность web
Я не нарушаю асинхронную сущность web. У меня намного более сложный кейс, чем просто "выстраивать абсолютно все запросы в очередь". Просто я попытался не вываливать сюда лишнюю информацию, а поставить вопрос максимально просто, с минимумом условий. Для того, чтобы комментаторы не лезли в ненужные дебри. А если бы мне дали ответ, я бы как-нибудь уж привел его к моему кейсу.
Но вы даже в этом случае умудрились уйти в сторону =)
Илья Ерохин: >> Как я писал выше - это не маленькая поправка,
>> это абсолютно другая логика
Ну, если для вас кейс "выполнить запрос -> подождать N миллисекунд -> выполнить следующий запрос из очереди" это абсолютно другая логика в сравнении с "выполнить запрос -> выполнить следующий запрос из очереди", то спорить тут бесполезно.
>> Затем, что у вас явно какое-то неудачное решение
Пожалуйста, позвольте мне самому решать, удачное у меня решение или нет.
>> Никто такой ерундой до вас не занимался
Если вы считаете сабж ерундой, зачем заходить в него и писать очевидные вещи, не имеющие отношения к сути вопроса? Поверьте, если я спрашиваю про решение с помощью существующих средств, то я уж как-нибудь догадался, что можно написать свой велосипед, и теперь меня интересует возможность избежать этого велосипедостроения. Если вы не знаете решения, лучше просто ничего не отвечать.
Илья Ерохин: >> Вы же описываете абсолютно другой кейс
Ну где же другой кейс? Посмотрите, пожалуйста, внимательно описание модуля ngx_http_limit_req_module. Если я поставлю rate=1r/s, то мое условие уже будет выполняться, только нужна одна маленькая поправка - нужно, чтобы если запрос выполнился менее, чем за секунду, сервер не ждал, а начинал выполнять следующий запрос.
>> Можно, например хеш по (ip+UserAgent+etc..)
Спасибо, я знаю
>> Можете форкнуть этот модуль nginx, и дописать фичу.
>> Или же можете повесить между nginx и php дополнительную прокладку
Оу, оу) Сразу форкать nginx - зачем же так жестоко?) Это понятно, что можно написать все что угодно. Я _уже_ накидал вариант такой "прокладки" на стороне моего backend'a. Но очень не хочется городить огород, т.к. я всегда считал, что каждой задаче свой инструмент. И мне кажется, что обратный прокси-сервер (т.е., nginx) это и есть тот инструмент, прямой задачей которого является управление запросами, прежде, чем они попадут на основной backend-сервер. И по моему скромному мнению, делает подобные вещи он гораздо эффективнее любой прокладки, т.к. заточен под это.
>> Могу кстати написать такую штуку на Ноде или асинхронном
>> Питоне за умеренную плату, если интересно.
Я тоже могу написать такую (и не только такую) штуку за умеренную плату, если интересно =)
Но вопрос стоит именно "как стандартными Linux-инструментами из коробки решить задачу".
Виктор Таран: То, что на Lua можно написать практически все, что угодно, это понятно. Но неужели у такого мощного инструмента как nginx нету решения из коробки для такой простецкой задачки? Или даже не у nginx, а у любого другого стандартного для Linux-сервера инструмента.
Я конечно, извиняюсь, но в вашем случае я посоветую внимательнее читать вопросы, на которые вы отвечаете. В данном случае, я писал, что мне нужно ставить запросы в очередь, а не выкидывать клиента с ошибкой 503. Указанный вами модуль я смотрел, и и он не подошел мне именно по этой причине.
Илья Ерохин: Как "так" не работает веб? Я же в своем вопросе указал на модуль nginx который _уже ставит в очередь запросы_, но только те, что не умещаются в заданный интервал времени. Мне просто нужно немного изменить условия.
IP это просто пример. Можно ведь сделать условие IP + какой-то заголовок для большей уникальности. Так что это не является проблемой.
Зачем это нужно, честно говоря, долго объяснять. А то тема обсуждения может съехать в ненужную сторону.