504- Таймаут шлюза только в функции django

У меня есть очень сложная проблема, и моя команда изо всех сил пытается ее решить. Мы сузили круг поиска, но не на 100%.

Введение

Мы пытаемся реализовать LTI в приложении Django с фронтендом Vue. Чтобы получить токен из URL, бэкенд делает POST запрос к URL с данными и должен получить токен или ошибку, если он просрочен или недействителен.

Дизайн


Браузер ---- POST REQUEST --> функция просмотра на Server (Django) --- POST REQUEST --> Auth URL

Проблема


Запрос на пост, который делает Django view, завершается с ошибкой 504 Gateway Timeout. Это может быть нормальным, если серверу требуется много времени. Однако, увеличение времени не помогло, и мы проверили Auth URL с помощью POSTMAN, он работал нормально и не был отключен.

Что я пробовал


Мы решили отладить или диагностировать этот вопрос, почему блок кода работает в функции, когда он вызывается через оболочку, но не работает, когда он вызывается запросом POST не работает.

  1. Убрали фронт-энд и использовали POSTMAN для отправки POST запроса на мой Django сервер - таймаут на Auth URL
  2. .
  3. Вызвал ту же функцию, используя Django shell - сработало
  4. Скопировал код в отдельный python файл вне Django -- сработало
  5. .

Чем он кажется


Когда вызывается функция POST и внутри нее делается другой запрос post, то происходит тайм-аут. Обратите внимание: Если я делаю запрос POST в той же ситуации с недействительными данными (скажем, отсутствующими grant_type), то тайм-аут не происходит.


Кодовый блок


auth_request = {
    "grant_type": "client_credentials",
    "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
    "client_assertion": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlJVbzNJWWlSR0ZDYUhNNEg0S2lid095enAtRU9KWlAweXkwd0g3bk5VOEEifQ.eyJpc3MiOiI2NjkxNmZmYy03YjE5LTQ0MWEtYjE5Zi0yOGQxMzVmYjZjOWYiLCJzdWIiOiI2NjkxNmZmYy03YjE5LTQ0MWEtYjE5Zi0yOGQxMzVmYjZjOWYiLCJhdWQiOiJodHRwczovL2RldmVsb3Blci5ibGFja2JvYXJkLmNvbS9hcGkvdjEvZ2F0ZXdheS9vYXV0aDIvand0dG9rZW4iLCJpYXQiOjE2NTMyODcyNzMsImV4cCI6MTY1MzI4NzMzOCwianRpIjoibHRpLXNlcnZpY2UtdG9rZW4tMDQyZTZhNjctNDA2My00YmQ1LWI2NmQtNTM4YjU2ZTllM2Q1In0.8Jaou965cPTCFv-7yP9iIlH8mMgQjAi0AR2li0KwCcRuHsRZ_1OpbE83bZ06RMXhbjA4crRqTI4zMi8aNfq16Mkg4lXoPj8JiJW7q8b_ZQ1rLZvIojmabehYjpyscHRitFPLibfTYF2mCjUyHqwPgnFRLNrHIVuSvM0BiK56PuYK6SiiSjxu2U3bmJqOHNW2mqx2YYfkaXx2u7ru6CKTiL3KBGzFPYjCUwwWNBdbz4R0g0aHK_l-hhA3oi_pCDZOyqdnyCmGAj5SpZbuZOqrZbQBrqPoEFtXdNDPpHGGwW7IUbbmCtsmE2NqQiYt6snmK-1pbxsLxE0mXrpDqASh4A",
    "scope": "https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly",
}
response = requests.post(
    "https://developer.blackboard.com/api/v1/gateway/oauth2/jwttoken",
    data=auth_request,
)
response = response.json()
print(response)

После нескольких дней попыток разобраться в этом, мы развернули проект с настройками Production и он заработал. После расследования причин, по которым проект не работал на staging, мы обнаружили следующее:

  1. Передняя часть отправляет POST-запрос на заднюю часть
  2. .
  3. Бэкэнд затем кодирует данные с помощью закрытого ключа и отправляет их на сторонний сервер
  4. Поскольку стороннему серверу нужно было подтвердить наше сообщение jwks, он отправил еще один запрос на URL-адрес нашего промежуточного сервера.
  5. Этот третий запрос не был обработан, так как на сервере был только один поток. Добавление параметра threads в gunicorn помогло.
  6. gunicorn ripple.wsgi --reload --log-level debug --threads 4

Вернуться на верх