Django, Apache2 и Mod_WSGI обслуживают данные медленнее, чем факсимильный аппарат

У меня есть очень простой экземпляр Django, установленный на RPi model 3. Важно, так как это действительно может быть проблемой.

Я использую Django 3.2, Python 3.7, Mod_WSGI, скомпилированный из исходников под эту версию python и Apache2, установленный через менеджер пакетов (apt install apache2). Будучи незнакомым с back-end стороной вещей в плане Python и WSGI, я подозреваю, что возможно проблема в моей настройке... но я отвлекаюсь.

Mod_WSGI установлен в режиме демона:

LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so
WSGIScriptAlias / /home/pi/steve/steve/steve/wsgi.py
WSGIProcessGroup steve
WSGIDaemonProcess steve python-home=/home/pi/steve/env python-path=/home/pi/steve processes=2 threads=15
#WSGIPythonHome /home/pi/steve/env
#WSGIPythonPath /home/pi/steve
LogLevel debug
<VirtualHost *:80>
...

Django собирает данные из базы данных PSQL, упорядочивает их и обслуживает с помощью return JsonResponse(JSONDataSorted, safe=False)

На данный момент все, что я предоставляю, это необработанный JSON. В нем всего 700 строк в формате:

[{"T": "Sun Aug 15 21:51:35 2021", "C": 17.0, "RH": 81.5},...]

Все работает полностью так, как ожидалось, но это ОЧЕНЬ медленно. Если проверить время запроса, то 65 мс тратится на подключение, 59,29 секунды на ожидание и 15 мс на получение. Если я возвращаю только одну строку, время уменьшается до 30 секунд ожидания. При выполнении запросов на родном PSQL с включенным \timing результаты возвращаются за 2-3 секунды. Запуск запроса из оболочки Django аналогично дает быстрый запрос. Мое представление для справки:

def last_12_hours(request):
    JSONData = []
    time_frame = datetime.datetime.now() - datetime.timedelta(hours=12) #import datetime
    AtmosphericObjects = Atmospheric.objects.filter(time__gt=time_frame).order_by('-time').all()
    for row in AtmosphericObjects:
        JSONData.append({
            "T": (row.pk).strftime("%c"), 
            "C": (float(row.temperature)), 
            "RH": (float(row.humidity))
            })
        JSONDataSorted = sorted(JSONData, key=lambda x: datetime.datetime.strptime(x['T'], '%c'))
    return JsonResponse(JSONDataSorted, safe=False)

Я установил для журналов apache режим отладки и проверил файл errors.log. Вот журнал сразу после запуска службы apache:

Я заметил, что 'mod_wsgi' импортируется много раз. Количество порождаемых процессов кажется неразумным для моего приложения, но все работало так же медленно, когда я опустил threads=2 processes=15.

Проверяя error.log после запроса страницы, я получаю эту строку, которая выглядит нормально:

[Mon Aug 16 12:59:55.425775 2021] [wsgi:info] [pid 20923:tid 1872253984] [remote 10.0.0.10:50953] mod_wsgi (pid=20923, process='steve', application=''): Loading Python script file '/home/pi/steve/steve/steve/wsgi.py'.

Если я проверяю htop во время такого запроса, apache использует 100% ядра процессора за то время, пока данные не появятся в браузере.

Может ли это быть просто результатом аппаратного обеспечения? С чего мне начать? В каждом ответе предлагается режим Daemon, и я использую его, но либо встроенный, либо daemon - оба занимают много времени, и в любом случае, я не уверен, что проблема не в Django, поскольку сервер Django также работает миллион лет:

[16/Aug/2021 11:08:27] "GET /last_12_hours HTTP/1.1" 200 45124

Есть предложения?

РЕШЕНО! Решение:

Причина того, что Django занимает так много времени, во многом связана с функцией sorted.

Я реализовал это, потому что мои результаты из запроса:

AtmosphericObjects = Atmospheric.objects.filter(time__gt=time_frame).order_by('-time').all()

входили не по порядку, несмотря на .order_by('-time'), что само по себе очень просто решается удалением .all()

Итак, вопрос сводится к следующему:

  1. Sorting function taking FOREVER to run on a Pi.
  2. Me not properly understanding the Django models and querySets.
  3. Unnecessarily doing the same thing twice (sorting by time).
Вернуться на верх