Приложение Flask на экземпляре AWS EC2 завершает работу с ошибкой 504.

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

У меня есть приложение Flask, которое работает на AWS-инстансе с изображением Linux. Скрипт – это бот-скрипт на Python, который использует Selenium для выполнения некоторых задач. Я вызываю API через простой POST-запрос. Проблема, с которой я столкнулся, заключается в том, что выполнение завершается через 60 секунд. Тем не менее, мой бот-скрипт успешно выполняется, но задача не выполняется должным образом. Я добавил некоторые операторы печати, и код проходит через них, что заставляет меня предполагать, что сам скрипт Selenium работает нормально.

Теперь конфигурация, которую я использую, включает gunicorn и nginx для запуска моего API на EC2. Конфигурации приведены ниже.

Мой файл конфигурации nginx на EC2:

server {
 listen 80;
  server_name 18.201.215.193;

  location / {
 proxy_pass http://unix:/home/ec2-user/python_script/app.sock;
 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 300s;
 proxy_send_timeout 300s;
 proxy_read_timeout 300s;
 send_timeout 300s;
  }
}

[1]: Мой конфигурационный файл для nginx на EC2.

Мой конфигурационный файл gunicorn выглядит следующим образом:

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=ec2-user
Group=www-data
WorkingDirectory=/home/ec2-user/python_script

ExecStart=/home/ec2-user/.local/bin/gunicorn --workers 5 --bind unix:app.sock --timeout 300 wsgi:app

[Install]
WantedBy=multi-user.target

Я увеличил время ожидания до 300 секунд, но процесс все равно возвращает ошибку через 60 секунд. Код инициализации моего скрипта, который работает на инстансе, приведен ниже:

class Ec2Handler:
def __init__(self, user_creds, invatation_url):
    self.user_creds = user_creds
    self.invatation_url = invatation_url


def api_trigger(self):

    api_url="http://18.201.215.193/run-script"
    payload = {
        'invatation_url': self.invatation_url,
        'user_creds': self.user_creds
    }
    response = requests.post(api_url,json=payload,headers={"Content-Type":"application/json"},timeout=None)
    #response = requests.get(api_url,headers={"Content-Type": "application/json"},timeout=450)
    if response.status_code == 200:
        print('Script executed successfully:', response.json())
    else:
        print('Error executing script:', response)

И это сам бот-скрипт:

@app.route('/run-script', methods=['POST'])
def run_script():
    # Выполните ваш скрипт с предоставленными аргументами

    print('Starting')
    data = request.get_json()
    user_creds = data['user_creds']
    with SB(headless2=True, undetectable=True) as sb:
         print("AS")
       
         print('Ok reached here')
         sb.driver.uc_open_with_reconnect("https://accounts.snapchat.com/accounts/v2/login", 4)
         ...остальной код...
         sb.driver.sleep(4)
         print('OK Reached here')
         print('QUITTING')
         sb.driver.quit()
         return jsonify({'message': 'Script triggered successfully'}), 200
 return jsonify({'message': 'Script triggered successfully'}), 200

В результате моя функция возвращает только это:
Ошибка выполнения скрипта: <Response [504]>

Буду признателен за любые отзывы об этом! Заранее спасибо

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

Для решения проблемы с тайм-аутом и ошибкой 504 при запуске Flask-приложения на AWS EC2 с использованием Gunicorn и Nginx необходимо применить систематический подход, учитывающий несколько ключевых аспектов.

Теория

Ошибка 504 Gateway Timeout обычно возникает, когда прокси-сервер (в данном случае Nginx) не получает ответ от сервера приложений (Gunicorn) в отведенное время. Это может произойти из-за неправильных настроек тайм-аутов, переполненности рабочей нагрузки или задержек в обработке запросов на сервере приложений.

Пример

Ваше текущее окружение настроено так, чтобы давать более длительные тайм-ауты для Nginx и Gunicorn. Однако, несмотря на увеличение тайм-аутов до 300 секунд, проблема сохраняется, что указывает на возможные другие узкие места:

  1. Gunicorn:

    • Конфигурация Gunicorn включает в себя корректное использование --timeout, что должно означать увеличение времени ожидания до 300 секунд для выполнения запроса.
  2. Nginx:

    • В конфигурации Nginx вы также увеличили значения proxy_connect_timeout, proxy_send_timeout, и proxy_read_timeout до 300 секунд. Этого должно быть достаточно для более длительных задач, выполняемых через API.

Применение

Следует провести дополнительные расследования и оптимизации:

  1. Проверка Concurrency:

    • Убедитесь, что количество воркеров в Gunicorn (5 воркеров) соответствует предполагаемой нагрузке. Для скриптов, которые требуют значительного времени выполнения, необходимо удостовериться, что именно количество воркеров соответствует количеству одновременных соединений, которое требуется поддерживать.
  2. Логирование:

    • Используйте более детализированное логирование, как на уровне Nginx, так и Gunicorn, для идентификации потенциальных узких мест или ошибок времени выполнения. Это поможет понять, в какой именно момент возникают тайм-ауты.
  3. Асинхронная обработка:

    • Рассмотрите возможность использования асинхронных инструментов для очень долгих операций. Перенос выполнения задачи в очередь, такое как Redis с Celery, разгрузит основной процесс и позволит вам немедленно отвечать пользователю через HTTP.
  4. Оптимизация скрипта:

    • Проверьте ваш скрипт на предмет неэффективностей или точек, которые могут привести к задержкам в выполнении. Инструментирование и профилирование кода может помочь в этом.

Таким образом, чтобы устранить ошибку 504, необходимо не только рассмотреть параметры конфигурации сервера, но и проверить фоновые процессы скрипта, в том числе серверную архитектуру и особенности выполнения кода.

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

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