当启动一个Flask APP如下,在同一浏览器开2个窗口访问这个服务(我的是http://172.18.43.32:8001/hello),前一个请求没返回时,另外一个窗口的相同请求不会有反应。
这是浏览器的锅,同一请求会顺序执行,此时可以用同一台电脑的不同浏览器测试,可以发现不会存在路由阻塞。
python展开代码import time
from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello_world():
    print("receive !")
    time.sleep(20)
    return 'Hello World!'
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8001)
python展开代码import requests
from concurrent.futures import ThreadPoolExecutor
def task():
    res = requests.request(method="GET", url="http://172.18.43.32:8001/hello", timeout=None)
executor = ThreadPoolExecutor(max_workers=100)
for i in range(100):
    executor.submit(task)
还是可以看见不会阻塞。
下面的情况下,访问就会阻塞。
python展开代码# -*- coding:utf-8 -*-
import asyncio
import time
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from fastapi import FastAPI, File, Form, UploadFile
import cv2
import numpy as np
app = FastAPI(
    title='FastAPI Tutorial',
    description='FastAPI教程',
    version='1.0.0',
    docs_url='/docs',
    redoc_url='/redocs',
)
@app.get("/hello")
async def hl():
    print("receive !")
    time.sleep(20)
    return {
        "token": "ads"
    }
def fastweb():
    uvicorn.run('deal:app', host='0.0.0.0', port=8001, reload=False, debug=False, workers=1)
if __name__ == '__main__':
    fastweb()
原因:在async标识的函数中使用同步方法time.sleep(20),这导致了一个异步程序之间的同步问题,出现了错误!这种写法本身就是错误的,加async 是想利用Python的协程机制 将路由变成异步请求, 进一步提高并发量!只要考虑加async ,那么就得好好设计函数内部, 多用一些异步方法,比如可以写成:
python展开代码@app.get("/hello")
async def hl():
    print("receive !")
    await asyncio.sleep(20)
    return {
        "token": "ads"
    }
设计合理就会极大利用起协程异步,从而极大提高并发量,设计不合理就是呆瓜。若是分不清,还是老老实实和Flask一样写法:
python展开代码@app.get("/hello")
def hl():
    print("receive !")
    time.sleep(20)
    return {
        "token": "ads"
    }
这样也是出现不了路由阻塞的。
1 Flask 中的属于同步并发,可以无阻塞访问!但要注意别让浏览器欺骗你!
2 FastAPI 支持异步框架,支持是支持,前提是你得用好它,不然就呆瓜。用好了并发量就提升了!
3 FastAPI 中同样支持Flask 那样子的同步并发,和Flask 一样一样的,但要注意写法!
4 FastAPI 貌似比 Flask 更强大!
java web
golang 协程


本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!