Flask 獨立 WSGI 容器

2021-08-11 10:43 更新

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

Gunicorn

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

gunicorn myproject:app

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

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

Tornado

Tornado 是一個開源的可伸縮的、非阻塞式的 web 服務(wù)器和工具集,它驅(qū)動了 FriendFeed 。因為它使用了 epoll 模型且是非阻塞的,它可以處理數(shù)以千計 的并發(fā)固定連接,這意味著它對實時 web 服務(wù)是理想的。把 Flask 集成這個服務(wù) 是直截了當?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)絡(luò)庫,使用 greenlet 來在 libevent 的事件循環(huán)上提供高層的同步 API

from gevent.wsgi import WSGIServer
from yourapplication import app

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

代理設(shè)置

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

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

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 設(shè)置的主機 名和從 X-Forwarded-For 設(shè)置的遠程地址:

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)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號