Сервер Flask / официантка перегружается из-за последовательных запросов GET от одного клиента - PullRequest
0 голосов
/ 28 мая 2020

У меня установлено приложение Flask с сервером официантки. Всегда только один клиентский браузер обращается к серверу (это внутренний проект). Предполагается, что большая база данных изображений будет транслироваться в браузере по одному изображению за раз (изображения загружаются с сервера, который выполняет итерацию по базе данных).

Сторона сервера

После некоторой настройки, приложение передает базу данных изображений по URL some_ip_address/get_next_image. После получения каждого запроса на get_next_image сервер получает следующее изображение, предварительно обрабатывает его и отправляет файл в качестве ответа. Сервер запускается с использованием waitress.serve(app, host='0.0.0.0', port=5000)

Клиентская сторона

После перенаправления на some_ip_address/stream в браузере отображается html файл stream.html. Эта страница немедленно вызывает streamNextImage() и отправляет GET-запрос на get_next_image. Как только изображение загружено, оно устанавливается как свойство src изображения, которое отображается на странице stream, а также устанавливается тайм-аут для запроса нового изображения (около 0,2 с).

Проблема

Сервер работает по назначению в течение некоторого времени (иногда в течение часа, иногда больше), но в конечном итоге время отклика начинает становиться ошибочным c (зависает на 10 секунд, затем снова отвечает нормально) , позже интервалы между ответами увеличиваются до 10 секунд, и в конечном итоге сервер вообще перестает отправлять изображения.

Когда это происходит, даже другие URL-адреса не отвечают в браузере, но в журнале сервера я получаю сообщение [WARNING] Task queue depth is 1, и хотя сервер ничего не отправляет (или не получает запросы), использование ЦП на машина, на которой она работает, высока, но я понятия не имею, что она делает.

Похоже, что сервер перегружен предыдущими запросами, но я не понимаю почему, поскольку клиент JS настроен в таком способ, которым новый запрос отправляется только после получения текущего изображения, поэтому переполнение не должно быть возможным.

Как я могу отладить это или в чем может быть проблема?

Код сервера

@app.route("/get_next_image")
def get_next_image():
    row_idx, row, _ = next(app.config["db_iterator"])
    image = preprocess_image(row_idx, row)
    cv2.imwrite('stream_image.jpg', image)
    return send_file(image_path)

Код обозревателя клиента

# stream.html
<html>
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
        function streamNextImage() {
            // Change images only when the new one is already downloaded
            nextImgSrc = '{{ url_for('get_next_image') }}?' + new Date().getTime(); // Add current time as param to prevent browser caching of this URL
            tmpImg.src = nextImgSrc;
            tmpImg.onload = function () {
                $('#face_image').attr('src', nextImgSrc);
                setTimeout(streamNextImage, 1000 * "{{ wait_period }}");
            }
        }

        var tmpImg = new Image();
        streamNextImage()
    </script>
</head>
<body>
    <img src='' alt="Image" id="face_image" name="face_image">
</body>
</html>

Вывод окончательного журнала сервера, когда сервер перестает отвечать

2020-05-28 05:05:16 [INFO ]  Streaming idx:6134/53122)
2020-05-28 05:05:17 [INFO ]  <Request 'http://localhost:5000/get_next_image?1590642317559' [GET]>
2020-05-28 05:05:17 [INFO ]  Streaming idx:6135/53122)
2020-05-28 05:05:26 [INFO ]  <Request 'http://localhost:5000/get_next_image?1590642326559' [GET]>
2020-05-28 05:05:26 [INFO ]  Streaming idx:6136/53122)
2020-05-28 05:05:27 [INFO ]  <Request 'http://localhost:5000/get_next_image?1590642327559' [GET]>
2020-05-28 05:05:27 [INFO ]  Streaming idx:6137/53122)
2020-05-28 05:05:35 [INFO ]  <Request 'http://localhost:5000/get_next_image?1590642332559' [GET]>
2020-05-28 05:05:35 [INFO ]  Streaming idx:6138/53122)
2020-05-28 05:05:36 [INFO ]  <Request 'http://localhost:5000/get_next_image?1590642336559' [GET]>
2020-05-28 05:05:36 [INFO ]  Streaming idx:6139/53122)
2020-05-28 08:05:22 [WARNI]  Task queue depth is 1
...