国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

FastAPI性能對(duì)比:同步vs異步

開(kāi)發(fā) 前端
如果你的應(yīng)用程序需要處理大量并發(fā)用戶,并嚴(yán)重依賴于I/O綁定任務(wù),那么異步FastAPI可以提供更好的性能、可擴(kuò)展性和響應(yīng)能力。

FastAPI已成為構(gòu)建Python API的最流行框架之一,因其速度和易用性而廣受歡迎。但在構(gòu)建高性能應(yīng)用程序時(shí),有一個(gè)重要問(wèn)題需要回答:應(yīng)該使用同步(sync)還是異步(async)代碼執(zhí)行?

在本文中,我們將通過(guò)現(xiàn)實(shí)世界的性能測(cè)試,對(duì)同步和異步的FastAPI實(shí)現(xiàn)進(jìn)行基準(zhǔn)測(cè)試,并深入分析相關(guān)數(shù)據(jù),以幫助開(kāi)發(fā)者決定何時(shí)使用這兩種方法。

一、同步與異步在FastAPI中的區(qū)別是什么?

  • 同步代碼(sync):在同步執(zhí)行中,任務(wù)一個(gè)接一個(gè)地處理。每個(gè)請(qǐng)求都需要等待前一個(gè)請(qǐng)求完成,這在用戶數(shù)量較多或存在慢I/O操作(如數(shù)據(jù)庫(kù)查詢或文件上傳)時(shí),可能會(huì)導(dǎo)致瓶頸。
  • 異步代碼(async):異步執(zhí)行支持多個(gè)請(qǐng)求并發(fā)處理。應(yīng)用程序無(wú)需等待I/O操作(如數(shù)據(jù)庫(kù)調(diào)用)完成,而是可以繼續(xù)處理其他請(qǐng)求,從而在高并發(fā)環(huán)境中更有效率。

那么,這兩者在性能上的真實(shí)差異是什么呢?讓我們來(lái)看看。

二、設(shè)置:在FastAPI中基準(zhǔn)測(cè)試同步與異步

為了比較同步和異步實(shí)現(xiàn),在這里創(chuàng)建了兩個(gè)版本的FastAPI應(yīng)用程序。

  1. 同步版本:使用傳統(tǒng)的阻塞數(shù)據(jù)庫(kù)查詢,采用psycopg2。
  2. 異步版本:使用非阻塞的異步查詢,采用asyncpg。

這兩個(gè)版本都執(zhí)行一個(gè)簡(jiǎn)單的任務(wù):從PostgreSQL數(shù)據(jù)庫(kù)查詢用戶。數(shù)據(jù)庫(kù)中包含極少的數(shù)據(jù),以便隔離同步/異步機(jī)制的影響。

技術(shù)棧:

  • 使用FastAPI作為API框架。
  • 使用SQLAlchemy作為ORM。
  • 使用psycopg2或psycopg2-binary(同步)和asyncpg(異步)進(jìn)行數(shù)據(jù)庫(kù)連接。
  • 使用PostgreSQL作為數(shù)據(jù)庫(kù)。

為了測(cè)試性能,使用**Apache Benchmark(ab)**模擬了1000個(gè)請(qǐng)求,具有100個(gè)并發(fā)連接。

2.1 同步版本代碼 ??

在同步版本中,在這里使用psycopg2驅(qū)動(dòng)與SQLAlchemy,后者可執(zhí)行阻塞查詢。表格是使用同步的SQLAlchemy引擎創(chuàng)建的。

同步:main.py

from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from .database import get_db, User

app = FastAPI()

@app.get("/users/{user_id}")
def get_user(user_id: int, db: Session = Depends(get_db)):
    # 同步和阻塞
    user = db.query(User).filter(User.c.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return {"id": user.id, "name": user.name, "email": user.email}

同步:database.py

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "postgresql://user:password@localhost/db_name"

# 創(chuàng)建同步的SQLAlchemy引擎
engine = create_engine(DATABASE_URL, echo=True)

# 創(chuàng)建用于同步查詢的會(huì)話生成器
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)

# 定義元數(shù)據(jù)
metadata = MetaData()

# 定義User表
User = Table(
    "users", metadata,
    Column("id", Integer, primary_key=True),
    Column("name", String),
    Column("email", String),
)

# 在數(shù)據(jù)庫(kù)中創(chuàng)建表
metadata.create_all(engine)

# 獲取同步數(shù)據(jù)庫(kù)會(huì)話的依賴
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

2.2 異步版本代碼 ??

在異步版本中,在這里使用asyncpg驅(qū)動(dòng)與SQLAlchemy,進(jìn)行非阻塞查詢。然而,表的創(chuàng)建仍然是同步進(jìn)行的,因?yàn)镾QLAlchemy的metadata.create_all()不支持異步。

