Почему количество обработанных запросов в секунду отличается на разных машинах: Nginx Load Balancer + Python Twisted Server - PullRequest
2 голосов
/ 18 июня 2020

Мой коллега и я тестировали производительность запросов в секунду (RPS) простого Twisted Python веб-сервера + Nginx прокси-сервера с балансировкой нагрузки на трех разных машинах, каждая со значительно разными результатами. Наша специфика c касается машины 3, экземпляра AWS Lightsail с примерно такими же аппаратными характеристиками, как у машины 1 и машины 2. Мы используем один и тот же код, описанный ниже, на всех трех машинах. Кажется, что машина 3 может обрабатывать только 1/10 числа запросов, которые могут обрабатывать машины 1 и 2.

(Код ниже одинаков для каждой машины).

Версии

Машина 1

  1. Ubuntu 20.04
  2. Nginx 1,18
  3. Python 3,7.4
  4. IP-адрес (фиктивный IP-адрес для презентации) = M1

Машина 2

  1. Ubuntu 18.04
  2. Nginx 1.14
  3. Python 3.7.4
  4. IP-адрес (фиктивный IP-адрес для презентации) = M2

Машина 3 (AWS Экземпляр Lightsail)

  1. Ubuntu 18.04
  2. Nginx 1.14
  3. Python 3.7.4
  4. IP-адрес (фиктивный IP-адрес для представления) = M3

Конфигурация сервера

Конфигурация сервера, server.conf в conf.d nginx каталог, на каждом компьютере эквивалентен следующей настройке:

upstream backend {
    least_conn;
    server localhost:8000;
    server localhost:8001;
    server localhost:8002;
    server localhost:8003;
    server localhost:8004;
    server localhost:8005;
    server localhost:8006;
    server localhost:8007;
}
server {
    listen 80;
    location /nginx_status {
        stub_status;
    }

    location / {
        proxy_pass http://backend;
    }
 }

Nginx Конфигурация

Файл nginx .conf выглядит следующим образом:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    use epoll;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    sendfile    on;
    tcp_nopush  on;
    tcp_nodelay on;

    keepalive_timeout  300;
    keepalive_requests 300;
    proxy_buffering off;

    include /etc/nginx/conf.d/*.conf;
}

Simple Twisted POST request Handler

Для этого поста я просто написал ea Класс Twisted Resource, который обрабатывает запросы на получение и публикацию.

from twisted.web import resource
class Server_class(resource.Resource):
    isLeaf = True

    def render_POST(self,request):
        ### Does stuff here ###

    def render_GET(self,request):
        ### Does stuff here ###

Затем я настраиваю 8 потоков на портах 8000-8007:

Создание потоков сервера

if __name__ == "__main__":

    #This is normally done via list comprehension, writing out for clarity of presentation
    s0 = server.Site(Server_class())
    s1 = server.Site(Server_class())
    ...
    s7 = server.Site(Server_class())

    #Attaches Server_class instances to specific port
    reactor.listenTCP(8000,s0)
    reactor.listenTCP(8001,s1)
    ...
    reactor.listenTCP(8007,s7)

    reactor.run()

Тестовый сценарий

Последний файл, который у меня есть, это тестовый скрипт, назовите его request_test_script.py:

import multiprocessing as mp
import requests
import threading as th

####List to hold all responses received####
manager = mp.Manager()
all_responses_received = manager.list()

def Send_HTTP_Post_Request(session):

    global all_responses_received

    url = "http://specific.ip.address"
    r = session.post(url, headers=...,data = ...)

    all_responses_received.append(response_information)
    return 

def Test_Method():
    global all_responses_received
    session = requests.Session()
    ticker = th.Event()
    pooler = mp.Pool(mp.cpu_count())
    x = 0

    frequency = .001 #This number is changed to test different RPS rates
    while not ticker.wait(frequency) and x != 10000:
        pooler.apply_async(Send_HTTP_Post_Request,args = (session))
        x = x + 1

    print(all_responses_received)
    return

if __name__ == "__main__":
    Test_Method()

Представлены результаты теста ниже. (Машина 1 - Машина 2 означает, что Машина 2 выполняла потоки Server_class, а Машина 1 выполняла тестовый сценарий).

Результаты испытаний

  • От машины 1 к машине 1: 2000+ RPS
  • Machine 1 to Machine 2: 1000+ RPS
  • от машины 1 к машине 3 / AWS Lightsail: 150 RPS

  • Machine 2 к Machine 1: 2000+ RPS

  • Machine 2 к машине 2: 1000+ RPS
  • Machine 2 к Machine 3 / AWS Lightsail: 200 RPS

  • Machine 3 / AWS Lightsail к Машина 3 / AWS Lightsail: 280 RPS

Примечания : Машина 1 и Машина 2 находились в одной локальной сети. Машина 3, экземпляр AWS Lightsail, находится в США. Сетевая задержка между машинами 1 и 3 и машинами 2 и 3 составляет примерно 25 мс. Потоку требуется примерно 0,2 мс для обработки запроса и отправки ответа (это код в методе render_POST).

Опять же, каждая машина имеет примерно эквивалентную вычислительную мощность процессора, память и т. Д. c. Машина 1 и Машина 2 - это две машины в моей локальной сети, поэтому они могут напрямую общаться друг с другом, тогда как запросы к экземпляру AWS Lightsail и от него были удаленными.

Результаты мониторинга

Когда я проверяю http://IP_Address / nginx_status для всех трех машин, ни один из них не показывает свидетельства об отброшенных пакетах. Когда я отправляю 10000 запросов со скоростью 1000+ об / с с компьютера 1 на компьютер 2, http://IP_Address / nginx_status показывает примерно 10000 полученных запросов. Это относится к тестам от машины 2 к машине 1, машины 1 к машине 1 и машины 2 к машине 2 (иногда пара запросов может быть пропущена, что не является серьезной проблемой).

Однако, когда Я отправляю 1000+ rps на машину 3, nginx_status показывает только около 2500-3000 из 10000 запросов, фактически полученных и отвеченных. Он не показывает отброшенные пакеты, он просто не принимает все запросы. По низким ставкам, например 200 или 100 оборотов в секунду, Машина 3 отлично принимает и обрабатывает все запросы.

Заключение

Мы с коллегой протестировали ряд возможных решений на машине 3, улучшить скорость передачи данных, включая конфигурации Nginx, мониторинг активности порта и временное отключение брандмауэров. Эти изменения оказали минимальное влияние на количество запросов, которые могла обработать машина 3. Все выполненные процедуры мониторинга показывают, что сервер обрабатывает все запросы, которые он действительно получает, но похоже, что он получает не все запросы.

Интересно, что могло вызвать такую ​​резкую c разницу в результатах тестов. Это проблемы с сетью или спецификациями c машины? Это AWS указывает c? Есть ли что-то в частной сети, в которой находятся Машины 1 и 2, что может вызвать проблемы? Есть ли что-то в сети, что может ограничивать количество запросов, которые могут быть отправлены go? Если это так, как мы можем это проверить / исправить? Мы не уверены, что еще мы можем протестировать или улучшить.

Спасибо!

...