在 Flask 應用中使用 gevent

2022-02-28 12:08:23 字數 2211 閱讀 2451

from flask import flask

def hello():

return 'hello world'

if __name__ == '__main__':

然而 flask 是單執行緒執行,如果在某個頁面中執行了一些耗時的工作,那麼程式就會在這裡等待,無法響應其他的請求。也就是說,如果乙個路由響應函式中有阻塞**,那麼其他使用者無法訪問這個 web 伺服器,而且自己也打不開其他頁面了。

在乙個路由中新增阻塞**,如下所示:

from time import sleep

def test_sleep():

sleep( 10 )

return 'hi, you wait for about 10 seconds, right?'

當開啟/testsleep頁面時,會發現瀏覽器一直在載入過程中,再去開啟/頁面,發現這個頁面也是在載入中。只有等到/testsleep頁面載入完了,才會去載入/頁面。

為了解決乙個頁面耗時導致所有頁面都無法訪問的問題。考慮使用 gevent 非阻塞的執行伺服器程式。在引入 gevent 前,可以在程式最開始執行的位置引入猴子補丁gevent.monkey,這能修改 python 預設的 io 行為,讓標準庫變成 協作式(cooperative)的 api。注意引入 gevent 後,不能再用原來的方式啟動我們的 web 應用了:

from gevent import monkey

monkey.patch_all() # 打上猴子補丁

from flask import flask

...if __name__ == '__main__':

from gevent import pywsgi

server.serve_forever()

這個時候再去開啟/testsleep頁面,還是要等待一些時間才會載入完頁面,但是這個時候已經訪問/頁面將會立即載入完畢。

if __name__ == '__main__':

server.serve_forever()

重新開啟首頁,可以看到熟悉的錯誤資訊。

...if __name__ == '__main__':

...from werkzeug.serving import run_with_reloader

run_with_reloader( server ).serve_forever()

然而如果你這樣做了就會發現一點用都沒有,甚至連 web 應用都不能正常啟動了。

按照這個思路來的還有這段**提供的 示例,但這個示例是將run_with_reloader作為裝飾器來使用,以下是該示例的**:

import gevent.wsgi

import werkzeug.serving

@werkzeug.serving.run_with_reloader

def runserver():

ws.serve_forever()

然而這也沒有什麼作用。看一下 flask 的源**可以發現,run_with_reloader 已經不是裝飾器了。而且開發者提醒我們不要使用下面的這個函式,這個 api 很明顯已經被廢棄了,flask 源**如下:

def run_with_reloader(*args, **kwargs):

# people keep using undocumented apis. do not use this function

# please, we do not guarantee that it continues working.

from werkzeug._reloader import run_with_reloader

return run_with_reloader(*args, **kwargs)

如果使用 gevent 作為 wsgi 的閘道器伺服器,似乎就沒法使用自動載入應用的功能了。

關於檔案改動事件,之前我也寫過乙個類似的 js 程式,原理類似,都是當檔案改動時自動執行重新構建應用的命令。

gevent monkey

hot reload gevent wsgiserver

gist

code snippet

廖雪峰 python 教程

django中使用celery及gevent

celery是分布式非同步任務佇列,通過在django中整合celery任務,可實現工作流的定製 非同步執行i o工作量大的任務 定時任務。下面的例子,給出了定時任務的實現過程。原始碼 django admin startproject mysite在mysite下建立poll應用 2 建立後mys...

python3在flask中使用mysql報錯

今天在python3 flask中使用mysql 無論怎麼弄都報錯 importerror no module named mysqldb 按照 stack overflow 上 說pip install mysqlclient或者pip install mysql python 結果都安裝不上,最...

在Flask中使用模板變數,並賦值

處為模板變數的名字,模板變數使用兩個花括號表示 2 python程式 匯入flask模組 from flask import flask,render template 使用定義的flask方法來定義路由 def 使用return函式來返回結果,記得使用render template 並使用rend...