異步:main.py

from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from .database import get_async_db, User, initialize_database


@asynccontextmanager
async def lifespan(app: FastAPI):
    # 啟動(dòng):初始化數(shù)據(jù)庫(kù)
    await initialize_database()
    yield


app = FastAPI(lifespan=lifespan)


@app.get("/users/{user_id}")
async def get_user(user_id: int, db: AsyncSession = Depends(get_async_db)):
    result = await db.execute(select(User).where(User.c.id == user_id))
    user = result.fetchone()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return {"id": user.id, "name": user.name, "email": user.email}

異步:database.py

from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import MetaData, Table, Column, Integer, String

DATABASE_URL = "postgresql+asyncpg://user:password@localhost/db_name"

# 用于異步查詢的異步引擎
engine = create_async_engine(
    DATABASE_URL,
    echo=True,
    pool_size=10,
    max_overflow=20,
)

# 用于異步查詢的異步會(huì)話
AsyncSessionLocal = sessionmaker(
    bind=engine, class_=AsyncSession, expire_on_commit=False
)

# 定義元數(shù)據(jù)
metadata = MetaData()

# 定義User表
users = Table(
    "users",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("name", String),
    Column("email", String),
)


# 創(chuàng)建所有表
async def init_db():
    async with engine.begin() as conn:
        await conn.run_sync(metadata.create_all)


# 獲取異步數(shù)據(jù)庫(kù)會(huì)話的依賴
async def get_async_db():
    async with AsyncSessionLocal() as session:
        yield session

# 啟動(dòng):初始化數(shù)據(jù)庫(kù)
async def initialize_database():
    await init_db()

在這個(gè)版本中,請(qǐng)求是以異步方式處理的,支持多個(gè)請(qǐng)求在等待I/O時(shí)并發(fā)處理。

三、基準(zhǔn)測(cè)試命令

  1. 同步版本:ab -n 1000 -c 100 http://127.0.0.1:8000/users/1
  2. 異步版本:ab -n 1000 -c 100 http://127.0.0.1:8001/users/1

基準(zhǔn)測(cè)試結(jié)果:同步vs異步

以下是基準(zhǔn)測(cè)試的性能指標(biāo)分析。

基準(zhǔn)測(cè)試結(jié)果:同步vs異步(Airtable)

性能明細(xì)

  1. 每秒請(qǐng)求數(shù):

異步版本每秒可處理50.68個(gè)請(qǐng)求,而同步版本每秒只能處理36.89個(gè)請(qǐng)求。

在相同時(shí)間內(nèi),異步處理的請(qǐng)求數(shù)比同步版本多37%,因此在并發(fā)性方面,異步顯然勝出。

  1. 每個(gè)請(qǐng)求的響應(yīng)時(shí)間(平均值):

異步版本的平均響應(yīng)時(shí)間低于同步版本27%(1973毫秒vs2710毫秒),這表明在高負(fù)載情況下,異步處理請(qǐng)求的效率更高。

  1. 最長(zhǎng)請(qǐng)求時(shí)間:

兩個(gè)版本的最長(zhǎng)請(qǐng)求時(shí)間相似(約4000毫秒),但異步版本的表現(xiàn)更穩(wěn)定,這體現(xiàn)在響應(yīng)時(shí)間的波動(dòng)較小。

圖表比較

圖表比較

以上是同步和異步版本在不同百分位數(shù)下的比較圖,包括平均和最長(zhǎng)請(qǐng)求時(shí)間。

  • 實(shí)線表示不同百分位數(shù)下的響應(yīng)時(shí)間。
  • 虛線表示同步(2710.648毫秒)和異步(1973.057毫秒)的平均響應(yīng)時(shí)間。
  • 點(diǎn)線突出顯示同步(4167毫秒)和異步(3851毫秒)的最長(zhǎng)請(qǐng)求時(shí)間。

四、何時(shí)在FastAPI中使用同步與異步?

使用異步的情況:

  • 應(yīng)用程序需要處理高流量和大量并發(fā)用戶。
  • 應(yīng)用程序是與I/O綁定的,需要進(jìn)行大量數(shù)據(jù)庫(kù)查詢或API調(diào)用。
  • 需要為大量請(qǐng)求最小化響應(yīng)時(shí)間。

使用同步的情況:

  • 應(yīng)用程序的并發(fā)量較小,或主要執(zhí)行CPU密集型任務(wù)。
  • 希望保持代碼庫(kù)的簡(jiǎn)單性,避免異步處理的復(fù)雜性。
  • 不希望應(yīng)用程序擴(kuò)展到同時(shí)處理數(shù)百或數(shù)千個(gè)請(qǐng)求。

