Szukaj…


Używanie uWSGI do uruchomienia aplikacji kolby

Wbudowany serwer werkzeug pewnością nie nadaje się do uruchamiania serwerów produkcyjnych. Najbardziej oczywistym powodem jest fakt, że serwer werkzeug jest jednowątkowy, a zatem może obsłużyć tylko jedno żądanie na raz.

Z tego powodu chcemy używać serwera uWSGI do obsługi naszej aplikacji. W tym przykładzie zainstalujemy uWSGI i uruchomimy z nim prostą aplikację testową.

Instalowanie uWSGI :

pip install uwsgi

To takie proste. Jeśli nie masz pewności co do wersji Pythona, której używa pip, wyraź to:

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

Teraz stwórzmy prostą aplikację testową:

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

W kolbie konwencjonalną nazwą aplikacji jest app ale uWSGI domyślnie szuka application . Dlatego w ostatnim wierszu tworzymy alias dla naszej aplikacji.

Teraz nadszedł czas, aby uruchomić aplikację:

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

Powinieneś zobaczyć komunikat „Hello uWSGI ...”, wskazując przeglądarkę na localhost:5000

Aby nie wpisywać pełnego polecenia za każdym razem, tworzymy plik uwsgi.ini do przechowywania tej konfiguracji:

uwsgi.ini

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

Opcje wsgi-file http i wsgi-file są takie same jak w poleceniu ręcznym. Ale są jeszcze trzy opcje:

  • single-interpreter : Zaleca się włączyć to, ponieważ może to zakłócać następną opcję

  • enable-threads : To musi być włączone, jeśli używasz dodatkowych wątków w swojej aplikacji. Nie używamy ich teraz, ale teraz nie musimy się tym martwić.

  • master : Tryb Master powinien być włączony z różnych powodów

Teraz możemy uruchomić aplikację za pomocą tego polecenia:

uwsgi --ini uwsgi.ini

Instalowanie nginx i konfigurowanie go dla uWSGI

Teraz chcemy zainstalować nginx, aby obsługiwał naszą aplikację.

sudo apt-get install nginx  # on debian/ubuntu

Następnie tworzymy konfigurację dla naszej strony internetowej

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

To każe nginx nasłuchiwać na porcie 80 (domyślnie dla http) i podawać coś w ścieżce katalogu głównego ( / ). Mówimy tam, aby nginx działał po prostu jako serwer proxy i przekazywał każde żądanie do gniazda o nazwie flask.sock znajdującego się w /tmp/ .

Włączmy witrynę:

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

Możesz usunąć domyślną konfigurację, jeśli jest włączona:

# inside /etc/sites-enabled
sudo rm default

Następnie uruchom ponownie nginx:

sudo service nginx restart

Skieruj przeglądarkę na localhost a zobaczysz błąd: 502 Bad Gateway .

Oznacza to, że nginx działa i działa, ale brakuje gniazda. Stwórzmy to.

Wróć do pliku uwsgi.ini i otwórz go. Następnie dodaj te linie:

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

Pierwszy wiersz mówi uwsgi, aby utworzyło gniazdo w danej lokalizacji. Gniazdo będzie używane do odbierania żądań i wysyłania odpowiedzi. W ostatnim wierszu zezwalamy innym użytkownikom (w tym nginx) na odczyt i zapis z tego gniazda.

Uruchom uwsgi ponownie za pomocą uwsgi --ini uwsgi.ini . Teraz ponownie skieruj przeglądarkę na localhost a ponownie zobaczysz powitanie „Hello uWSGI”.

Zauważ, że nadal możesz zobaczyć odpowiedź na localhost:5000 ponieważ uWSGI obsługuje teraz aplikację przez http i gniazdo. Wyłączmy więc opcję http w pliku ini

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

Teraz do aplikacji można uzyskać dostęp tylko z nginx (lub bezpośrednio czytając to gniazdo :)).

Włącz strumieniowanie z kolby

Flask ma tę funkcję, która pozwala przesyłać strumieniowo dane z widoku za pomocą generatorów.

app.py plik app.py

  • dodaj from flask import Response
  • dodaj from datetime import datetime
  • dodaj from time import sleep
  • utwórz nowy widok:
@app.route("/time/")
def time():
    def streamer():
        while True:
            yield "<p>{}</p>".format(datetime.now())
            sleep(1)

    return Response(streamer())

