Buscar..


Usando uWSGI para ejecutar una aplicación matraz

El servidor werkzeug incorporado ciertamente no es adecuado para ejecutar servidores de producción. La razón más obvia es el hecho de que el servidor werkzeug es de un solo hilo y, por lo tanto, solo puede manejar una solicitud a la vez.

Debido a esto, queremos usar el servidor uWSGI para servir nuestra aplicación en su lugar. En este ejemplo instalaremos uWSGI y ejecutaremos una aplicación de prueba simple con él.

Instalando uWSGI :

pip install uwsgi

Es tan simple como eso. Si no está seguro de la versión de python que utiliza su pip, hágala explícita:

python3 -m pip install uwsgi  # for python3
python2 -m pip install uwsgi  # for python2

Ahora vamos a crear una aplicación de prueba simple:

app.py

from flask import Flask
from sys import version

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello uWSGI from python version: <br>" + version

application = app

En el matraz, el nombre convencional para la aplicación es app pero uWSGI busca la application por defecto. Es por eso que creamos un alias para nuestra aplicación en la última línea.

Ahora es el momento de ejecutar la aplicación:

uwsgi --wsgi-file app.py --http :5000

Debería ver el mensaje "Hola uWSGI ..." apuntando su navegador a localhost:5000

Para no escribir el comando completo cada vez que creamos un archivo uwsgi.ini para almacenar esa configuración:

uwsgi.ini

[uwsgi]
http = :9090
wsgi-file = app.py
single-interpreter = true
enable-threads = true
master = true

Las opciones de wsgi-file http y wsgi-file son las mismas que en el comando manual. Pero hay tres opciones más:

  • single-interpreter : se recomienda activar esto porque podría interferir con la siguiente opción

  • enable-threads : esto debe estar activado si está utilizando subprocesos adicionales en su aplicación. No los usamos ahora, pero ahora no tenemos que preocuparnos por eso.

  • master : el modo maestro debe habilitarse por varias razones

Ahora podemos ejecutar la aplicación con este comando:

uwsgi --ini uwsgi.ini

Instalando nginx y configurándolo para uWSGI

Ahora queremos instalar nginx para servir nuestra aplicación.

sudo apt-get install nginx  # on debian/ubuntu

Luego creamos una configuración para nuestro sitio web.

cd /etc/nginx/site-available  # go to the configuration for available sites
# create a file flaskconfig with your favourite editor

flaskconfig

server {
    listen 80;
    server_name localhost;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/flask.sock;
    }
}

Esto le indica a nginx que escuche en el puerto 80 (predeterminado para http) y sirva algo en la ruta raíz ( / ). Allí le decimos a nginx que simplemente actúe como un proxy y pase cada solicitud a un socket llamado flask.sock ubicado en /tmp/ .

Vamos a habilitar el sitio:

cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/flaskconfig .

Es posible que desee eliminar la configuración predeterminada si está habilitada:

# inside /etc/sites-enabled
sudo rm default

Luego reinicie nginx:

sudo service nginx restart

Apunte su navegador a localhost y verá un error: 502 Bad Gateway .

Esto significa que nginx está activo y funcionando pero falta el zócalo. Así que vamos a crear eso.

Vuelva a su archivo uwsgi.ini y ábralo. Luego agrega estas líneas:

socket = /tmp/flask.sock
chmod-socket = 666

La primera línea le dice a uwsgi que cree un socket en la ubicación dada. El socket se utilizará para recibir solicitudes y enviar las respuestas. En la última línea permitimos que otros usuarios (incluido nginx) puedan leer y escribir desde ese socket.

Vuelva a iniciar uwsgi con uwsgi --ini uwsgi.ini . Ahora apunte su navegador de nuevo a localhost y verá nuevamente el saludo "Hola, uWSGI".

Tenga en cuenta que todavía puede ver la respuesta en localhost:5000 porque uWSGI ahora sirve la aplicación a través de http y el socket. Así que vamos a deshabilitar la opción http en el archivo ini

