Método de implementación de la aplicación Flask Flask + Gunicorn + Nginx

1. Por qué Flask + Gunicorn + Nginx

Flask + Gunicorn + Nginx es la solución de implementación de Flask más utilizada. ¿Alguna vez se ha preguntado por qué utiliza esta combinación?

1.1 ¿Por qué?

Flask es un marco web, no un servidor web. Los servicios web directamente extraídos por Flask se limitan al entorno de desarrollo. El entorno de producción no es lo suficientemente estable y no puede soportar la concurrencia de una gran cantidad de solicitudes. entorno de té, se requiere software de servidor para manejar cada una de Tales solicitudes, como Gunicorn, Nginx o Apache, y la combinación de Gunicorn + Nginx tiene muchos beneficios. Por un lado, reenvía el servicio Gunicorn basado en Nginx, que puede complementar el Deficiencias del servicio Gunicorn en algunos casos en el entorno de producción. Además de los servicios, un sitio web también tiene muchos archivos estáticos que necesitan ser alojados. Esta es la fortaleza de Nginx, y también es algo para lo que Gunicorn no es adecuado. Por lo tanto, es una buena opción usar Gunicorn y Nginx al implementar un sitio web basado en Flask.

1.2 ¿Algo más?

1. ¿Por qué necesito Nginx para reenviar el servicio Gunicorn?

Nginx es poderoso y hay muchos beneficios al usar Nginx. Sin embargo, usar Nginx para reenviar los servicios de Gunicorn se enfoca en resolver el problema de la degradación del rendimiento causada por el "comportamiento lento del cliente" en el servidor; además, al implementar servicios HTTP en Internet. , también debe considerar "La" respuesta rápida del cliente ", el procesamiento SSL y los problemas de alta concurrencia pueden resolverse en Nginx. Por lo tanto, agregar una capa de proxy inverso de Nginx sobre el servicio Gunicorn es una solución de implementación que servirá para múltiples propósitos.

2. ¿Por qué existe un problema de degradación del rendimiento del servicio causado por un "comportamiento lento del cliente"?

La comunicación entre el servidor y el cliente se divide en tres partes: solicitud, manejo de solicitudes y respuesta, es decir, el cliente inicia una solicitud al servidor, el servidor responde y procesa la solicitud, y devuelve el resultado de la solicitud al cliente. Estos tres procesos.

Por lo general, la parte de manejo de solicitudes es el cálculo del servidor, que se trata del rendimiento del servidor, y el procesamiento es más eficiente y estable, mientras que las partes de solicitud y respuesta tienen más factores de influencia. Si estos tres procesos se colocan en el mismo proceso para el procesamiento síncrono Si las partes de solicitud y respuesta requieren mucho tiempo, los recursos informáticos estarán ocupados y no se podrán liberar a tiempo, lo que provocará un uso ineficiente de los recursos informáticos y reducirá la capacidad de procesamiento del servidor.

El "comportamiento lento del cliente" se refiere a la parte de la solicitud (o respuesta) que consume mucho tiempo. Gunicorn pone los tres procesos anteriores en el mismo proceso. Cuando se produce el "comportamiento lento del cliente", la eficiencia es Muy baja:

Gunicorn es un software de pre-bifurcación , que es muy eficaz para la comunicación de baja latencia, como el equilibrio de carga o la comunicación entre servicios. Sin embargo, la desventaja del sistema de pre-bifurcación es que cada comunicación ocupará un proceso exclusivamente. Cuando se envían más solicitudes al servidor que los procesos disponibles para el servidor, la eficiencia de respuesta se reducirá porque no hay más procesos en el servidor. lado del servidor para responder a nuevas solicitudes.

Para los sitios web o servicios, dado que los retrasos en las solicitudes y respuestas son incontrolables, debemos considerar el procesamiento de las solicitudes de los clientes de alta latencia. Estas solicitudes ocuparán el proceso del lado del servidor. Cuando el cliente lento se comunica directamente con el servicio, dado que las solicitudes de clientes lentos ocuparán el proceso, la cantidad de procesos disponibles para procesar nuevas solicitudes se reducirá. Si hay muchas solicitudes de clientes lentos que ocupan todos los procesos, las nuevas solicitudes solo pueden esperar. se libera un proceso, obtiene una respuesta. Además, si la aplicación desea una mayor concurrencia, la comunicación entre el servidor y el cliente debe ser más eficiente y la comunicación asíncrona será más efectiva que la comunicación síncrona.