五、優(yōu)化異步性能

雖然異步在這些測(cè)試中速度更快,但仍有一些方法可以進(jìn)一步優(yōu)化。

  • 連接池:使用連接池重用數(shù)據(jù)庫(kù)連接,避免為每個(gè)請(qǐng)求創(chuàng)建一個(gè)新連接。
  • 使用異步庫(kù):確保所有I/O綁定的任務(wù)(例如文件讀/寫、外部API調(diào)用)都以異步方式處理,以獲得最佳性能。
  • 測(cè)試更高的并發(fā)性:進(jìn)行更高并發(fā)量的負(fù)載測(cè)試(例如,500+用戶),以充分發(fā)揮異步的優(yōu)勢(shì)。
engine = create_async_engine(
    DATABASE_URL,
    pool_size=10,
    max_overflow=20
)

六、結(jié)論

如果你的應(yīng)用程序需要處理大量并發(fā)用戶,并嚴(yán)重依賴于I/O綁定任務(wù),那么異步FastAPI可以提供更好的性能、可擴(kuò)展性和響應(yīng)能力。不過(guò),對(duì)于更簡(jiǎn)單的用例,可以選擇同步實(shí)現(xiàn)。

責(zé)任編輯:武曉燕 來(lái)源: Python學(xué)研大本營(yíng)
相關(guān)推薦

2023-11-27 00:46:39

裸機(jī)虛擬機(jī)

2017-11-02 13:20:08

數(shù)據(jù)處理PythonNumpy

2025-12-02 09:29:16

2021-05-07 17:46:53

存儲(chǔ)IO

2019-12-25 09:53:01

虛擬機(jī)技術(shù)固態(tài)硬盤

2025-06-03 08:15:00

微服務(wù)架構(gòu)異步任務(wù)隊(duì)列

2024-07-11 16:49:43

同步通信異步通信通信

2017-04-13 15:15:17

Netflix ZuuNginx性能

2010-01-16 11:02:12

Ubuntu性能測(cè)試

2010-06-28 13:11:05

2022-12-05 17:01:20

MySQL數(shù)據(jù)庫(kù)Oracle

2010-01-22 11:06:03

GNUkFreeBSDLinux

2010-04-13 17:38:13

WindowsEmbe微軟嵌入式開(kāi)發(fā)Windows7

2010-04-13 17:07:18

WindowsEmbe微軟嵌入式開(kāi)發(fā)Windows7

2010-04-13 17:28:09

WindowsEmbe微軟嵌入式開(kāi)發(fā)Windows7

2009-11-20 09:01:13

Ubuntu性能對(duì)比

2009-03-12 09:59:43

Windows7WindowsVistWindowsXP

2009-07-24 13:17:43

世紀(jì)互聯(lián)至強(qiáng)CloudEx

2010-04-13 17:47:50

WindowsEmbe微軟嵌入式開(kāi)發(fā)Windows7

2017-11-21 15:50:09

FlinkStorm性能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

