Соединение 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, который вы видите в приведенной ниже ошибке, - это то место, откуда я ссылаюсь на JS.

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/"

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

  • Синатра API на ВМ "х" с портом 9292
  • Сервер nginx на виртуальной машине "x", обслуживающий прокси-сервер на порту 80 для API для запросов, поступающих на "api.myapp.com"
  • тот же сервер nginx также обслуживает файл javascript на порту 80 для запросов, поступающих на "xsa.myapp.com"

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

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

* ОБНОВИТЬ *

Ошибка "Отказано в соединении" на самом деле возникает, даже если JS обслуживается локально и работает правильно, поэтому похоже, что эта ошибка - красная сельдь.

1 ответ

Решение

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

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

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

set :bind, '::1'

В частности, вы не должны связываться с 127.0.0.1.

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

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

Другие вопросы по тегам