El software de servidor asincrónico como Nginx es bueno para manejar una gran cantidad de solicitudes con muy poca memoria y sobrecarga de CPU. Dado que son buenos para manejar una gran cantidad de solicitudes de clientes al mismo tiempo, las solicitudes de clientes lentas tienen poco efecto sobre ellas. En lo que respecta a Nginx, en condiciones normales de hardware de servidor, es fácil manejar decenas de miles de solicitudes al mismo tiempo.

Por lo tanto, bloquear Nginx frente al servicio de bifurcación previa para procesar solicitudes es una buena opción. Nginx puede responder a las solicitudes de los clientes de forma asíncrona y con alta concurrencia (las solicitudes lentas de los clientes tienen poco efecto en Nginx). Una vez que Nginx recibe la solicitud, la reenvía inmediatamente al servicio Gunicorn para su procesamiento, y Nginx envía el resultado al cliente en el forma de respuesta final. De esta forma, toda la comunicación entre el servidor y el cliente ha cambiado de la comunicación síncrona original solo a través de Gunicorn a la comunicación asincrónica basada en Nginx y Gunicorn, y se ha mejorado enormemente la eficiencia y concurrencia de la comunicación.

Para el sitio web, además de la situación descrita anteriormente, también debemos considerar el alojamiento de varios archivos estáticos. Los archivos estáticos incluyen no solo CSS, JavaScript y otros archivos de interfaz, sino también imágenes, videos y varios documentos. Por lo tanto, los archivos estáticos pueden ser más grandes o recibir llamadas con más frecuencia. La función de alojamiento de los archivos estáticos es garantizar todo tipo de Rendimiento estático La carga, vista previa o descarga normal es en realidad el "comportamiento lento del cliente" de Response que consume mucho tiempo. El uso de Gunicorn para alojar archivos estáticos también afectará seriamente la eficiencia de respuesta de Gunicorn, que es exactamente en lo que Nginx es bueno, por lo que el alojamiento de archivos estáticos debería ser manejado por Nginx.

 

2. Cómo implementar el sitio web de Flask

Combinado con la explicación en la sección anterior, cómo implementar el sitio web de Flask también es muy claro:

  1. Utilice un software de servidor (como Gunicorn) para abrir la aplicación escrita en Flask
  2. Utilice Nginx para crear un proxy inverso para la aplicación que se activó en el paso anterior
  3. Los archivos estáticos involucrados en el sitio web, utilizan Nginx para el alojamiento de archivos

