Назад | Перейти на главную страницу

В соединении с nginx отказано при подключении к восходящему потоку

У меня есть сервер, на котором я развернул API (Sinatra). Я запускаю этот API на порт 9292 и запрашиваю к нему прокси.

Мне также нужно развернуть статический файл javascript и его вспомогательные ресурсы. Я делаю это на том же сервере.

Вся приведенная ниже информация анонимна.

Конечная точка доступа к API такова:

server {
    listen 80;
    server_name api.myapp.com;

    location / {
            proxy_pass http://localhost:9292;
    }
}

и конечная точка, из которой я обслуживаю JS:

server {
    listen 80;
    server_name xsa.myapp.com;

    location / {
            root /data/mydir/xsa;
    }
}

Я имею в виду сервер "localhost: 3003", который вы видите в приведенной ниже ошибке.

2018/11/23 23:31:27 [error] 18720#0: *32 connect() failed 
(111: Connection refused) while connecting to upstream, 
client: 255.255.255.7, server: api.myapp.com,
request: "GET /api/v1/sub/sub_ABCXYZ/info?token%3D56f51132-
406b-4e06-a600-7379876446ed HTTP/1.1", upstream:
"http://[::1]:9292/api/v1/sub/sub_ABCXYZ/info?token%3D56f51132
-406b-4e06-a600-7379876446ed", host: "api.myapp.com",
 referrer: "http://xsa.myapp.com/src/selector.html?
mfid=sub_ABCXYZ&location=http://localhost:3003/"

Итак, резюмируем:

Я прекрасно могу просматривать JS в браузере, так что он действительно обслуживается. Именно в динамическом материале, который он делает при создании экземпляра, вызывает ошибку.

Я также вижу, что сервер Sinatra на 9292 действительно получает запрос и возвращает 200. Похоже, что проблема уже после этого. Так что даже не похоже, что в восходящем соединении действительно отказано. Я дважды проверил, что этот ответ является точно таким же ответом, как когда JS обслуживается локально (и работает).

* ОБНОВИТЬ *

Ошибка «соединение отклонено» действительно происходит, даже когда JS обслуживается локально и работает правильно, поэтому похоже, что эта ошибка - отвлекающий маневр.

Вы получаете это сообщение об ошибке, потому что ваше приложение Sinatra не прослушивает IPv6-адрес по умолчанию для localhost, ::1, но вместо этого прослушивает старый адрес IPv4, 127.0.0.1.

Поскольку вы указали, что ваш восходящий поток nginx localhost, nginx сначала пробует IPv6-адрес, но поскольку ваш сервер приложений не прослушивает этот адрес, nginx получает отказ в соединении. Затем он повторно пытается установить соединение по IPv4, что успешно и обслуживает ваше приложение.

Поскольку это приводит к проблемам с производительностью и поскольку IPv6 предпочтительнее устаревшего IPv4, вам следует перенастроить приложение Sinatra для прослушивания IPv6. Например,

set :bind, '::1'

В частности, вам следует не привязать к 127.0.0.1.

Вы также можете просто удалить хост привязки, потому что по умолчанию он будет прослушивать локальный хост IPv6, если вы используете thin (как вы должны в prod) или WEBrick (в dev, если вы забыли установить тонкий gem).

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