Sök…


Använda uWSGI för att köra en kolvapplikation

Den inbyggda werkzeug servern werkzeug verkligen inte för att köra produktionsservrar. Det mest uppenbara skälet är det faktum att werkzeug servern är enkeltrådad och därför bara kan hantera en begäran åt gången.

På grund av detta vill vi använda uWSGI-servern för att betjäna vår applikation istället. I det här exemplet kommer vi att installera uWSGI och köra en enkel testapplikation med den.

Installera uWSGI :

pip install uwsgi

Det är så enkelt som det. Om du är osäker på pythonversionen som din pip använder gör det uttryckligt:

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

Låt oss nu skapa en enkel testapplikation:

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

I kolven är det konventionella namnet för applikationen app men uWSGI letar efter application standard. Det är därför vi skapar ett alias för vår app i den sista raden.

Nu är det dags att köra appen:

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

Du bör se meddelandet "Hej uWSGI ..." genom att peka din webbläsare till localhost:5000

För att inte skriva in hela kommandot varje gång skapar vi en uwsgi.ini fil för att lagra den konfigurationen:

uwsgi.ini

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

wsgi-file http och wsgi-file är desamma som i det manuella kommandot. Men det finns ytterligare tre alternativ:

  • single-interpreter : Det rekommenderas att slå på det eftersom det kan störa nästa alternativ

  • enable-threads : Detta måste vara på om du använder ytterligare trådar i din applikation. Vi använder dem inte just nu men nu behöver vi inte oroa oss för det.

  • master : Master-läget bör vara aktiverat av olika skäl

Nu kan vi köra appen med det här kommandot:

uwsgi --ini uwsgi.ini

Installera nginx och ställa in det för uWSGI

Nu vill vi installera nginx för att betjäna vår applikation.

sudo apt-get install nginx  # on debian/ubuntu

Sedan skapar vi en konfiguration för vår webbplats

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;
    }
}

Detta säger nginx att lyssna på port 80 (standard för http) och tjäna något på rotvägen ( / ). Där berättar vi för nginx att bara fungera som en proxy och överföra varje förfrågan till ett uttag som heter flask.sock beläget i /tmp/ .

Låt oss aktivera webbplatsen:

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

Du kanske vill ta bort standardkonfigurationen om den är aktiverad:

# inside /etc/sites-enabled
sudo rm default

Starta sedan om nginx:

sudo service nginx restart

Rikta din webbläsare till localhost så ser du ett fel: 502 Bad Gateway .

Detta betyder att nginx är igång och fungerar men uttaget saknas. Så låt oss skapa det.

Gå tillbaka till din uwsgi.ini fil och öppna den. Lägg sedan till dessa rader:

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

Den första raden berättar uwsgi att skapa ett uttag på den angivna platsen. Socket kommer att användas för att ta emot förfrågningar och skicka tillbaka svaren. I den sista raden tillåter vi andra användare (inklusive nginx) att kunna läsa och skriva från det uttaget.

Börja uwsgi igen med uwsgi --ini uwsgi.ini . Peka nu webbläsaren igen till localhost så ser du hälsningen "Hej uWSGI" igen.

Observera att du fortfarande kan se svaret på localhost:5000 eftersom uWSGI nu betjänar applikationen via http och socket. Så låt oss inaktivera http-alternativet i ini-filen

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

Nu kan appen bara nås från nginx (eller läsa det uttaget direkt :)).

Aktivera strömning från kolven

Flask har den funktionen som låter dig strömma data från en vy med hjälp av generatorer.

Låt oss ändra app.py filen

  • lägg till from flask import Response
  • lägg till from datetime import datetime
  • lägg till from time import sleep
  • skapa en ny vy:
@app.route("/time/")
def time():
    def streamer():
        while True:
            yield "<p>{}</p>".format(datetime.now())
            sleep(1)

    return Response(streamer())

Öppna nu din webbläsare på localhost/time/ . Webbplatsen laddas för evigt eftersom nginx väntar tills svaret är fullständigt. I detta fall kommer svaret aldrig att vara fullständigt eftersom det skickar aktuellt datum och tid för alltid.

För att förhindra att nginx väntar måste vi lägga till en ny rad i konfigurationen.

Redigera /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
    }
}

Linjen uwsgi_buffering off; säger nginx att inte vänta tills svaret har slutförts.

Starta om nginx: sudo service nginx restart och titta på localhost/time/ gång.

Nu ser du att varje sekund dyker upp en ny linje.

Ställ in Flask Application, uWGSI, Nginx - Server Configurationations pannmall (standard, proxy och cache)

Detta är en porting av uppsättningar som kommer från DigitalOcean's handledning om hur man serverar kolvapplikationer med uWSGI och Nginx på Ubuntu 14.04

och några användbara git-resurser för nginx-servrar.

Kolvansökan

Denna handledning antar att du använder Ubuntu.

  1. hitta var/www/ mapp.
  2. Skapa din mkdir myexample mapp mkdir myexample
  3. cd myexample

valfritt Du kanske vill ställa in virtuell miljö för distribution av webbapplikationer på produktionsservern.

sudo pip install virtualenv

att installera virtuell miljö.

virtualenv myexample

för att ställa in virtuell miljö för din app.

source myprojectenv/bin/activate 

för att aktivera din miljö. Här installerar du alla pythonpaket.

slut valfritt men rekommenderas

Ställ in kolven och gateway uWSGI

Installera kolven och uSWGI-gateway:

pip install uwsgi flask

Exempel på flask-app i 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')

Skapa fil för att kommunicera mellan din webbapp och webbservern: gateway-gränssnitt [ https://sv.wikipedia.org/wiki/Web_Server_Gateway_Interface]

nano wsgi.py

importera sedan din webbappmodul och låt den köras från gateway-startpunkten.

from myexample import application

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

Så här testar du uWSGI:

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

Så här konfigurerar du uWSGI:

  1. Skapa en konfigurationsfil .ini

    nano myexample.ini

  2. Grundläggande konfiguration för 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

valfritt om du använder virtuell env. Du kan deactivate din virtuella miljö.

Nginx-konfiguration Vi ska använda nginx som:

  1. standardserver för att skicka förfrågan till uttaget med dittsgiprotokoll
  2. proxy-server framför standardservern
  3. cachserver för cache framgångsrika förfrågningar (som exempel kanske du vill cache GET-förfrågningar om din webbapplikation)

Leta reda på din katalog som är sites-available och skapa en konfigurationsfil för din applikation:

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

Lägg till följande block, i kommentarer vad det gör:

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;
    }
}

Slutligen, länka filen till en sites-enabled katalog. För svar på tillgängliga och aktiverade webbplatser, se svar: [ http://serverfault.com/a/527644]

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

Du är klar nu med nginx. Du kanske dock vill kolla in den här mycket värdefulla pannmallen: [ https://github.com/h5bp/server-configs-nginx]

Mycket användbart för finjustering.

Testa nu Nginx:

sudo nginx -t

Starta Nginx:

sudo service nginx restart

Automatisera Ubuntu för att starta uWSGI Det sista är att få Ubuntu att starta wsgi-gatewayen som kommunicerar med din applikation, annars bör du göra det manuellt.

  1. Leta upp katalog för initialiseringsskript i Ubuntu och skapa ett nytt skript:

sudo nano /etc/init/myexample.conf

  1. Lägg till följande block, kommentarer i rad för att förklara vad det gör

    # 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
    
    

Nu kan du aktivera ditt skript: sudo start myexample



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow