Низкий уровень RPS при тестировании производительности веб-сайта django

У меня есть такой код, который кэширует страницу на 60 минут:

Я установил панель инструментов отладки django, и она показывает время ~40 мс для кэшированной главной страницы. На моем сервере 2 процессора. Когда я пытаюсь протестировать производительность с помощью locust, я получаю около 3 кадров в секунду. Я думал, что получу около 2CPU * (1000/40) ~ 50 оборотов в секунду.

Я запускаю свой сервер, используя эту команду внутри контейнера docker:

gunicorn main.wsgi:application
            -k gevent
            --workers 6
            --bind 0.0.0.0:8080
            --worker-connections 1000
            --timeout 120

Также я использую psycopg2 с psycogreen wsgi.py начинается с этого:

from psycogreen.gevent import patch_psycopg
patch_psycopg()

Что я делаю не так? Почему не могу справиться с большим количеством RPS?

ваш декоратор кэша в принципе бесполезен для зарегистрированных пользователей. Посмотрите на эту строку

if request.user.is_authenticated:
    return view(request, *args, **kw)  # Completely bypasses cache!

Каждый прошедший проверку пользователь выполняет запросы к вашей базе данных за get_cart_info(). Вот почему вы получаете только 3 повторных запроса вместо ожидаемых более 50.

Кэшируйте пользовательские данные отдельно:

def get_cart_info(user, request):
    if user.is_anonymous:
        return {}, 0, [], 0, []
    
    cache_key = f"user_cart:{user.id}"
    data = cache.get(cache_key)
    if not data:
        # Do your DB queries here
        # Cache for like 1-2 minutes max
        cache.set(cache_key, data, 120)
    return data

Сначала протестируйте с анонимными пользователями - вы легко достигнете более 100 оборотов в секунду для получения действительно кэшированного контента.

Конфигурация Gunicorn, вероятно, подойдет, но попробуйте sync workers вместо gevent для этого варианта использования:

gunicorn main.wsgi:application --workers 4 --worker-class sync --bind 0.0.0.0:8080

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

Те 40 мс, которые вы видите, вероятно, относятся к аутентифицированному запросу, а не к кэшированному. По-настоящему кэшированная страница должна работать максимум 5-10 мс.

Скорее всего, вы столкнулись с этими проблемами:

1. Используя LocMemCache (по умолчанию):

У каждого работника Gunicorn есть свой собственный кэш = общего кэша нет.

** Чтобы исправить это, используйте Redis или Memcached в settings.py:

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.redis.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
    }
}

2. В вашем нагрузочном тесте Locust могут использоваться зарегистрированные пользователи

Ваш кэш работает только для анонимных пользователей:

if request.user.is_authenticated:
    return view(request, *args, **kw)

** Нагрузочный тест с анонимными (не прошедшими проверку подлинности) пользователями.

3. Gunicorn Не использует все процессоры в Docker

** Используйте все ядра динамически:

--workers $(nproc)

Полная команда:

gunicorn main.wsgi:application \
    -k gevent \
    --workers $(nproc) \
    --worker-connections 1000 \
    --timeout 120 \
    --bind 0.0.0.0:8080

Кроме того, убедитесь, что Docker разрешено использовать 2 процессора:

docker run --cpus="2.0" ...
<время работы/>

4. Gunicorn работает медленно для статических файлов.

** Используйте Nginx или CDN для статических файлов.

Вернуться на верх