Gunicorn [CRITICAL] WORKER TIMEOUT, При перенаправлении

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

Я делаю социальную систему входа в Nginx + gunicorn + Dango by DRF.

При запросе GET {api-path}/kakao/login с моего сервера возникает ошибка. Мой сервер должен предоставить токен пользователя и перенаправить пользователя.

Вход нового/старого пользователя завершен успешно, но ** страница пользователя не переключается и не получает токен.**

когда я запускаю python manage.py runserver 0.0.0.0:8000, ошибки не возникает, и возвращается нормальное значение токена.

Но Если я использую gunicorn или uwsgi, возникает ошибка.

Как я могу решить эту проблему?

Ниже я кратко описал свои попытки и свой код.

1. Я пытался

https://www.datadoghq.com/blog/nginx-502-bad-gateway-errors-gunicorn/

  • проверьте "Gunicorn не запущен". другие запросы типа {api-path}/admin работают нормально.

  • check "NGINX не может взаимодействовать с Gunicorn" другие запросы типа {api-path}/admin работают нормально.

    .
  • check "Gunicorn is timing out". Когда я запустил python manage.py runserver 0.0.0.0:8000 и попробовал выполнить проблемный запрос, на ответ ушло всего 2 ~ 3 секунды. Поскольку временной лимит gunicorn по умолчанию составляет 30 секунд, я думаю, что причина моей ошибки не связана с таймингом Nginx и таймингом Gunicorn.

  • Я пробовал uwsgi, uwsgi's socket too, но возникла та же ошибка.

  • Я пробовал только gunicorn + Django, но возникла та же ошибка.

  • settings.py ALLOWED_HOSTS = ["*"]

2. мои настройки DNS

DNS -> ec2 load balancer -> ec2 instance (nginx -> gunicorn -> Django)

3. мой журнал

  • журнал гюникорн
[CRITICAL] WORKER TIMEOUT (pid:26573)
[INFO] Worker exiting (pid: 26573)
save! # When user information is saved, this message is output.
  • nginx error.log
2021/08/17 13:14:18 [error] 29691#29691: *120 upstream prematurely closed connection while reading response header from upstream, client: 172.31.33.82, server: {server-name}, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8001/", host: "172.31.6.198:8000"
2021/08/17 13:14:23 [error] 29691#29691: *122 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.13.15, server: {server-name}, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8001/", host: "172.31.6.198:8000"

4. мой код

  • установкаnginx
# django.conf
server {
  listen  8000;

  server_name {server-name};

  location /static {
    root /home/ubuntu/django_api/django;
  }

  location / {
     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_connect_timeout 120; 
     proxy_send_timeout 120;
     proxy_read_timeout 120;
     proxy_buffers 64 16k; # default 8 4k
     proxy_pass http://127.0.0.1:8001;

  }
}
  • настройка грифонов
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/django_api/django
ExecStart=/home/ubuntu/django_api/django/.venv/bin/gunicorn --bind 0.0.0.0:8001 --timeout=60 project.wsgi:application

[Install]
WantedBy=multi-user.target
#urls.py
from django.urls import path, include
from . import views

urlpatterns = [
    path('', views.UserList.as_view()),
    path('current/', views.current_user),

    path('rest-auth/', include('rest_auth.urls')),
    path('rest-auth/registration/', include('rest_auth.registration.urls')),

    path("auth/profile/<int:user_pk>/", views.ProfileAPI.as_view()),
    path("auth/profile/<int:user_pk>/update/", views.ProfileUpdateAPI.as_view()),
    path("auth/profile/<int:id>/delete/", views.ProfileDelteAPI.as_view()),

    path('kakao/login', views.kakao_login, name='kakao_login'),
    path('kakao/callback/', views.kakao_callback, name='kakao_callback'),  
    path('kakao/login/finish/', views.KakaoLogin.as_view(), name='kakao_login_todjango'),
]
# views.py
def kakao_login(request):
    rest_api_key = getattr(settings, 'KAKAO_REST_API_KEY')
    return redirect(
        f"https://kauth.kakao.com/oauth/authorize?client_id={rest_api_key}&redirect_uri={KAKAO_CALLBACK_URI}&response_type=code"
    )


def kakao_callback(request):
    rest_api_key = getattr(settings, 'KAKAO_REST_API_KEY')
    code = request.GET.get("code")
    redirect_uri = KAKAO_CALLBACK_URI
    """
    Access Token Request
    """
    token_req = requests.get(
        f"https://kauth.kakao.com/oauth/token?grant_type=authorization_code&client_id={rest_api_key}&redirect_uri={redirect_uri}&code={code}")
    token_req_json = token_req.json()
    error = token_req_json.get("error")
    if error is not None:
        raise JSONDecodeError(error)
    access_token = token_req_json.get("access_token")
    """
    Email Request
    """
    profile_request = requests.get(
        "https://kapi.kakao.com/v2/user/me", 
        headers=({'Authorization':f'Bearer {access_token}'}))
    profile_json = profile_request.json()
    error = profile_json.get("error")
    if error is not None:
        raise JSONDecodeError(error)
    kakao_account = profile_json.get('kakao_account')
    
    email = kakao_account.get('email')
    """
    Signup or Signin Request
    """
    try:
        user = User.objects.get(email=email)
        
        social_user = SocialAccount.objects.get(user=user)
        if social_user is None:
            return JsonResponse({'err_msg': 'email exists but not social user'}, status=status.HTTP_400_BAD_REQUEST)
        if social_user.provider != 'kakao':
            return JsonResponse({'err_msg': 'no matching social type'}, status=status.HTTP_400_BAD_REQUEST)

        data = {'access_token': access_token, 'code': code}
        accept = requests.post(
            f"{BASE_URL}user/kakao/login/finish/", data=data)
        accept_status = accept.status_code
        if accept_status != 200:
            return JsonResponse({'err_msg': 'failed to signin'}, status=accept_status)
        accept_json = accept.json()
        accept_json.pop('user', None)
        return JsonResponse(accept_json)
    except User.DoesNotExist:

        data = {'access_token': access_token, 'code': code}
        accept = requests.post(
            f"{BASE_URL}user/kakao/login/finish/", data=data)
        accept_status = accept.status_code
        if accept_status != 200:
            return JsonResponse({'err_msg': 'failed to signup'}, status=accept_status)

        accept_json = accept.json()
        accept_json.pop('user', None)
        return JsonResponse(accept_json)


class KakaoLogin(SocialLoginView):
    adapter_class = kakao_view.KakaoOAuth2Adapter
    client_class = OAuth2Client
    callback_url = KAKAO_CALLBACK_URI

5. my env

  • ubuntu 20.4
  • Python 3.8
  • django '3.2.6'
  • gunicorn (версия 20.1.0)
  • nginx версия: nginx/1.14.0 (Ubuntu)
Вернуться на верх