У меня возникла странная проблема, из-за которой я не уверен, проблема ли это в конфигурации или ошибка в nginx. Моя установка - это обратный прокси-сервер nginx с внутренними серверами Apache2. Балансировщик нагрузки довольно прост, похож на пример из вики, например упрощенный:
http {
upstream myproject {
server 127.0.0.1:8000;
}
server {
listen 80;
location / {
proxy_pass http://myproject;
}
}
}
Теперь проблема возникает, например, когда я пытаюсь запросить каталог в Apache без косой черты в конце URL-адреса. Например, клиент запрашивает:
http://apache.myserver.com/somedirectory
Apache ответит HTTP 302, чтобы перенаправить клиента на
http://apache.myserver.com/somedirectory/
Обратите внимание, что URL-адрес в конце имеет косую черту, чтобы указать, что это каталог. Также обратите внимание, что Apache «умный», используя имя хоста входящего запроса в заголовке перенаправления. Пока все в порядке. Однако при использовании nginx с балансировкой нагрузки этот 301 отправляется клиенту без преобразования имени восходящего потока nginx обратно на фактический сервер / домен. Таким образом, клиент получит следующее:
GET http://nginx.myserver.com/somedirectory
HTTP 301 Moved Permanently
...
Location: http://myproject:8000/somedirectory/
В myproject
- это имя бэкэнда восходящего потока nginx. Это не реальный хост, который может разрешить клиент. Мне кажется, что вместо этого клиента следовало перенаправить на
http://nginx.myserver.com/somedirectory/
Т.е. имя вышестоящего бэкэнда должно было быть заменено в заголовке ответа. Это ошибка в nginx или я что-то не так делаю?
Оказывается, у nginx довольно много прокси перенаправление варианты решения такого рода проблем. В итоге я использовал что-то вроде этого:
location / {
proxy_pass http://myproject;
proxy_set_header Host myproject;
proxy_redirect http://myproject/ $scheme://$host/;
proxy_redirect http://myproject:8000/ $scheme://$host/;
}
Это в основном заменяет имя восходящего потока на $ host и удаляет порт. В моем случае это сработало, потому что я размещаю nginx на портах по умолчанию для HTTP / HTTPS. Если nginx работает на порту, отличном от порта по умолчанию, необходимо что-то вроде этого:
proxy_redirect http://myproject/ $scheme://$host:$server_port/;
proxy_redirect http://myproject:8000/ $scheme://$host:$server_port/;
Попробуйте использовать server_name_in_redirect как это:
server_name_in_redirect off;
Если это не сработает, возможно, вам придется что-то делать с proxy_redirect, хотя похоже, что ваш бэкэнд ведет себя правильно.