http = :5000  # <-- remove this line and restart uwsgi

Ahora solo se puede acceder a la aplicación desde nginx (o leer ese socket directamente :)).

Habilitar la transmisión desde el matraz

Flask tiene esa característica que le permite transmitir datos desde una vista mediante el uso de generadores.

Vamos a cambiar el archivo app.py

  • añadir from flask import Response
  • agregar from datetime import datetime
  • añadir from time import sleep
  • crear una nueva vista:
@app.route("/time/")
def time():
    def streamer():
        while True:
            yield "<p>{}</p>".format(datetime.now())
            sleep(1)

    return Response(streamer())

Ahora abra su navegador en localhost/time/ . El sitio se cargará para siempre porque nginx espera hasta que se complete la respuesta. En este caso, la respuesta nunca estará completa porque enviará la fecha y hora actuales para siempre.

Para evitar que nginx espere, debemos agregar una nueva línea a la configuración.

Edite /etc/nginx/sites-available/flaskconfig

server {
    listen 80;
    server_name localhost;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/flask.sock;
        uwsgi_buffering off;  # <-- this line is new
    }
}

La línea uwsgi_buffering off; le dice a nginx que no espere hasta que se complete una respuesta.

Reinicie nginx: sudo service nginx restart y observe localhost/time/ again.

Ahora verás que a cada segundo aparece una nueva línea.

Configure la aplicación Flask, uWGSI, Nginx - Plantilla de caldera de configuraciones de servidor (predeterminado, proxy y caché)

Esta es una parte de la configuración que se obtiene del tutorial de DigitalOcean de Cómo Servir las Aplicaciones de Flask con uWSGI y Nginx en Ubuntu 14.04

y algunos recursos git útiles para servidores nginx.

Aplicación del matraz

Este tutorial asume que usas Ubuntu.

  1. busque var/www/ folder.
  2. Crea tu carpeta de aplicaciones web mkdir myexample
  3. cd myexample

opcional Es posible que desee configurar un entorno virtual para implementar aplicaciones web en el servidor de producción.

sudo pip install virtualenv

para instalar el entorno virtual.

virtualenv myexample

para configurar el entorno virtual para su aplicación.

source myprojectenv/bin/activate 

para activar su entorno. Aquí instalarás todos los paquetes de python.

final opcional pero recomendado

Configurar frasco y puerta de enlace uWSGI

Instalar matraz y puerta de enlace uSWGI:

pip install uwsgi flask

Ejemplo de aplicación matraz en myexample.py:

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
    return "<h1>Hello World</h1>"

if __name__ == "__main__":
    application.run(host='0.0.0.0')

Cree un archivo para comunicarse entre su aplicación web y el servidor web: interfaz de puerta de enlace [ https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface]

nano wsgi.py

luego importe su módulo de aplicación web y hágalo funcionar desde el punto de entrada de la puerta de enlace.

from myexample import application

if __name__ == "__main__":
    application.run()

Para probar uWSGI:

uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi

Para configurar uWSGI:

  1. Crear un archivo de configuración .ini

    nano myexample.ini

  2. Configuración básica para gateway uWSGI

# include header for using uwsgi
[uwsgi]
# point it to your python module wsgi.py
module = wsgi
# tell uWSGI to start a master node to serve requests
master = true
# spawn number of processes handling requests
processes = 5
# use a Unix socket to communicate with Nginx. Nginx will pass connections to uWSGI through a socket, instead of using ports. This is preferable because Nginx and uWSGI stays on the same machine.
socket = myexample.sock
# ensure file permission on socket to be readable and writable
chmod-socket = 660
# clean the socket when processes stop
vacuum = true
# use die-on-term to communicate with Ubuntu versions using Upstart initialisations: see:
# http://uwsgi-docs.readthedocs.io/en/latest/Upstart.html?highlight=die%20on%20term
die-on-term = true

Opcional si está usando env virtual . Puede deactivate su entorno virtual.