El software de servidor común es Gunicorn y uWSGI. Debido a que Gunicorn es fácil de usar y eficiente, es muy simple usar Gunicorn para abrir el sitio web de Flask, por lo que Gunicorn se usa generalmente para implementar el sitio web de Flask y es la solución de implementación más común. (Además, a Gevin personalmente también le gusta Gunicorn porque Gunicorn está escrito en Python puro y se puede instalar directamente con pip, mientras que uwsgi tiene que instalar dependencias adicionales en el sistema. Esto es particularmente simple cuando se usa con docker.

Para el alojamiento de archivos estáticos, dado que el marco de Flask se usa generalmente para implementar el alojamiento de archivos estáticos durante la fase de desarrollo, cuando se usa Gunicorn para abrir el sitio web de Flask, el sitio web ha implementado la función de alojamiento de archivos basada en Gunicorn, así que configure el Alojamiento de archivos estáticos de Nginx Cuando se utiliza la URL, se puede configurar directamente como una ruta de archivo coherente con el alojamiento de Gunicorn, lo que simplifica la lógica de desarrollo e implementación. Además, dado que Nginx es una capa más alta que Gunicorn, cuando el cliente solicita un archivo estático, Nginx devolverá directamente la Respuesta. No se preocupe por solicitar a Gunicorn que afecte la eficiencia del servidor.

2.1 Gunicornio

Cómo Gunicorn implementa el sitio web de Flask, solo mire los archivos oficiales de Flask o Gunicorn, generalmente solo ejecute una línea de comandos similar a la siguiente:

/usr/local/bin/gunicorn -w 2 -b :4000 manage:app

2.2 Nginx

El uso de Nginx como proxy inverso y el alojamiento de archivos estáticos también es muy simple. Estoy aquí para proporcionar una demostración que se puede utilizar. Para obtener más formas de jugar, consulte la documentación de Nginx.

server {
    listen 80;

    server_name localhost;

    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://localhost:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

    location /media  {
        alias /usr/share/nginx/html/media;  
    }

    location /static  {
        alias /usr/share/nginx/html/static;  
    }
}

Entre ellos, la configuración del proxy inverso es:

    location / {
        proxy_pass         http://localhost:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

La configuración para el alojamiento de archivos estáticos es:

    location /media  {
        alias /usr/share/nginx/html/media;  
    }

    location /static  {
        alias /usr/share/nginx/html/static;  
    }

Aquí gestioné los archivos en las dos carpetas.

 

3. Implementación del sitio web de Flask basado en Docker

Docker tiene la ventaja de implementarse una vez y ejecutarse en todas partes. En la práctica, es más conveniente encapsular los métodos de implementación tradicionales anteriores en una imagen de Docker y luego cooperar con los servicios de orquestación de Docker Compose.

3.1 Cree un espejo del sitio web de Flask

Por lo general, el espejo contiene el entorno de ejecución del sitio web de Flask, y luego Gunicorn se puede usar como el comando de ejecución de la imagen. Por ejemplo, el Dockerfile de mi OctBlog se escribe de la siguiente manera:

# MAINTAINER        Gevin <[email protected]>
# DOCKER-VERSION    18.03.0-ce, build 0520e24

FROM python:3.6.5-alpine3.7
LABEL maintainer="[email protected]"

RUN mkdir -p /usr/src/app  && \
    mkdir -p /var/log/gunicorn

WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/requirements.txt

RUN pip install --no-cache-dir gunicorn && \
    pip install --no-cache-dir -r /usr/src/app/requirements.txt

COPY . /usr/src/app


ENV PORT 8000
EXPOSE 8000 5000

CMD ["/usr/local/bin/gunicorn", "-w", "2", "-b", ":8000", "manage:app"]

Aquí, Gevin usa directamente la imagen Python-alpine más pequeña como imagen básica, lo que reduce en gran medida el volumen de la imagen de la aplicación Flask que se va a construir. Para una imagen mínima como alpine, que tiene solo unos pocos megabytes, pip install uwsgise informará de un error directamente sin instalar otras dependencias del sistema .

3.2 Configuración relacionada con Nginx

Nginx se utiliza principalmente para el alojamiento de archivos estáticos y proxy inverso, que es coherente con el archivo de configuración anterior, como:

server {
    listen 80;

    server_name localhost;

    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://blog:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

    location /media  {
        alias /usr/share/nginx/html/media;  
    }

    location /static  {
        alias /usr/share/nginx/html/static;  
    }
}

La única diferencia entre este archivo de configuración y el capítulo anterior es que proxy_pass http://blog:8000/; el servicio de proxy inverso en la línea 10 bloges el servicio del sitio web OctBlog configurado en Docker-compose a continuación.

3.3 Utilice Docker-compose para organizar los servicios

El archivo de orquestación de Docker-compose de OctBlog es el siguiente:

version: '3'
services:
  blog:
    # restart: always
    image: gevin/octblog:0.4.1
    volumes:
      - blog-static:/usr/src/app/static
    env_file: .env
    networks:
      - webnet

  mongo:
    # restart: always
    image: mongo:3.2
    volumes:
      - /Users/gevin/projects/data/mongodb:/data/db
    networks:
      - webnet

  blog-proxy:
    # restart: always
    image: nginx:stable-alpine
    ports:
      - "8080:80"
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - blog-static:/usr/share/nginx/html/static:ro
      - blog-static:/usr/share/nginx/html/media:ro
    networks:
      - webnet


volumes:
  blog-static:
networks:
  webnet:

Entre ellos, para permitir que múltiples servicios se comuniquen entre sí, se crea una red personalizada  webnety para permitir que los archivos se compartan entre múltiples servicios, se comparte un volumen  blog-static.

 

4. Implementación de otros sitios web de Python

Basándonos en el contenido anterior, por analogía, también podemos clasificar las rutinas generales de varios marcos web de Python para la implementación de sitios web:

  1. Utilice un servidor HTTP WSGI de Python para implementar código, como:
  2. Utilice Nginx como proxy inverso
  3. Haz un buen trabajo alojando archivos estáticos

 

5. Nota:

  1. Además de Nginx, el software de servidor también tiene otras opciones como Apache. Gevin no tiene un conocimiento profundo de otros sitios web de Python de implementación de software de servidor, por lo que este artículo no lo cubre.
  2. El código fuente de OctBlog está alojado en GitHub, puede buscar en el repositorio de flyhigher139 / OctBlog para ver

Al escribir este artículo, nos referimos al siguiente contenido, puedes ampliarlo:

Por qué flask + nginx + gunicorn:

Acerca de Preforking:

Nginx sirve archivos estáticos de matraces:

Supongo que te gusta

Origin blog.csdn.net/smilejiasmile/article/details/110825837
Recomendado
Clasificación