Flask о масштабируемости сигары и пушки

Я разработал конечную точку HTTP API, используя flask, которая принимает данные 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-anaлиз-of-python-wsgi-servers-part-2/ может обслуживать несколько тысяч запросов в секунду на 2-ядерная машина. Что я делаю не так?

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

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

0 ответов

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