Получение через обратный прокси NGINX работает, но POST возвращает ошибку 502 Bad Gateway.

Вопрос или проблема

Я использую NGINX в качестве обратного прокси и только что развернул новый сервис, написанный на Go.

Сервис имеет две конечные точки

GET /tracking/ping

POST /tracking/customer

В NGINX я использую следующее для проксирования запроса

location /v1/location/ {
    proxy_pass http://path-to-tracking-service:8181/;
}

Когда я выполняю curl по двум конечным точкам, например, следующим образом, я получаю разные результаты.

Конечная точка GET /tracking/ping

curl -X GET https://example.com/v1/location/tracking/ping
"Pong!"

Конечная точка POST /tracking/customer

curl -H "Content-Type: application/json" -d '{"userId":"1234"}'  https://example.com/v1/location/tracking/customer
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.9.12</center>
</body>

Не уверен, почему это происходит. Я проксирую другие сервисы, и POST запросы работают отлично.

Вот nginx.conf

user nginx;
worker_processes 1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    proxy_connect_timeout       600;
proxy_send_timeout          600;
proxy_read_timeout          600;
send_timeout                600;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;

    #server {
        #include /etc/nginx/sites-enabled/*;
    #}

    server {
        listen 80;
        server_name *.example.com;
        #return 301 https://$host$request_uri;
        include /etc/nginx/sites-enabled/*;
    }

    server {

    #listen 80;
    listen 443 ssl;
    server_name *.example.com;

    ssl_certificate           /etc/ssl/example.crt;
    ssl_certificate_key       /etc/ssl/example.key;

    #ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    include /etc/nginx/sites-enabled/*;
    }
}

У меня есть отдельные файлы, которые связаны с /sites-enabled, в которых есть мои объявления proxy_params.

Два из них следующие

location /v1/location/ {
    proxy_pass http://example.com:8181/;
}

location /v1/ {
    proxy_pass http://example.com:8282/;
}

Я могу увидеть, что может возникнуть проблема с путаницей из-за /v1 в обоих прокси, но это работает для конечной точки GET.

ИЗМЕНЕНИЕ

Некоторые люди отметили, что это может вызывать панику, поэтому я проверил журналы Docker для контейнера на Go и получил следующее

location-tracking-staging-1 | 2016-03-14T02:35:33.580963673Z 2016/03/14 02:35:33 http: panic serving 10.7.1.5:35613: no reachable servers
location-tracking-staging-1 | 2016-03-14T02:35:33.581005488Z goroutine 97 [running]:
location-tracking-staging-1 | 2016-03-14T02:35:33.581012905Z net/http.(*conn).serve.func1(0xc820057b00)
location-tracking-staging-1 | 2016-03-14T02:35:33.581017348Z    /usr/local/go/src/net/http/server.go:1389 +0xc1
location-tracking-staging-1 | 2016-03-14T02:35:33.581030498Z panic(0x81e620, 0xc82013c5e0)
location-tracking-staging-1 | 2016-03-14T02:35:33.581034545Z    /usr/local/go/src/runtime/panic.go:426 +0x4e9
location-tracking-staging-1 | 2016-03-14T02:35:33.581038792Z main.RepoCreateVendorLocation(0xc82011ecb8, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
location-tracking-staging-1 | 2016-03-14T02:35:33.581042502Z    /go/src/location-tracking/repo.go:19 +0x178
location-tracking-staging-1 | 2016-03-14T02:35:33.581047145Z main.VendorLocationCreate(0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581050747Z    /go/src/location-tracking/handlers.go:63 +0x47b
location-tracking-staging-1 | 2016-03-14T02:35:33.581054911Z net/http.HandlerFunc.ServeHTTP(0x9965b0, 0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581058786Z    /usr/local/go/src/net/http/server.go:1618 +0x3a
location-tracking-staging-1 | 2016-03-14T02:35:33.581062770Z github.com/gorilla/mux.(*Router).ServeHTTP(0xc820010640, 0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581066604Z    /go/src/github.com/gorilla/mux/mux.go:103 +0x270
location-tracking-staging-1 | 2016-03-14T02:35:33.581070176Z net/http.serverHandler.ServeHTTP(0xc820056300, 0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581073992Z    /usr/local/go/src/net/http/server.go:2081 +0x19e
location-tracking-staging-1 | 2016-03-14T02:35:33.581077629Z net/http.(*conn).serve(0xc820057b00)
location-tracking-staging-1 | 2016-03-14T02:35:33.581081221Z    /usr/local/go/src/net/http/server.go:1472 +0xf2e
location-tracking-staging-1 | 2016-03-14T02:35:33.581084811Z created by net/http.(*Server).Serve
location-tracking-staging-1 | 2016-03-14T02:35:33.581088336Z    /usr/local/go/src/net/http/server.go:2137 +0x44e

У моего NGINX была аналогичная ошибка с POST запросом, в то время как GET запрос работал нормально.

Исправление заключалось в добавлении правила брандмауэра, чтобы разрешить HTTP(S) трафик через брандмауэр хост-машины.

Это может не относиться к вашей конкретной конфигурации.

План

  • Запустить https://gist.github.com/bradmontgomery/2219997 как отдельный процесс на порту 5000

  • Проксировать python http сервер на https, используя POST запросы

Проблема с “502 Bad Gateway” при заданной конфигурации

  • cat /etc/nginx/sites-enabled/example.local

server {
        location /random {
                proxy_pass http://127.0.0.1:5000;
        }
}

root@sf:/var/www# curl -d “foo=bar&bin=baz” http://localhost:5000

<html><body><h1>привет!</h1></body></html>

root@sf:/var/www# curl -d “foo=bar&bin=baz” https://example.local/random

<html>
<head><title>502 Bad Gateway</title></head>
....

Решение

конфигурация nginx после изменений:

server {
...
        error_page 502 =200 @502;

        location /random {
                proxy_pass http://127.0.0.1:5000;
        }


        location @502 {
                root /var/www/sf_random;
                proxy_method GET;
                proxy_pass http://127.0.0.1:5000;
        }
}
  • проверка синтаксиса конфигурации

    nginx -t

  • после успешной проверки

    service nginx restart

И у меня это заработало 🙂

Ответ или решение

Чтобы решить проблему с НГИНКС, где запросы POST возвращают ошибку 502 Bad Gateway, а GET запросы работают корректно, необходимо рассмотреть несколько возможных причин и решения.

Возможные причины и решения

  1. Проблемы с вашим Go-сервисом:

    • Ошибка no reachable servers, указанная в логах вашего контейнера, может указывать на то, что Go-сервис не может обработать входящий запрос. Возможно, проблема в том, что он не может найти или подключиться к необходимым ресурсам (например, к базе данных или стороннему сервису). Проверьте логи вашего Go-сервиса для получения более подробной информации и убедитесь, что все сервисы, от которых ваш Go-сервис зависит, работают исправно.
  2. Некорректная конфигурация NGINX:

    • Убедитесь, что у вас правильно настроена конфигурация для проксирования POST-запросов. Проверьте, что в блоке location у вас достаточно настроек для обработки заголовков и тела запроса. Вы можете добавить следующее:
      location /v1/location/ {
       proxy_pass http://path-to-tracking-service:8181/;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_http_version 1.1;
       proxy_set_header Connection "";
      }
    • Обратите внимание на proxy_http_version 1.1, это может помочь с обработкой соединений при отправке POST-запросов.
  3. Проблемы с CORS (если применимо):

    • Если запрос отправляется с другого домена, убедитесь, что сервер Go позволяет CORS-запросы. Добавьте соответствующие заголовки в ваши HTTP-ответы.
  4. Проблемы с фаерволом:

    • Как упоминали другие пользователи, убедитесь, что ваш фаервол не блокирует трафик на порту 8181 или 8282 для POST-запросов.
  5. Проблемы с маршрутизацией:

    • Возможно, вы столкнулись с конфликтом в маршрутизации из-за пересечения /v1/location/ и /v1/. Убедитесь, что ваши маршруты настроены правильно и не конфликтуют между собой. Вам может понадобиться изменить порядок блоков location в конфигурации NGINX.

Пример исправленной конфигурации

Ваш файл конфигурации NGINX может выглядеть следующим образом:

server {
    listen 443 ssl;
    server_name *.example.com;

    ssl_certificate /etc/ssl/example.crt;
    ssl_certificate_key /etc/ssl/example.key;

    location /v1/location/ {
        proxy_pass http://path-to-tracking-service:8181/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /v1/ {
        proxy_pass http://example.com:8282/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    error_page 502 /custom_502.html;
    location = /custom_502.html {
        root /usr/share/nginx/html;
        internal;
    }
}

# Дополнительные настройки...

Заключение

Следуя этим рекомендациям и проверив вашу конфигурацию и логи, вы сможете устранить проблему с ошибкой 502 для POST-запросов к вашему сервису. Если ошибка продолжает возникать, рекомендуется провести более глубокую отладку и, возможно, использовать инструмент для мониторинга или трассировки соединений, чтобы выявить проблемные места.

Оцените материал
Добавить комментарий

Капча загружается...