日韩国产伦理| av无码精品一区二区三区| 狂野欧美性猛交xxxx| 中文字幕一区二区视频| 成人福利免费观看| 在线观看欧美| 日韩精品在线一区| 九色porny在线观看| 成人污污视频在线观看| 国产高清自拍一区| 一区二区中文字幕在线观看| 日韩一区国产二区欧美三区| av免费看大片| 国产成人av一区二区三区在线观看| 国产欧美日韩精品专区| 日韩精品麻豆| 欧美一区二区三区免费观看视频| av男人的天堂网| 成人99免费视频| 日本在线视频不卡| 欧美伊人久久| 国产精品igao视频| 精品视频一区二区三区在线观看| 精品福利一区二区三区免费视频| 亚洲欧美一区二区三区在线播放| 99精品黄色片免费大全| 在线一区高清| 久久激情视频| 国产精品一区在线观看| 欧美军人男男激情gay| 久久精品中文字幕一区| 国产无遮挡裸体视频在线观看| 欧美日韩一级片网站| 在线欧美成人| 1000部国产精品成人观看| 精品一二三四五区| 久久久久久夜| 欧洲在线视频一区| 亚洲黄网站黄| 国产欧美日韩视频一区二区三区| 精品大片一区二区| 日本一区二区在线免费播放| 一区中文字幕电影| 欧美极品欧美精品欧美视频| 免费一区二区三区在线视频| 日韩中文理论片| 91麻豆精品| 欧美成人精品三级在线观看| 高清一区二区三区av| 精品国产欧美一区二区三区成人| 欧美magnet| 亚洲天堂免费观看| 久久91视频| 久久影视免费观看| 午夜视频在线观看精品中文| 久99久在线视频| 日韩欧美中文字幕一区二区三区 | 国产女人水真多18毛片18精品| 欧美日本三区| 欧美一区二区三区成人久久片| 久久亚洲精选| 亚洲欧美一区二区原创| 丁香婷婷深情五月亚洲| 黄色高清无遮挡| 中文字幕不卡一区| 922tv免费观看在线| 日韩欧美精品网址| 午夜av在线播放| 亚洲男人天堂久| 日本在线一区二区三区| 国产精品久久久久久av福利软件| 欧美jjzz| 女人床在线观看| 国产亚洲视频系列| 在线国产网址| 日韩视频123| 四虎影视精品永久在线观看| 性欧美长视频免费观看不卡| 日韩高清欧美| 亚洲永久激情精品| 久久久久久久av麻豆果冻| 最近2018中文字幕免费在线视频| 日本高清免费不卡视频| 黄色在线免费观看网站| 久久中文字幕在线| 亚洲乱码免费伦视频| www.午夜色| 亚洲欧美日本韩国| 国产在线激情| 欧美国产一区二区三区| 中文字幕一区二区三区欧美日韩| 亚洲午夜精品久久久中文影院av | 在线视频日韩一区| 色综合久久中文综合久久牛| 天堂av中文在线观看| 97精品久久久| 男人天堂欧美日韩| 性猛交ⅹ×××乱大交| 欧美日韩视频不卡| 欧美另类中文字幕| 国产亚洲福利社区| 国产网红主播福利一区二区| 爱爱爱免费视频在线观看| 国产亚洲精品美女| 日韩欧美一区二区三区在线视频 | 亚洲精品1区| 欧美综合在线播放| 在线观看av一区二区| 国产亚洲观看| 久久亚洲综合网| 亚洲欧美激情小说另类| 欧美sm一区| 亚洲字幕在线观看| 久久久噜噜噜久久中文字幕色伊伊| 高清在线观看av| 久久免费国产视频| 激情欧美一区二区三区在线观看| 欧美福利网站| 夜夜嗨av一区二区三区免费区| 色婷婷亚洲mv天堂mv在影片| 成人在线免费在线观看| 欧美日韩精品欧美日韩精品一| 丁香一区二区| 一区二区三区四区免费观看| 欧美日韩在线第一页| 久久精品福利| 在线视频精品一区| 欧美性猛交一区二区三区精品| 日本精品一区二区三区在线观看视频| 欧美日本韩国一区二区三区| 午夜精品123| 日韩美脚连裤袜丝袜在线| 菠萝蜜视频在线观看入口| 欧美日韩精品一区二区三区蜜桃| 国产最新精品| 色综合手机在线| 一区二区三区四区精品| 免费人成精品欧美精品| 尤物在线视频| 国产日韩换脸av一区在线观看| 国产亚洲欧洲一区高清在线观看| 久久青草伊人| 欧美日韩国产精品一区二区| 日韩欧美大尺度| 精品av一区二区| xxxx影院| 5566日本婷婷色中文字幕97| 久久久欧美精品sm网站| 国产成人亚洲一区二区三区| 在线观看成人一级片| 精品日韩欧美一区二区| 久久一综合视频| 成人黄视频在线观看| 国产精品12| 欧美日韩国产小视频| 欧美视频网站| 狠狠狠综合7777久夜色撩人| 国产精品久久久久一区二区| 亚洲综合色成人| 成人写真视频| 香蕉自在线视频| 国产日韩欧美在线观看| 午夜伦欧美伦电影理论片| 国产欧美日韩| 国模私拍视频| 国产精品揄拍500视频| 天天综合天天综合色| 自拍欧美日韩| 国产日产精品久久久久久婷婷| 国产精品成人aaaaa网站| 亚洲最新视频在线观看| 欧州一区二区| 亚洲精品男人| 国产精品毛片va一区二区三区| 欧美性欧美巨大黑白大战| 丝袜脚交一区二区| 日本大片在线播放| 视色,视色影院,视色影库,视色网| 亚洲视屏在线播放| 国产午夜三级一区二区三| 免费看日本一区二区| 如如影视在线观看经典| 99久久精品久久久久久ai换脸| 欧美性欧美巨大黑白大战| 丝袜美腿成人在线| 天天综合网站| 一区二区三区网址| 国产精品亚洲视频在线观看| 欧美美女一区二区在线观看| 国产精品自产自拍| 亚洲视频国产| 在线播放av片| 亚洲一区影院| 久久久久久亚洲精品不卡| 亚洲成av人片在线观看无码| 国产精品综合| 日韩色淫视频| 国产国产人免费人成免费视频| 99久久一区三区四区免费| 日韩av在线免播放器|