Arhn - архитектура программирования

uwsgi не может обрабатывать запрос дольше одной минуты

У меня есть приложение Django, которое обслуживается в контейнере докеров через uwsgi. Я подготовил собственное представление только для того, чтобы воспроизвести проблему, о которой я упоминаю. Это выглядит точно так, как показано ниже:

def get(self, request):
    logger = logging.getLogger('ReleaseReport')
    logger.critical('Entering and sleeping')
    time.sleep(180)
    logger.critical('Awaking')

    return Response({'response': 'anything'})

Единственное, что он делает (намеренно), — это регистрирует сообщение, спит в течение 3 минут, а затем записывает другое сообщение.

Вот как работает файл журнала после того, как я пытаюсь посетить представление из Firefox/Chrome/PyCharm's rest API client:

spawned uWSGI worker 9 (pid: 14, cores: 1)
spawned uWSGI worker 10 (pid: 15, cores: 1)
spawned uWSGI http 1 (pid: 16)
CRITICAL 2018-08-31 12:10:37,658 views Entering and sleeping
CRITICAL 2018-08-31 12:11:37,742 views Entering and sleeping
CRITICAL 2018-08-31 12:11:38,687 views Awaking
[pid: 10|app: 0|req: 1/1] 10.187.133.2 () {36 vars in 593 bytes} [Fri Aug 31 12:10:37 2018] GET /api/version/ => generated 5156 bytes in 61229 msecs (HTTP/1.1 200) 4 headers in 137 bytes (1 switches on core 0)
CRITICAL 2018-08-31 12:12:37,752 views Entering and sleeping
CRITICAL 2018-08-31 12:12:38,784 views Awaking
[pid: 15|app: 0|req: 1/2] 10.187.133.2 () {36 vars in 593 bytes} [Fri Aug 31 12:11:37 2018] GET /api/version/ => generated 5156 bytes in 61182 msecs (HTTP/1.1 200) 4 headers in 137 bytes (1 switches on core 0)
CRITICAL 2018-08-31 12:13:38,020 views Entering and sleeping
CRITICAL 2018-08-31 12:13:38,776 views Awaking
[pid: 10|app: 0|req: 2/3] 10.187.133.2 () {36 vars in 593 bytes} [Fri Aug 31 12:12:37 2018] GET /api/version/ => generated 5156 bytes in 61034 msecs (HTTP/1.1 200) 4 headers in 137 bytes (1 switches on core 0)

Через одну минуту представление вроде бы выполняется снова, а еще через минуту выполняется третий раз. Более того, в журнале указано, что это HTTP 200, но клиент не получает данные и просто говорит, что не может загрузить их через несколько минут (зависит от клиента). Однако первый HTTP 200 в журнале появляется намного раньше, чем клиент сдается.

Любые подсказки, что может быть причиной этой проблемы? Вот мой uwsgi.ini:

[uwsgi]

http = 0.0.0.0:8000
chdir = /app
module = web_server.wsgi:application
pythonpath = /app

static-map = /static=/app/static

master = true
processes = 10
vacuum = true

Команда Dockerfile выглядит следующим образом:

/usr/local/bin/uwsgi --ini /app/uwsgi.ini

В моем реальном приложении это приводит к тому, что клиент считает, что запрос не выполнен, но, поскольку он фактически был выполнен и завершен 3 раза, в базе данных есть 3 записи. Изменение количества рабочих процессов на 1 мало что меняет. Вместо того, чтобы ждать в течение одной минуты, чтобы снова создать вид, он создается после завершения предыдущего.

Что не так с моей конфигурацией?

РЕДАКТИРОВАТЬ:

Я немного изменил свой вид, теперь он принимает параметр времени сна и выглядит так:

def get(self, request, minutes=None):
    minutes = int(minutes)
    original_minutes = minutes
    logger = logging.getLogger(__name__)
    while minutes > 0:
        logger.critical(f'Sleeping, {minutes} more minutes...')
        time.sleep(60)
        minutes -= 1

    logger.critical(f'Slept for {original_minutes} minutes...')
    return Response({'slept_for': original_minutes})

