Flask о масштабируемости Gunicorn/ Cheroot

Я разработал конечную точку HTTP API, используя флягу, которая принимает данные json по запросам POST и отправляет ответ json.

Я пробовал использовать несколько серверов WSGI: gunicorn, cheroot, Bjoern за Nginx в качестве обратного прокси.

Я заметил, что независимо от того, какой сервер WSGI я использую, приложение не может обрабатывать постоянную нагрузку в 500 запросов в секунду. Внезапный всплеск 500 - это нормально. Но не тогда, когда он поддерживается. Запросы начинают получать отложенные ответы, а довольно много запросов просто истекает.

Сеть Flask развернута на 24-ядерном физическом сервере. Итак, у него 48 логических ядер. Я использую приложение C ++ на другом аналогичном 24-ядерном сервере, чтобы запускать эти запросы асинхронно. Один запрос каждые 2 мс, то есть 500 в секунду.

Рассмотрим приведенный ниже пример простого однофайлового приложения flask на сервере Cheroot WSGI, которое я создал для тестирования производительности. Он только регистрирует запрос json и отправляет ответ json. Даже это не способно справиться с устойчивой нагрузкой в ​​500 запросов на мощный 24-ядерный физический сервер. Во время теста загрузка ЦП всегда ниже 5%.

      import os
import json
import logging
from logging.handlers import TimedRotatingFileHandler
from flask import Flask
from flask import request, jsonify
from cheroot.wsgi import PathInfoDispatcher
from cheroot.wsgi import Server

app = Flask(__name__)

# Setup logger for the app
if not os.path.exists('logs'):
        os.mkdir('logs')
file_handler = TimedRotatingFileHandler('logs/simpleflaskapp.log', when='midnight', interval=1, backupCount=10)
file_handler.setFormatter(logging.Formatter(
    '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)

app.logger.setLevel(logging.INFO)
app.logger.info("simpleflaskapp startup")
# end setup logger

@app.route( '/test', methods = [ 'POST' ] )
def test():
    app.logger.info(json.dumps(request.json))
    res = {
        "statusCode": 200,
        "message": "OK",
    }
    return jsonify(res)

d = PathInfoDispatcher({'/': app})
server = Server(('0.0.0.0', 8000), d, numthreads=os.cpu_count(), request_queue_size=int(os.cpu_count()/2))

if __name__ == '__main__':
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()

Автор сообщения в блоге https://www.appdynamics.com/blog/engineering/a-performance-analysis-of-python-wsgi-servers-part-2/ может обрабатывать несколько тысяч запросов в секунду на 2-х ядерная машина. Что я делаю неправильно?

Устранение дискового ввода-вывода путем комментирования ведения журнала в приведенном выше примере приложения позволяет мне достигать 666 запросов в секунду. Но не более того. Это все еще мало, учитывая оборудование, на котором я его использую.

Я уже проверил конфигурацию Nginx, и она настроена на гораздо более высокие нагрузки. Я также пробовал отправлять запросы непосредственно на сервер WSGI, пропуская Nginx, и результаты были хуже.

0 ответов

Другие вопросы по тегам