Низкий уровень 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 для статических файлов.