Теперь керлинг:

> curl http://test-host/api/test/0
{"slept_for":0}

> curl http://test-host/api/test/1
{"slept_for":1}

> curl http://test-host/api/test/2
curl: (52) Empty reply from server

В журнале:

CRITICAL 2018-08-31 14:23:36,200 views Slept for 0 minutes...
[pid: 10|app: 0|req: 1/14] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:23:35 2018] GET /api/test/0 => generated 15 bytes in 265 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
CRITICAL 2018-08-31 14:23:42,878 views Slept for 0 minutes...
[pid: 10|app: 0|req: 2/15] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:23:42 2018] GET /api/test/0 => generated 15 bytes in 1 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
CRITICAL 2018-08-31 14:23:46,370 views Sleeping, 1 more minutes...
CRITICAL 2018-08-31 14:24:46,380 views Slept for 1 minutes...
[pid: 10|app: 0|req: 3/16] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:23:46 2018] GET /api/test/1 => generated 15 bytes in 60011 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)
CRITICAL 2018-08-31 14:27:06,903 views Sleeping, 2 more minutes...
CRITICAL 2018-08-31 14:28:06,963 views Sleeping, 1 more minutes...
CRITICAL 2018-08-31 14:29:06,995 views Slept for 2 minutes...
[pid: 9|app: 0|req: 1/17] 10.160.43.172 () {28 vars in 324 bytes} [Fri Aug 31 14:27:06 2018] GET /api/test/2 => generated 15 bytes in 120225 msecs (HTTP/1.1 200) 4 headers in 129 bytes (1 switches on core 0)

Если я использую ту же команду для тестирования сервера, работающего с manage.py runserver, он отвечает каждый раз - независимо от того, сплю ли я 2 минуты или 10. Так что это не вина клиента. Поменял харакири на 3600, без изменений.

EDIT2 (мой файл Docker):

FROM python:3.7.0-alpine

ADD . /app

RUN set -ex \
    && apk add mysql-dev \
               pcre-dev \
    && apk add --no-cache --virtual .build-deps \
            gcc \
            make \
            libc-dev \
            musl-dev \
            linux-headers \
            libffi-dev \
    && pip install --no-cache-dir -r /app/requirements.txt \
    && runDeps="$( \
            scanelf --needed --nobanner --recursive /venv \
                    | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
                    | sort -u \
                    | xargs -r apk info --installed \
                    | sort -u \
    )" \
    && apk add --virtual .python-rundeps $runDeps \
    && apk del .build-deps

WORKDIR /app

RUN mkdir -p static
RUN python manage.py collectstatic --clear --noinput

EXPOSE 8000

CMD ["/usr/local/bin/uwsgi", "--ini", "/app/uwsgi.ini"]
31.08.2018

  • Через некоторое время браузеры сдаются и больше не слушают ответ, независимо от того, предоставит его сервер или нет. Кроме того, Django работает с пулом рабочих, которые обрабатывают запросы, если я правильно помню. Таким образом, он будет ограничивать количество запросов, которые выполняются одновременно. 31.08.2018
  • Так что, если вышесказанное верно, оператор может попробовать curl, чтобы подтвердить это. 31.08.2018
  • Я пробовал разные клиенты, включая встроенный PyCharm и Insomnia. 31.08.2018
  • Но ваша точка зрения правильная. Похоже, что браузер и клиенты повторяют попытку. Похоже, они не могут прочитать ответ HTTP и просто пытаются снова. Curl нет, он просто говорит Empy reply from server. 31.08.2018
  • Как выглядит ваш dockerfile? 01.09.2018
  • Я обновил вопрос с помощью dockerfile. 01.09.2018

Ответы:


1

На самом деле это была проблема с Dockerfile. Раньше у меня был uWSGI в файле requirements.txt, поэтому он был установлен pip install.
Когда я удалил его и добавил uwsgi-python3 в apk add, теперь все в порядке.

Не знаю, почему это важно (все остальное работало нормально), но это решило мою проблему.

03.09.2018
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..