maximkv25
@maximkv25
web-developer

Как выявить слабые места при нагрузочном тестировании?

Приветствую, проводил нагрузочное тестирование через loader.io, хочу понять механизм по какому определять слабые места в сервисе.

Сервер VPS (flops): Intel Xeon E5-2620, 2048 Мб RAM, 64 Гб SSD
Данные о процессоре:
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 42
Model name:            Intel Xeon E5 (Sandy Bridge)
Stepping:              1
CPU MHz:               2399.998
BogoMIPS:              4799.99
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0


Установлен nginx, со следующей конфигурацией:

nginx.conf
user www-data;
worker_processes 1;
pid /run/nginx.pid;
worker_rlimit_nofile 16384;

events {
	worker_connections 8192;
	multi_accept on;
	use epoll;
}


http {

    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    upstream websocket {
        server alpha.domain;
    }

    include sites-enabled/*.conf;
}


domain.conf
server {

    if ($host !~ ^(alpha.domain|www.domain|domain)$ ) {
        return 444;
    }

    listen 443;
    ssl on;
    ssl_certificate /etc/ssl/alpha.domain.crt;
    ssl_certificate_key /etc/ssl/alpha.domain.key;
    server_name alpha.domain;

    # Loader
    location /loaderio-50871621bbb3128##9662822af####29 {
        root /home/dev.domain/front/public;
    }

    # Monitorix
    location /nginx_status {
		stub_status on;
		access_log off;
		allow 127.0.0.1;
		deny all;
	}

    # Django
    location /static_admin/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
        alias /home/dev.domain/backend/static;
    }

    location /strawberry/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
    }

    location /api/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
    }

    location /r/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
    }


    #############
    # Ws server #
    #############

    location /ws {
        proxy_pass http://127.0.0.1:8060;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 5000s;
    }


    # Node
    location / {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8000;
    }

    location ~* /static/.*\.(gif|jpg|jpeg|bmp|png)$ {
        include sites-enabled/proxy.conf;
        #proxy_pass http://127.0.0.1:8000;
        root /home/dev.domain/front/public/;
    }
}

server {
    listen 80;
    server_name alpha.domain;

    # Monitorix
    location /nginx_status {
		stub_status on;
		access_log off;
		allow 127.0.0.1;
		deny all;
	}

    # Django
    location /static_admin/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
        alias /home/dev.domain/backend/static;
    }

    location /strawberry/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
    }

    location /api/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
    }

    location /r/ {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8080;
    }

    #############
    # Ws server #
    #############

    location /ws {
        proxy_pass http://127.0.0.1:8060;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 5000s;
    }


    # Node
    location / {
        include sites-enabled/proxy.conf;
        proxy_pass http://127.0.0.1:8000;
    }

    location ~* /static/.*\.(gif|jpg|jpeg|bmp|png)$ {
        include sites-enabled/proxy.conf;
        #proxy_pass http://127.0.0.1:8000;
        root /home/dev.domain/front/public/;
    }
}


Front на angularjs 1.5.*, запущен через forever, тест проводил на главной странице, где нет запросов по api к back
5a60a9f228952877649451.png

Back собран с помощью docker
version: '3'
services:

    # Django web server
    web:
      volumes:
        - "./app/back:/app"
        - "../front/public/static:/app/static"
        - "./phantomjs-2.1.1:/app/phantomjs"
      build:
        context: .
        dockerfile: dockerfile_django
      ports:
        - "8080:8080"
      links:
        - async
        - ws_server
        - mysql
        - redis

    async:
      volumes:
        - "./app/async_web:/app"
      build:
        context: .
        dockerfile: dockerfile_async
      ports:
        - "8070:8070"

    # Aiohtp web socket server
    ws_server:
      volumes:
        - "./app/ws_server:/app"
      build:
        context: .
        dockerfile: dockerfile_ws_server
      ports:
        - "8060:8060"

    # MySQL db
    mysql:
      image: mysql/mysql-server:5.7
      volumes:
        - "./db_mysql:/var/lib/mysql"
        - "./my.cnf:/etc/my.cnf"
      environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_USER: user
        MYSQL_PASSWORD: pass
        MYSQL_DATABASE: dev
        MYSQL_PORT: 3306
      ports:
        - "3300:3306"

    # Redis
    redis:
      image: redis:4.0.6
      ports:
        - "6379:6379"

    # Celery worker
    celery:
      build:
        context: .
        dockerfile: dockerfile_celery
      command: celery -A backend worker -l info --concurrency=20
      volumes:
        - "./app/back:/app"
        - "../front/public/static:/app/static"
      links:
        - redis

    # Celery beat
    beat:
      build:
        context: .
        dockerfile: dockerfile_beat
      command: celery -A backend beat
      volumes:
        - "./app/back:/app"
        - "../front/public/static:/app/static"
      links:
        - redis

    # Flower monitoring
    flower:
      build:
        context: .
        dockerfile: dockerfile_flower
      command: celery -A backend flower
      volumes:
        - "./app/back:/app"
        - "../front/public/static:/app/static"
      ports:
        - "5555:5555"
      links:
        - redis


Сервер django запущен через uwsgi
dockerfile_django
FROM python:3.4


RUN mkdir /app
WORKDIR /app
ADD app/back/requirements.txt /app
RUN pip3 install -r requirements.txt

CMD ["uwsgi", "--ini", "/app/uwsgi.ini"]


Настройки uwsgi.ini
[uwsgi]
http-socket = :8080
chdir = /app
module = backend.wsgi
master = true
processes = 10
harakiri=30


Результаты теста
5a619d0908c18001402810.png

  1. Какие есть методологии мониторинга? (пробовал через monitorix, но данные обновляются не совсем real time, здесь может посоветуете как правильно настроить или же заменить другой утилитой)
  2. Nginx и uwsgi дают настолько большую нагрузку на процессор? (при проведении нагрузочного тестирования на сервере отслеживал загрузку через top, в основном потреблял nginx до 80%, иногда uwsgi подымал значения до 18%)

  3. Каким образом лучше всего мониторить нагрузку на бд и отслеживать проблемные места?

  4. Как понять что тормозит фреймворк? (все что приходит на ум, это логировать время выполнения кода обвешенного декоратором)



P.S.
Так же буду благодарен за дельные советы, статьи и прочую полезную информацию.
  • Вопрос задан
  • 438 просмотров
Пригласить эксперта
Ответы на вопрос 1
@marataziat
Джангист-тракторист
Делайте нагрузку на разные роуты, где будет появляться 50x ошибка или долгое время ответа дебажте, и оптимизируйте.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы