簡體   English   中英

在使用Gunicorn和Gevent運行Flask時,請求包含請求的非阻塞請求

[英]Make a non-blocking request with requests when running Flask with Gunicorn and Gevent

我的Flask應用程序將收到一個請求,進行一些處理,然后向一個需要5秒鍾響應的慢速外部端點發出請求。 看起來使用Gevent運行Gunicorn將允許它同時處理許多這些慢速請求。 如何修改下面的示例以使視圖無阻塞?

import requests

@app.route('/do', methods = ['POST'])
def do():
    result = requests.get('slow api')
    return result.content
gunicorn server:app -k gevent -w 4

如果您使用gunicorn部署Flask應用程序,它已經是非阻塞的。 如果客戶端正在等待您的某個視圖的響應,則另一個客戶端可以毫無問題地向同一視圖發出請求。 將有多個工作人員同時處理多個請求。 無需更改代碼即可實現此功能。 這也適用於幾乎所有Flask部署選項。

首先是一些背景,阻塞套接字是默認類型的套接字,一旦你開始閱讀你的應用程序或線程在實際讀取數據或斷開連接之前無法重新獲得控制權。 這就是python-requests的默認操作方式。 有一個名為grequests ,它提供非阻塞讀取。

主要的機械差異是send,recv,connect和accept可以在沒有做任何事情的情況下返回。 你(當然)有很多選擇。 您可以檢查返回代碼和錯誤代碼,通常會讓自己發瘋。 如果你不相信我,請嘗試一下

資料來源: https//docs.python.org/2/howto/sockets.html

它還繼續說:

毫無疑問,最快的套接字代碼使用非阻塞套接字並選擇多路復用它們。 您可以將可以使LAN連接飽和的東西放在一起,而不會給CPU帶來任何壓力。 麻煩的是,以這種方式編寫的應用程序無法做任何其他事情 - 它需要隨時准備好隨機播放字節。

假設您的應用實際上應該做更多的事情,線程是最佳解決方案

但是,您是否希望通過生成自己的線程來為視圖添加大量復雜性。 特別是當gunicorn作為異步工人

可用的異步工作程序基於Greenlets(通過Eventlet和Gevent)。 Greenlets是Python的協作多線程的實現。 通常,應用程序應該能夠使用這些工作類而不進行任何更改。

需要異步工作程序的一些行為示例:進行長阻塞調用的應用程序(即外部Web服務)

所以長話短說,不要改變任何東西! 隨它去吧。 如果您要進行任何更改,請使用它來引入緩存。 考慮使用由python-requests開發人員推薦的擴展控件

您可以使用grequests 它允許其他greenlet在請求時運行。 它與requests庫兼容並返回requests.Response對象。 用法如下:

import grequests

@app.route('/do', methods = ['POST'])
def do():
    result = grequests.map([grequests.get('slow api')])
    return result[0].content

編輯:我添加了一個測試,看到時間沒有隨着問候而改善,因為gunicorn的gevent worker在初始化時已經執行了猴子修補: https//github.com/benoitc/gunicorn/blob/master/gunicorn /workers/ggevent.py#L65

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM