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 не работает.
- Убрали фронт-энд и использовали
POSTMANдля отправкиPOSTзапроса на мой Django сервер - таймаут на Auth URL .
- Вызвал ту же функцию, используя
Djangoshell- сработало - Скопировал код в отдельный python файл вне Django -- сработало .
Чем он кажется
Когда вызывается функция 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, мы обнаружили следующее:
- Передняя часть отправляет POST-запрос на заднюю часть .
- Бэкэнд затем кодирует данные с помощью закрытого ключа и отправляет их на сторонний сервер
- Поскольку стороннему серверу нужно было подтвердить наше сообщение
jwks, он отправил еще один запрос на URL-адрес нашего промежуточного сервера. - Этот третий запрос не был обработан, так как на сервере был только один поток. Добавление параметра threads в
gunicornпомогло.
gunicorn ripple.wsgi --reload --log-level debug --threads 4