No hay respuesta en el problema original de github: https://github.com/tiangolo/meinheld-gunicorn-flask-docker/issues/48
En la configuración simple a continuación, espero que el gunicorn procese al menos 4 solicitudes en paralelo, pero solo obtengo 2. En la configuración a continuación, podemos ver 2 trabajadores con 2 subprocesos.
Además, intentamos configurar el número de trabajadores == 1 con 2 subprocesos, luego obtuvimos solo 1 solicitud procesada en un momento dado. Entonces, parece que la configuración de gunicorn + meinheld puede procesar solo 1 solicitud en cada trabajador, lo cual es muy ineficiente.
Estamos enviando 53 solicitudes en paralelo en cada configuración.
aplicación_simple.py:
import sys from flask import Flask, request import json import time app = Flask(__name__) @app.route("/", methods=['POST']) def hello(): headers = request.headers data = json.loads(request.data) version = "{}.{}".format(sys.version_info.major, sys.version_info.minor) message = "Hello World from Flask in a Docker container running Python {} with Meinheld and Gunicorn (default): {}:{}".format( version, headers, json.dumps(data) ) print(message) time.sleep(15) return messagegunicorn_dev_conf.py:
import json import multiprocessing import os workers_per_core_str = os.getenv("WORKERS_PER_CORE", "2") web_concurrency_str = os.getenv("WEB_CONCURRENCY", None) host = os.getenv("HOST", "0.0.0.0") port = os.getenv("PORT", "80") bind_env = os.getenv("BIND", None) use_loglevel = os.getenv("LOG_LEVEL", "debug") if bind_env: use_bind = bind_env else: use_bind = "{host}:{port}".format(host=host, port=port) cores = multiprocessing.cpu_count() workers_per_core = float(workers_per_core_str) default_web_concurrency = workers_per_core * cores if web_concurrency_str: web_concurrency = int(web_concurrency_str) assert web_concurrency > 0 else: web_concurrency = int(default_web_concurrency) # Gunicorn config variables loglevel = use_loglevel workers = web_concurrency workers = 2 reuse_port = True bind = use_bind keepalive = 120 errorlog = "-" threads = 2 # For debugging and testing log_data = { "loglevel": loglevel, "workers": workers, "bind": bind, # Additional, non-gunicorn variables "workers_per_core": workers_per_core, "host": host, "port": port} accesslog = "-" preload_app = False print_config = True # max_requests = 1900 # max_requests_jitter = 50 sendfile = True print(json.dumps(log_data), flush=True)Comando de ejecución de la ventana acoplable:
docker run --rm --name demo_dev --privileged -it -p 8080:80 -v ./gunicorn_dev_conf.py:/app/gunicorn_conf.py:rw -v ./simple_app.py:/app/main.py tiangolo/meinheld-gunicorn-flask:python3.8-alpine3.11Comando curl paralelo:
for i in {1..53} do echo "Welcome num$i; $(date)" curl "http://localhost:8080/" -d @simpleJson.json -H 'content-type: application/json' -o dir_$i&&echo "num"$i"; $(date)" & donesimpleJson.json:
{ "field1": [ { "field2": "09-090" } ] }producción:
10.0.2.100 - - [05/Aug/2021:12:16:20 +0000] "POST / HTTP/1.1" 200 251 "-" "curl/7.61.1" Hello World from Flask in a Docker container running Python 3.8 with Meinheld and Gunicorn (default): Host: localhost:8080 User-Agent: curl/7.61.1 Accept: */* Content-Type: application/json Content-Length: 70 :{"field1": [{"field2": "09-090"}]} 10.0.2.100 - - [05/Aug/2021:12:16:20 +0000] "POST / HTTP/1.1" 200 251 "-" "curl/7.61.1" Hello World from Flask in a Docker container running Python 3.8 with Meinheld and Gunicorn (default): Host: localhost:8080 User-Agent: curl/7.61.1 Accept: */* Content-Type: application/json Content-Length: 70 :{"field1": [{"field2": "09-090"}]} >> WAIT 15 seconds... 10.0.2.100 - - [05/Aug/2021:12:16:35 +0000] "POST / HTTP/1.1" 200 251 "-" "curl/7.61.1" Hello World from Flask in a Docker container running Python 3.8 with Meinheld and Gunicorn (default): Host: localhost:8080 User-Agent: curl/7.61.1 Accept: */* Content-Type: application/json Content-Length: 70 :{"field1": [{"field2": "09-090"}]} 10.0.2.100 - - [05/Aug/2021:12:16:35 +0000] "POST / HTTP/1.1" 200 251 "-" "curl/7.61.1" Hello World from Flask in a Docker container running Python 3.8 with Meinheld and Gunicorn (default): Host: localhost:8080 User-Agent: curl/7.61.1 Accept: */* Content-Type: application/json Content-Length: 70 :{"field1": [{"field2": "09-090"}]}