Teraz otwórz przeglądarkę na localhost/time/ . Witryna będzie się ładować na zawsze, ponieważ nginx czeka na odpowiedź do końca. W takim przypadku odpowiedź nigdy nie będzie kompletna, ponieważ na zawsze wyśle bieżącą datę i godzinę.

Aby zapobiec oczekiwaniu nginx, musimy dodać nowy wiersz do konfiguracji.

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

Linia uwsgi_buffering off; mówi nginx, aby nie czekał na odpowiedź do końca.

Zrestartuj nginx: sudo service nginx restart i spójrz na localhost/time/ again.

Teraz zobaczysz, że co sekundę pojawia się nowa linia.

Skonfiguruj aplikację Flask, uWGSI, Nginx - szablon kotła Konfiguracje serwera (domyślnie, proxy i pamięć podręczna)

Jest to portowanie konfiguracji pochodzącej z samouczka DigitalOcean na temat obsługi aplikacji Flask za pomocą uWSGI i Nginx na Ubuntu 14.04

i kilka przydatnych zasobów git dla serwerów nginx.

Aplikacja na kolbę

W tym samouczku założono, że używasz Ubuntu.

  1. zlokalizuj folder var/www/ .
  2. Utwórz folder aplikacji internetowej mkdir myexample
  3. cd myexample

opcjonalnie Możesz skonfigurować środowisko wirtualne do wdrażania aplikacji internetowych na serwerze produkcyjnym.

sudo pip install virtualenv

zainstalować środowisko wirtualne.

virtualenv myexample

skonfigurować środowisko wirtualne dla Twojej aplikacji.

source myprojectenv/bin/activate 

aby aktywować środowisko. Tutaj zainstalujesz wszystkie pakiety Pythona.

koniec opcjonalny, ale zalecany

Skonfiguruj skrzynkę i bramę uWSGI

Zainstaluj kolbę i bramę uSWGI:

pip install uwsgi flask

Przykład aplikacji flask w 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')

Utwórz plik do komunikacji między aplikacją internetową a serwerem: interfejs bramy [ https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface]

nano wsgi.py

następnie zaimportuj moduł aplikacji internetowej i uruchom go z punktu wejścia bramy.

from myexample import application

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

Aby przetestować uWSGI:

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

Aby skonfigurować uWSGI:

  1. Utwórz plik konfiguracyjny .ini

    nano myexample.ini

  2. Podstawowa konfiguracja bramki 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

opcjonalne, jeśli używasz wirtualnej env Możesz deactivate swoje wirtualne środowisko.

Konfiguracja Nginx Użyjemy nginx jako:

  1. domyślny serwer do przekazywania żądań do gniazda przy użyciu protokołu uwsgi
  2. serwer proxy przed domyślnym serwerem
  3. buforuj serwer w celu buforowania udanych żądań (na przykład możesz chcieć buforować żądania GET, jeśli twoja aplikacja internetowa)

Znajdź katalog sites-available dla sites-available i utwórz plik konfiguracyjny dla swojej aplikacji:

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

Dodaj następujący blok, w komentarzach, co robi:

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

Na koniec połącz plik z katalogiem sites-enabled . Aby uzyskać wyjaśnienie dostępnych i włączonych witryn, zobacz odpowiedź: [ http://serverfault.com/a/527644]

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

Skończyłeś z nginx. Możesz jednak sprawdzić ten bardzo cenny szablon kotła: [ https://github.com/h5bp/server-configs-nginx]

Bardzo przydatne do precyzyjnego strojenia.

Teraz przetestuj Nginx:

sudo nginx -t

Uruchom Nginx:

sudo service nginx restart

Zautomatyzuj Ubuntu, aby uruchomić uWSGI Ostatnią rzeczą jest, aby Ubuntu uruchomił bramę wsgi komunikującą się z twoją aplikacją, w przeciwnym razie powinieneś zrobić to ręcznie.

  1. Znajdź katalog skryptów inicjujących w Ubuntu i utwórz nowy skrypt:

sudo nano /etc/init/myexample.conf

  1. Dodaj następujący blok, komentarze w linii, aby wyjaśnić, co robi

    # 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
    
    

Teraz możesz aktywować skrypt: sudo uruchom mój przykład



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow