Чрезмерные файловые дескрипторы (на lsof) Когда Python регистрируется с помощью Starlette и Uvicorn - PullRequest
8 голосов
/ 24 апреля 2020

У меня есть минимальное приложение Starlette, работающее через Uvicorn, ничего не делающее, кроме возвращения пинга. Странно, даже с одним потоком у меня есть 45 файловых дескрипторов к моему файлу журнала. Дескрипторы увеличиваются при попадании в приложение и плато на 45. Я считаю файловые дескрипторы, используя lsof:

lsof | grep kml-bkny.log

Конечно, это минимальное повторное производство. На самом деле мое общее приложение производит тысячи файловых дескрипторов. Некоторые (~ 200) я бы ожидал данных потоков * контроллеров модулей. Однако я не могу объяснить, где создаются тысячи файловых дескрипторов. В моей настоящей программе они тоже не плато, они растут вечно.

вот мое приложение (api.py):

import logging

from starlette.applications import Starlette
from starlette.responses import JSONResponse

logger = logging.getLogger("kml")
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler('/tmp/kml-bkny.log')
logger.addHandler(handler)

def controller_ping(request):
    try:
        logger.debug("Received /ping request")
        return JSONResponse({}, status_code=200)
    except Exception as e:
        logger.error(e)
        return JSONResponse({}, status_code=500)

app = Starlette()
app.add_route(path='/kml/ping', methods=['GET'], route=controller_ping)

Я запускаю это в командной строке как так:

uvicorn api:app

Я тестирую приложение с помощью простого скрипта:

import time
import requests

while True:
    time.sleep(1)
    for _ in range(10):
        r = requests.get(f'http://localhost:8000/kml/ping', timeout=5)

Это работает на Ubuntu 18.04 с starlette == 0.13.3 и uvicorn == 0.11.3 на Python 3.6

Для сравнения, при запуске без starlette + uvicorn такого эффекта нет. Приведенная ниже управляющая программа выдаст 2 и только 2 файловых дескриптора на lsof:

import logging
import time

logger = logging.getLogger("kml")
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler('/tmp/kml-bkny.log')
logger.addHandler(handler)

while True:
    time.sleep(1)
    for _ in range(10):
        logger.debug("Received /ping request")

Почему будет создано так много файловых дескрипторов, которые я вижу на lsof при представлении starlette и uvicorn?

...