Flask 獨立 WSGI 容器

2021-08-11 10:43 更新

有用 Python 編寫的流行服務器來容納 WSGI 應用并提供 HTTP 服務。這些服務器在運行 時是獨立的:你可以從你的 web 服務器設置到它的代理。如果你遇見問題,請注意 代理設置 一節(jié)的內容。

Gunicorn

Gunicorn ‘Green Unicorn’ 是一個給 UNIX 用的 WSGI HTTP 服務器。這是一個從 Ruby 的 Unicorn 項目移植的 pre-fork worker 模式。它既支持 eventlet ,也 支持 greenlet 。在這個服務器上運行 Flask 應用是相當簡單的:

gunicorn myproject:app

Gunicorn 提供了許多命令行選項 —— 見 gunicorn -h 。 例如,用四個 worker 進程( gunicorn -h )來運行一個 Flask 應用,綁定 到 localhost 的4000 端口( -b 127.0.0.1:4000 ):

gunicorn -w 4 -b 127.0.0.1:4000 myproject:app

Tornado

Tornado 是一個開源的可伸縮的、非阻塞式的 web 服務器和工具集,它驅動了 FriendFeed 。因為它使用了 epoll 模型且是非阻塞的,它可以處理數(shù)以千計 的并發(fā)固定連接,這意味著它對實時 web 服務是理想的。把 Flask 集成這個服務 是直截了當?shù)?

from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from yourapplication import app

http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()

Gevent

Gevent 是一個基于協(xié)同程序的 Python 網(wǎng)絡庫,使用 greenlet 來在 libevent 的事件循環(huán)上提供高層的同步 API

from gevent.wsgi import WSGIServer
from yourapplication import app

http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()

代理設置

如果你在一個 HTTP 代理后把你的應用部署到這些服務器中的之一,你需要重寫一些標頭 來讓應用正常工作。在 WSGI 環(huán)境中兩個有問題的值通常是 REMOTE_ADDRHTTP_HOST 。你可以配置你的 httpd 來傳遞這些標頭,或者在中間件中手動修正。 Werkzeug 帶有一個修正工具來解決常見的配置,但是你可能想要為特定的安裝自己寫 WSGI 中間件。

這是一個簡單的 nginx 配置,它監(jiān)聽 localhost 的 8000 端口,并提供到一個應用的 代理,設置了合適的標頭:

server {
    listen 80;

    server_name _;

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

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

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

如果你的 httpd 不提供這些標頭,最常見的配置引用從 X-Forwarded-Host 設置的主機 名和從 X-Forwarded-For 設置的遠程地址:

from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

信任標頭

請記住在一個非代理配置中使用這樣一個中間件會是一個安全問題,因為它盲目地信任 一個可能由惡意客戶端偽造的標頭。

如果你想從另一個標頭重寫標頭,你可能會使用這樣的一個修正程序:

class CustomProxyFix(object):

    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        host = environ.get('HTTP_X_FHOST', '')
        if host:
            environ['HTTP_HOST'] = host
        return self.app(environ, start_response)

app.wsgi_app = CustomProxyFix(app.wsgi_app)


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號