Configuración de Nginx Vamos a utilizar nginx como:

  1. servidor predeterminado para pasar la solicitud al socket, utilizando el protocolo uwsgi
  2. servidor proxy delante del servidor predeterminado
  3. servidor de caché para almacenar en caché las solicitudes exitosas (como ejemplo, es posible que desee almacenar en caché las solicitudes GET si su aplicación web)

Localice su directorio de sites-available y cree un archivo de configuración para su aplicación:

sudo nano /etc/nginx/sites-available/myexample

Agregue el siguiente bloque, en comentarios lo que hace:

server {
   

    # setting up default server listening to port 80
    listen 8000 default_server;
    server_name myexample.com; #you can also use your IP 
    
    # specify charset encoding, optional
    charset utf-8;

    # specify root of your folder directory
    root /var/www/myexample;

    # specify locations for your web apps.
    # here using /api endpoint as example
    location /api {
        # include parameters of wsgi.py and pass them to socket
        include uwsgi_params;
        uwsgi_pass unix:/var/www/myexample/myexample.sock;
    }

}

# Here you will specify caching zones that will be used by your virtual server
# Cache will be stored in /tmp/nginx folder
# ensure nginx have permissions to write and read there!
# See also:
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html

proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";

# set up the virtual host!
server {
    listen   80  default_server;
    
    # Now www.example.com will listen to port 80 and pass request to http://example.com
    server_name www.example.com;

    # Why not caching responses

    location /api {
        # set up headers for caching
        add_header X-Proxy-Cache $upstream_cache_status;

        # use zone specified above
        proxy_cache my_zone;
        proxy_cache_use_stale updating;
        proxy_cache_lock on;
        
        # cache all responses ?
        # proxy_cache_valid 30d;

        # better cache only 200 responses :)
        proxy_cache_valid 200 30d;

        # ignore headers to make cache expire
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;

        # pass requests to default server on port 8000
        proxy_pass http://example.com:8000/api;
    }
}

Finalmente, vincule el archivo al directorio de sites-enabled . Para obtener una explicación de los sitios disponibles y habilitados, consulte la respuesta: [ http://serverfault.com/a/527644]

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

Ya has terminado con nginx. Sin embargo, es posible que desee revisar esta preciosa plantilla de caldera: [ https://github.com/h5bp/server-configs-nginx]

Muy útil para el ajuste fino.

Ahora prueba Nginx:

sudo nginx -t

Lanzar Nginx:

sudo service nginx restart

Automatice Ubuntu para iniciar uWSGI Lo último es hacer que Ubuntu inicie la puerta de enlace wsgi comunicándose con su aplicación, de lo contrario debería hacerlo manualmente.

  1. Localice el directorio para los scripts de inicialización en Ubuntu y cree un nuevo script:

sudo nano /etc/init/myexample.conf

  1. Agregue el siguiente bloque, comentarios en línea para explicar lo que hace

    # description for the purpose of this script
    description "uWSGI server instance configured to serve myproject"
    
    # Tell to start on system runtime 2, 3, 4, 5. Stop at any other level (0,1,6). 
    # Linux run levels: [http://www.debianadmin.com/debian-and-ubuntu-linux-run-levels.html]
    start on runlevel [2345]
    stop on runlevel [!2345]
    
    # Set up permissions! "User" will be the username of your user account on ubuntu.
    setuid user
    # Allow www-data group to read and write from the socket file. 
    # www-data is normally the group Nginx and your web applications belong to.
    # you may have all web application projects under /var/www/ that belongs to www-data group
    setgid www-data
    
    # tell Ubunutu which environment to use.
    # This is the path of your virtual environment: python will be in this path if you installed virtualenv. Otherwise, use path of your python installation
    env PATH=/var/www/myexample/myexample/bin
    # then tell to Ubuntu to change and locate your web application directory
    chdir /var/www/myexample
    # finally execute initialisation script, that load your web app myexample.py
    exec uwsgi --ini myexample.ini
    
    

Ahora puedes activar tu script: sudo start myexample



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow